diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/common.c | 12 | ||||
-rw-r--r-- | drivers/usb/core/of.c | 24 | ||||
-rw-r--r-- | drivers/usb/imx/chipidea-imx.c | 13 |
3 files changed, 49 insertions, 0 deletions
diff --git a/drivers/usb/core/common.c b/drivers/usb/core/common.c index 690d5a39ea..bcbe3a155d 100644 --- a/drivers/usb/core/common.c +++ b/drivers/usb/core/common.c @@ -17,3 +17,15 @@ const char *usb_speed_string(enum usb_device_speed speed) return speed_names[speed]; } EXPORT_SYMBOL_GPL(usb_speed_string); + +enum usb_device_speed usb_speed_by_string(const char *string) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(speed_names); i++) + if (!strcmp(string, speed_names[i])) + return i; + + return USB_SPEED_UNKNOWN; +} +EXPORT_SYMBOL_GPL(usb_speed_by_string); diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c index fd20368424..979088ef4e 100644 --- a/drivers/usb/core/of.c +++ b/drivers/usb/core/of.c @@ -90,3 +90,27 @@ enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np, return USBPHY_INTERFACE_MODE_UNKNOWN; } EXPORT_SYMBOL_GPL(of_usb_get_phy_mode); + +/** + * of_usb_get_maximum_speed - Get maximum speed for given device_node + * @np: Pointer to the given device_node + * + * The function gets maximum speed string from property 'maximum-speed', + * and returns the correspondig enum usb_device_speed + */ +enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np, + const char *propname) +{ + const char *maximum_speed; + int err; + + if (!propname) + propname = "maximum-speed"; + + err = of_property_read_string(np, propname, &maximum_speed); + if (err < 0) + return USB_SPEED_UNKNOWN; + + return usb_speed_by_string(maximum_speed); +} +EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed); diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c index 505f5eb35d..3e3e6a365f 100644 --- a/drivers/usb/imx/chipidea-imx.c +++ b/drivers/usb/imx/chipidea-imx.c @@ -51,6 +51,7 @@ struct imx_chipidea { static int imx_chipidea_port_init(void *drvdata) { struct imx_chipidea *ci = drvdata; + uint32_t portsc; int ret; if ((ci->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_ULPI) { @@ -74,6 +75,14 @@ static int imx_chipidea_port_init(void *drvdata) if (ret) dev_err(ci->dev, "misc init failed: %s\n", strerror(-ret)); + /* PFSC bit is reset by ehci_reset(), thus have to set it not in + * probe but here, after ehci_reset() is already called */ + if (ci->flags & MXC_EHCI_PFSC) { + portsc = readl(ci->base + 0x184); + portsc |= MXC_EHCI_PFSC; + writel(portsc, ci->base + 0x184); + } + return ret; } @@ -159,6 +168,10 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci) "over-current-active-high", NULL)) ci->flags |= MXC_EHCI_OC_PIN_ACTIVE_LOW; + if (of_usb_get_maximum_speed(ci->dev->device_node, NULL) == + USB_SPEED_FULL) + ci->flags |= MXC_EHCI_PFSC; + return 0; } |