summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2019-01-29 12:23:40 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-01-30 11:22:35 +0300
commitb97a31348379f7beed7664a8d4eab491e227c165 (patch)
tree484fcbd9a7d97738ebb322918d7f75c29c13d722
parentc9381e185fdcf86e9d7966d638c933894f87cdd7 (diff)
downloadlinux-b97a31348379f7beed7664a8d4eab491e227c165.tar.xz
usb: core: comply to PHY framework
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>
-rw-r--r--drivers/usb/core/hcd.c5
-rw-r--r--drivers/usb/core/phy.c28
-rw-r--r--drivers/usb/core/phy.h2
3 files changed, 35 insertions, 0 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 015b126ce455..86f39e44f98a 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -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;
diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
index 38b2c776c4b4..7580493b867a 100644
--- a/drivers/usb/core/phy.c
+++ b/drivers/usb/core/phy.c
@@ -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;
diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h
index 88a3c037e9df..dad564e2d2d4 100644
--- a/drivers/usb/core/phy.h
+++ b/drivers/usb/core/phy.h
@@ -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);