summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/common.c12
-rw-r--r--drivers/usb/core/of.c24
-rw-r--r--drivers/usb/imx/chipidea-imx.c13
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;
}