summaryrefslogtreecommitdiffstats
path: root/drivers/usb/imx/chipidea-imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/imx/chipidea-imx.c')
-rw-r--r--drivers/usb/imx/chipidea-imx.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c
index bf8b6f1eb8..c5e6ce61e9 100644
--- a/drivers/usb/imx/chipidea-imx.c
+++ b/drivers/usb/imx/chipidea-imx.c
@@ -9,13 +9,13 @@
#include <of.h>
#include <errno.h>
#include <driver.h>
-#include <usb/usb.h>
-#include <usb/ehci.h>
+#include <linux/usb/usb.h>
+#include <linux/usb/ehci.h>
#include <regulator.h>
-#include <usb/chipidea-imx.h>
-#include <usb/phy.h>
-#include <usb/ulpi.h>
-#include <usb/fsl_usb2.h>
+#include <linux/usb/chipidea-imx.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/ulpi.h>
+#include <linux/usb/fsl_usb2.h>
#include <linux/err.h>
#include <linux/phy/phy.h>
#include <linux/clk.h>
@@ -27,13 +27,13 @@ struct imx_chipidea_data {
};
struct imx_chipidea {
- struct device_d *dev;
+ struct device *dev;
void __iomem *base;
struct ehci_data data;
unsigned long flags;
enum usb_dr_mode mode;
int portno;
- struct device_d *usbmisc;
+ struct device *usbmisc;
enum usb_phy_interface phymode;
struct param_d *param_mode;
struct regulator *vbus;
@@ -104,7 +104,7 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci)
struct of_phandle_args out_args;
if (ci->have_usb_misc) {
- if (of_parse_phandle_with_args(ci->dev->device_node, "fsl,usbmisc",
+ if (of_parse_phandle_with_args(ci->dev->of_node, "fsl,usbmisc",
"#index-cells", 0, &out_args))
return -ENODEV;
@@ -117,7 +117,7 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci)
ci->flags = MXC_EHCI_MODE_UTMI_8BIT;
- ci->mode = of_usb_get_dr_mode(ci->dev->device_node, NULL);
+ ci->mode = of_usb_get_dr_mode(ci->dev->of_node, NULL);
if (ci->mode == USB_DR_MODE_UNKNOWN) {
/*
@@ -130,7 +130,7 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci)
ci->mode = USB_DR_MODE_HOST;
}
- ci->phymode = of_usb_get_phy_mode(ci->dev->device_node, NULL);
+ ci->phymode = of_usb_get_phy_mode(ci->dev->of_node, NULL);
switch (ci->phymode) {
case USBPHY_INTERFACE_MODE_UTMI:
ci->flags = MXC_EHCI_MODE_UTMI_8BIT;
@@ -151,18 +151,18 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci)
dev_dbg(ci->dev, "no phy_type setting. Relying on reset default\n");
}
- if (of_find_property(ci->dev->device_node,
+ if (of_find_property(ci->dev->of_node,
"disable-over-current", NULL))
ci->flags |= MXC_EHCI_DISABLE_OVERCURRENT;
- else if (!of_find_property(ci->dev->device_node,
+ else if (!of_find_property(ci->dev->of_node,
"over-current-active-high", NULL))
ci->flags |= MXC_EHCI_OC_PIN_ACTIVE_LOW;
- if (of_find_property(ci->dev->device_node, "power-active-high", NULL))
+ if (of_find_property(ci->dev->of_node, "power-active-high", NULL))
ci->flags |= MXC_EHCI_PWR_PIN_ACTIVE_HIGH;
- if (of_usb_get_maximum_speed(ci->dev->device_node, NULL) ==
+ if (of_usb_get_maximum_speed(ci->dev->of_node, NULL) ==
USB_SPEED_FULL)
ci->flags |= MXC_EHCI_PFSC;
@@ -213,7 +213,7 @@ static int ci_set_mode(void *ctx, enum usb_dr_mode mode)
return 0;
}
-static int imx_chipidea_probe(struct device_d *dev)
+static int imx_chipidea_probe(struct device *dev)
{
struct resource *iores;
struct imx_chipidea_data *imx_data;
@@ -232,7 +232,7 @@ static int imx_chipidea_probe(struct device_d *dev)
if (!ret)
ci->have_usb_misc = imx_data->have_usb_misc;
- if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node) {
+ if (IS_ENABLED(CONFIG_OFDEVICE) && dev->of_node) {
ret = imx_chipidea_probe_dt(ci);
if (ret)
return ret;
@@ -260,16 +260,14 @@ static int imx_chipidea_probe(struct device_d *dev)
* devices which have only one.
*/
ci->clk = clk_get(dev, NULL);
- if (!IS_ERR(ci->clk))
- clk_enable(ci->clk);
/* Device trees are using both "phys" and "fsl,usbphy". Prefer the
* more modern former one but fall back to the old one.
*
* Code should be removed when all devicetrees are using "phys" */
- if (of_property_read_bool(dev->device_node, "phys"))
+ if (of_property_read_bool(dev->of_node, "phys"))
phynode_name = "phys";
- else if (of_property_read_bool(dev->device_node, "fsl,usbphy"))
+ else if (of_property_read_bool(dev->of_node, "fsl,usbphy"))
phynode_name = "fsl,usbphy";
else
phynode_name = NULL;
@@ -302,6 +300,14 @@ static int imx_chipidea_probe(struct device_d *dev)
ci->data.drvdata = ci;
ci->data.usbphy = ci->usbphy;
+ /*
+ * Enable the clock after we ensured that all resources are available.
+ * This is crucial since the phy can be missing which and so the
+ * usb-controller <-> usb-phy communication is only partly initialized.
+ * This can trigger strange system hangs at least on i.MX8M SoCs.
+ */
+ clk_enable(ci->clk);
+
if ((ci->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_HSIC)
imx_chipidea_port_init(ci);
@@ -324,7 +330,7 @@ static int imx_chipidea_probe(struct device_d *dev)
return ret;
};
-static void imx_chipidea_remove(struct device_d *dev)
+static void imx_chipidea_remove(struct device *dev)
{
struct imx_chipidea *ci = dev->priv;
@@ -357,8 +363,9 @@ static __maybe_unused struct of_device_id imx_chipidea_dt_ids[] = {
/* sentinel */
},
};
+MODULE_DEVICE_TABLE(of, imx_chipidea_dt_ids);
-static struct driver_d imx_chipidea_driver = {
+static struct driver imx_chipidea_driver = {
.name = "imx-usb",
.probe = imx_chipidea_probe,
.of_compatible = DRV_OF_COMPAT(imx_chipidea_dt_ids),