usb: core: comply to PHY framework
authorMiquel Raynal <miquel.raynal@bootlin.com>
Tue, 29 Jan 2019 09:23:40 +0000 (10:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Jan 2019 08:22:35 +0000 (09:22 +0100)
Current implementation of the USB core does not take into account the
new PHY framework. Correct the situation by adding a call to
phy_set_mode() before phy_power_on().

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hcd.c
drivers/usb/core/phy.c
drivers/usb/core/phy.h

index 015b126ce4555e8d58b8744e7666c384387e9ddf..86f39e44f98a40b165c6479beac06373022b9dd6 100644 (file)
@@ -2736,6 +2736,11 @@ int usb_add_hcd(struct usb_hcd *hcd,
                if (retval)
                        return retval;
 
+               retval = usb_phy_roothub_set_mode(hcd->phy_roothub,
+                                                 PHY_MODE_USB_HOST_SS);
+               if (retval)
+                       goto err_usb_phy_roothub_power_on;
+
                retval = usb_phy_roothub_power_on(hcd->phy_roothub);
                if (retval)
                        goto err_usb_phy_roothub_power_on;
index 38b2c776c4b421a2b3e58d200cd37a8b4f4929e0..7580493b867a2f974f43d8a5fb774abf55d73b85 100644 (file)
@@ -123,6 +123,34 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub)
 }
 EXPORT_SYMBOL_GPL(usb_phy_roothub_exit);
 
+int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub,
+                            enum phy_mode mode)
+{
+       struct usb_phy_roothub *roothub_entry;
+       struct list_head *head;
+       int err;
+
+       if (!phy_roothub)
+               return 0;
+
+       head = &phy_roothub->list;
+
+       list_for_each_entry(roothub_entry, head, list) {
+               err = phy_set_mode(roothub_entry->phy, mode);
+               if (err)
+                       goto err_out;
+       }
+
+       return 0;
+
+err_out:
+       list_for_each_entry_continue_reverse(roothub_entry, head, list)
+               phy_power_off(roothub_entry->phy);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_set_mode);
+
 int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub)
 {
        struct usb_phy_roothub *roothub_entry;
index 88a3c037e9df59194ba94d3ecd7ec3e2626ccb33..dad564e2d2d42dff78d88a486fc30d7e255a2798 100644 (file)
@@ -16,6 +16,8 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev);
 int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub);
 int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub);
 
+int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub,
+                            enum phy_mode mode);
 int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub);
 void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub);