]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
UBUNTU: SAUCE: USB: core: Make port power cycle a seperate helper function
authorKai-Heng Feng <kai.heng.feng@canonical.com>
Thu, 5 Dec 2019 17:05:00 +0000 (18:05 +0100)
committerMarcelo Henrique Cerri <marcelo.cerri@canonical.com>
Fri, 17 Jan 2020 17:23:14 +0000 (14:23 -0300)
BugLink: https://bugs.launchpad.net/bugs/1855312
Add a new function, hub_port_power_cycle() to power cycle port's power.
It'll be used by a following patch.

In addition to that, check the return value of usb_hub_set_port_power(),
so we don't need to wait if the set power operation fails.

Furthermore, remove parameter *hdev from usb_hub_set_port_power(), since
we can get *hdev from *hub directly.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/port.c

index 6ff732a7fc4951c93c3c577ae754e63b86f0a998..6ed7de25d3f4c52b386288cb673a8fd7a9e81bc1 100644 (file)
@@ -786,9 +786,9 @@ static void hub_tt_work(struct work_struct *work)
  *
  * Return: 0 if successful. A negative error code otherwise.
  */
-int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
-                          int port1, bool set)
+int usb_hub_set_port_power(struct usb_hub *hub, int port1, bool set)
 {
+       struct usb_device *hdev = hub->hdev;
        int ret;
 
        if (set)
@@ -2673,6 +2673,27 @@ static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1,
                || link_state == USB_SS_PORT_LS_COMP_MOD;
 }
 
+static void hub_port_power_cycle(struct usb_hub *hub, int port1)
+{
+       struct usb_port *port_dev = hub->ports[port1  - 1];
+       int ret;
+
+       ret = usb_hub_set_port_power(hub, port1, false);
+       if (ret) {
+               dev_info(&port_dev->dev, "failed to disable port power\n");
+               return;
+       }
+
+       msleep(2 * hub_power_on_good_delay(hub));
+       ret = usb_hub_set_port_power(hub, port1, true);
+       if (ret) {
+               dev_info(&port_dev->dev, "failed to enable port power\n");
+               return;
+       }
+
+       msleep(hub_power_on_good_delay(hub));
+}
+
 static int hub_port_wait_reset(struct usb_hub *hub, int port1,
                        struct usb_device *udev, unsigned int delay, bool warm)
 {
@@ -4994,10 +5015,7 @@ loop:
                /* When halfway through our retry count, power-cycle the port */
                if (i == (SET_CONFIG_TRIES / 2) - 1) {
                        dev_info(&port_dev->dev, "attempt power cycle\n");
-                       usb_hub_set_port_power(hdev, hub, port1, false);
-                       msleep(2 * hub_power_on_good_delay(hub));
-                       usb_hub_set_port_power(hdev, hub, port1, true);
-                       msleep(hub_power_on_good_delay(hub));
+                       hub_port_power_cycle(hub, port1);
                }
        }
        if (hub->hdev->parent ||
index 2a700ccc868c9bca2743294ace7a3639fcfbc23e..dab8921b2711e3881f403fe9c8238fcd5a2f873a 100644 (file)
@@ -109,8 +109,7 @@ extern int usb_hub_create_port_device(struct usb_hub *hub,
                int port1);
 extern void usb_hub_remove_port_device(struct usb_hub *hub,
                int port1);
-extern int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
-               int port1, bool set);
+extern int usb_hub_set_port_power(struct usb_hub *hub, int port1, bool set);
 extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev);
 extern int hub_port_debounce(struct usb_hub *hub, int port1,
                bool must_be_connected);
index 032683ac4db4e88683a6b91001003c23de6a844b..f55e44524b050333fab7070e54f70940f3f84af9 100644 (file)
@@ -171,7 +171,7 @@ static int usb_port_runtime_resume(struct device *dev)
                pm_runtime_get_sync(&peer->dev);
 
        usb_autopm_get_interface(intf);
-       retval = usb_hub_set_port_power(hdev, hub, port1, true);
+       retval = usb_hub_set_port_power(hub, port1, true);
        msleep(hub_power_on_good_delay(hub));
        if (udev && !retval) {
                /*
@@ -224,7 +224,7 @@ static int usb_port_runtime_suspend(struct device *dev)
                return -EBUSY;
 
        usb_autopm_get_interface(intf);
-       retval = usb_hub_set_port_power(hdev, hub, port1, false);
+       retval = usb_hub_set_port_power(hub, port1, false);
        usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
        if (!port_dev->is_superspeed)
                usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);