summaryrefslogtreecommitdiff
path: root/kernels/linux-libre-xtreme/0010-usb-core-add-power-sequence-handling-for-USB-devices.patch
diff options
context:
space:
mode:
Diffstat (limited to 'kernels/linux-libre-xtreme/0010-usb-core-add-power-sequence-handling-for-USB-devices.patch')
-rw-r--r--kernels/linux-libre-xtreme/0010-usb-core-add-power-sequence-handling-for-USB-devices.patch164
1 files changed, 0 insertions, 164 deletions
diff --git a/kernels/linux-libre-xtreme/0010-usb-core-add-power-sequence-handling-for-USB-devices.patch b/kernels/linux-libre-xtreme/0010-usb-core-add-power-sequence-handling-for-USB-devices.patch
deleted file mode 100644
index ddebef4f0..000000000
--- a/kernels/linux-libre-xtreme/0010-usb-core-add-power-sequence-handling-for-USB-devices.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-From 1358757f34c7feff4aab541814c73f6cf3e83b69 Mon Sep 17 00:00:00 2001
-From: Peter Chen <peter.chen@nxp.com>
-Date: Wed, 21 Jun 2017 14:42:05 +0800
-Subject: [PATCH 10/14] usb: core: add power sequence handling for USB devices
-
-Some hard-wired USB devices need to do power sequence to let the
-device work normally, the typical power sequence like: enable USB
-PHY clock, toggle reset pin, etc. But current Linux USB driver
-lacks of such code to do it, it may cause some hard-wired USB devices
-works abnormal or can't be recognized by controller at all.
-
-In this patch, it calls power sequence library APIs to finish
-the power sequence events. It will do power on sequence at hub's
-probe for all devices under this hub (includes root hub).
-At hub_disconnect, it will do power off sequence which is at powered
-on list.
-
-Signed-off-by: Peter Chen <peter.chen@nxp.com>
-Tested-by Joshua Clayton <stillcompiling@gmail.com>
-Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
-Reviewed-by: Vaibhav Hiremath <hvaibhav.linux@gmail.com>
-Acked-by: Alan Stern <stern@rowland.harvard.edu>
----
- drivers/usb/Kconfig | 1 +
- drivers/usb/core/hub.c | 49 ++++++++++++++++++++++++++++++++++++++----
- drivers/usb/core/hub.h | 1 +
- 3 files changed, 47 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
-index 987fc5ba6321..bd09fc8ff763 100644
---- a/drivers/usb/Kconfig
-+++ b/drivers/usb/Kconfig
-@@ -45,6 +45,7 @@ config USB
- tristate "Support for Host-side USB"
- depends on USB_ARCH_HAS_HCD
- select USB_COMMON
-+ select POWER_SEQUENCE
- select NLS # for UTF-8 strings
- ---help---
- Universal Serial Bus (USB) is a specification for a serial bus
-diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index fcae521df29b..0c708d3ef179 100644
---- a/drivers/usb/core/hub.c
-+++ b/drivers/usb/core/hub.c
-@@ -28,6 +28,7 @@
- #include <linux/mutex.h>
- #include <linux/random.h>
- #include <linux/pm_qos.h>
-+#include <linux/power/pwrseq.h>
-
- #include <linux/uaccess.h>
- #include <asm/byteorder.h>
-@@ -1654,6 +1655,7 @@ static void hub_disconnect(struct usb_interface *intf)
- hub->error = 0;
- hub_quiesce(hub, HUB_DISCONNECT);
-
-+ of_pwrseq_off_list(&hub->pwrseq_list);
- mutex_lock(&usb_port_peer_mutex);
-
- /* Avoid races with recursively_mark_NOTATTACHED() */
-@@ -1700,11 +1702,41 @@ static bool hub_descriptor_is_sane(struct usb_host_interface *desc)
- return true;
- }
-
-+#ifdef CONFIG_OF
-+static int hub_of_pwrseq_on(struct usb_hub *hub)
-+{
-+ struct device *parent;
-+ struct usb_device *hdev = hub->hdev;
-+ struct device_node *np;
-+ int ret;
-+
-+ if (hdev->parent)
-+ parent = &hdev->dev;
-+ else
-+ parent = bus_to_hcd(hdev->bus)->self.sysdev;
-+
-+ for_each_child_of_node(parent->of_node, np) {
-+ ret = of_pwrseq_on_list(np, &hub->pwrseq_list);
-+ /* Maybe no power sequence library is chosen */
-+ if (ret && ret != -ENOENT)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+#else
-+static int hub_of_pwrseq_on(struct usb_hub *hub)
-+{
-+ return 0;
-+}
-+#endif
-+
- static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
- {
- struct usb_host_interface *desc;
- struct usb_device *hdev;
- struct usb_hub *hub;
-+ int ret = -ENODEV;
-
- desc = intf->cur_altsetting;
- hdev = interface_to_usbdev(intf);
-@@ -1795,6 +1827,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
- INIT_DELAYED_WORK(&hub->leds, led_work);
- INIT_DELAYED_WORK(&hub->init_work, NULL);
- INIT_WORK(&hub->events, hub_event);
-+ INIT_LIST_HEAD(&hub->pwrseq_list);
- usb_get_intf(intf);
- usb_get_dev(hdev);
-
-@@ -1808,11 +1841,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
- if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
- hub->quirk_check_port_auto_suspend = 1;
-
-- if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
-- return 0;
-+ if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
-+ ret = hub_of_pwrseq_on(hub);
-+ if (!ret)
-+ return 0;
-+ }
-
- hub_disconnect(intf);
-- return -ENODEV;
-+ return ret;
- }
-
- static int
-@@ -3653,14 +3689,19 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
-
- /* stop hub_wq and related activity */
- hub_quiesce(hub, HUB_SUSPEND);
-- return 0;
-+ return pwrseq_suspend_list(&hub->pwrseq_list);
- }
-
- static int hub_resume(struct usb_interface *intf)
- {
- struct usb_hub *hub = usb_get_intfdata(intf);
-+ int ret;
-
- dev_dbg(&intf->dev, "%s\n", __func__);
-+ ret = pwrseq_resume_list(&hub->pwrseq_list);
-+ if (ret)
-+ return ret;
-+
- hub_activate(hub, HUB_RESUME);
- return 0;
- }
-diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
-index 4accfb63f7dc..abe71c5e84cb 100644
---- a/drivers/usb/core/hub.h
-+++ b/drivers/usb/core/hub.h
-@@ -70,6 +70,7 @@ struct usb_hub {
- struct delayed_work init_work;
- struct work_struct events;
- struct usb_port **ports;
-+ struct list_head pwrseq_list; /* powered pwrseq node list */
- };
-
- /**
---
-2.18.0
-