Some controllers need an init hook after the USB controller is
started, so implement the post init hook for i.MX.

Signed-off-by: Sascha Hauer <[email protected]>
---
 drivers/usb/imx/chipidea-imx.c |   43 ++++++++++++++++++++++-----
 drivers/usb/imx/imx-usb-misc.c |   63 ++++++++++++++++++++++++++++++++--------
 include/usb/chipidea-imx.h     |    2 ++
 3 files changed, 89 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c
index 64bb866..de80c36 100644
--- a/drivers/usb/imx/chipidea-imx.c
+++ b/drivers/usb/imx/chipidea-imx.c
@@ -22,12 +22,41 @@
 
 #define MXC_EHCI_PORTSC_MASK ((0xf << 28) | (1 << 25))
 
+static int imx_chipidea_port_init(void *drvdata)
+{
+       struct device_d *dev = drvdata;
+       struct imxusb_platformdata *pdata = dev->platform_data;
+       int ret;
+
+       ret = imx_usbmisc_port_init(dev->id, pdata->flags);
+       if (ret)
+               dev_err(dev, "misc init failed: %s\n", strerror(-ret));
+
+       if (pdata->init)
+               pdata->init(dev->id);
+
+       return ret;
+}
+
+static int imx_chipidea_port_post_init(void *drvdata)
+{
+       struct device_d *dev = drvdata;
+       struct imxusb_platformdata *pdata = dev->platform_data;
+       int ret;
+
+       ret = imx_usbmisc_port_post_init(dev->id, pdata->flags);
+       if (ret)
+               dev_err(dev, "post misc init failed: %s\n", strerror(-ret));
+
+       return ret;
+}
+
 static int imx_chipidea_probe(struct device_d *dev)
 {
        struct imxusb_platformdata *pdata = dev->platform_data;
        int ret;
        void __iomem *base;
-       struct ehci_data data;
+       struct ehci_data data = {};
        uint32_t portsc;
 
        if (!pdata) {
@@ -39,17 +68,17 @@ static int imx_chipidea_probe(struct device_d *dev)
        if (!base)
                return -ENODEV;
 
+       data.init = imx_chipidea_port_init;
+       data.post_init = imx_chipidea_port_post_init;
+       data.drvdata = dev;
+
+       imx_chipidea_port_init(dev);
+
        portsc = readl(base + 0x184);
        portsc &= ~MXC_EHCI_PORTSC_MASK;
        portsc |= pdata->flags & MXC_EHCI_PORTSC_MASK;
        writel(portsc, base + 0x184);
 
-       ret = imx_usbmisc_port_init(dev->id, pdata->flags);
-       if (ret) {
-               dev_err(dev, "failed to init misc regs: %s\n", strerror(-ret));
-               return ret;
-       }
-
        if ((pdata->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_ULPI) {
                dev_dbg(dev, "using ULPI phy\n");
                if (IS_ENABLED(CONFIG_USB_ULPI)) {
diff --git a/drivers/usb/imx/imx-usb-misc.c b/drivers/usb/imx/imx-usb-misc.c
index 4cdf5ab..d42f4c0 100644
--- a/drivers/usb/imx/imx-usb-misc.c
+++ b/drivers/usb/imx/imx-usb-misc.c
@@ -34,6 +34,11 @@
 #define MX25_H1_USBTE_BIT      (1 << 4)
 #define MX25_H1_OCPOL_BIT      (1 << 2)
 
+struct imx_usb_misc_data {
+       int (*init)(void __iomem *base, int port, unsigned int flags);
+       int (*post_init)(void __iomem *base, int port, unsigned int flags);
+};
+
 static __maybe_unused int mx25_initialize_usb_hw(void __iomem *base, int port, 
unsigned int flags)
 {
        unsigned int v;
@@ -93,6 +98,10 @@ static __maybe_unused int mx25_initialize_usb_hw(void 
__iomem *base, int port, u
        return 0;
 }
 
+static __maybe_unused struct imx_usb_misc_data mx25_data = {
+       .init = mx25_initialize_usb_hw,
+};
+
 #define MX27_OTG_SIC_SHIFT     29
 #define MX27_OTG_SIC_MASK      (0x3 << MX27_OTG_SIC_SHIFT)
 #define MX27_OTG_PM_BIT                (1 << 24)
@@ -152,6 +161,10 @@ static __maybe_unused int mx27_mx31_initialize_usb_hw(void 
__iomem *base, int po
        return 0;
 }
 
+static __maybe_unused struct imx_usb_misc_data mx27_mx31_data = {
+       .init = mx27_mx31_initialize_usb_hw,
+};
+
 #define USBCTRL_OTGBASE_OFFSET 0x600
 
 #define MX35_OTG_SIC_SHIFT     29
@@ -229,6 +242,10 @@ static __maybe_unused int mx35_initialize_usb_hw(void 
__iomem *base, int port, u
        return 0;
 }
 
+static __maybe_unused struct imx_usb_misc_data mx35_data = {
+       .init = mx35_initialize_usb_hw,
+};
+
 /* USB_CTRL */
 #define MX5_OTG_UCTRL_OWIE_BIT         (1 << 27)       /* OTG wakeup intr 
enable */
 #define MX5_OTG_UCTRL_OPM_BIT          (1 << 24)       /* OTG power mask */
@@ -324,53 +341,61 @@ static __maybe_unused int mx5_initialize_usb_hw(void 
__iomem *base, int port,
        return 0;
 }
 
+static __maybe_unused struct imx_usb_misc_data mx5_data = {
+       .init = mx5_initialize_usb_hw,
+};
+
 static __maybe_unused int mx6_initialize_usb_hw(void __iomem *base, int port,
                unsigned int flags)
 {
        return 0;
 }
 
+static __maybe_unused struct imx_usb_misc_data mx6_data = {
+       .init = mx6_initialize_usb_hw,
+};
+
 static struct platform_device_id imx_usbmisc_ids[] = {
 #ifdef CONFIG_ARCH_IMX25
        {
                .name = "imx25-usb-misc",
-               .driver_data = (unsigned long)&mx25_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx25_data,
        },
 #endif
 #ifdef CONFIG_ARCH_IMX27
        {
                .name = "imx27-usb-misc",
-               .driver_data = (unsigned long)&mx27_mx31_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx27_mx31_data,
        },
 #endif
 #ifdef CONFIG_ARCH_IMX31
        {
                .name = "imx31-usb-misc",
-               .driver_data = (unsigned long)&mx27_mx31_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx27_mx31_data,
        },
 #endif
 #ifdef CONFIG_ARCH_IMX35
        {
                .name = "imx35-usb-misc",
-               .driver_data = (unsigned long)&mx35_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx35_data,
        },
 #endif
 #ifdef CONFIG_ARCH_IMX51
        {
                .name = "imx51-usb-misc",
-               .driver_data = (unsigned long)&mx5_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx5_data,
        },
 #endif
 #ifdef CONFIG_ARCH_IMX53
        {
                .name = "imx53-usb-misc",
-               .driver_data = (unsigned long)&mx5_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx5_data,
        },
 #endif
 #ifdef CONFIG_ARCH_IMX6
        {
                .name = "imx6-usb-misc",
-               .driver_data = (unsigned long)&mx6_initialize_usb_hw,
+               .driver_data = (unsigned long)&mx6_data,
        },
 #endif
        {
@@ -378,20 +403,34 @@ static struct platform_device_id imx_usbmisc_ids[] = {
        },
 };
 
-static int (*__imx_usbmisc_port_init)(void __iomem *base, int port, unsigned 
flags);
+static struct imx_usb_misc_data *imxusbmisc_data;
 static void __iomem *usbmisc_base;
 
 int imx_usbmisc_port_init(int port, unsigned flags)
 {
-       if (!__imx_usbmisc_port_init)
+       if (!imxusbmisc_data)
                return -ENODEV;
 
-       return __imx_usbmisc_port_init(usbmisc_base, port, flags);
+       if (!imxusbmisc_data->init)
+               return 0;
+
+       return imxusbmisc_data->init(usbmisc_base, port, flags);
+}
+
+int imx_usbmisc_port_post_init(int port, unsigned flags)
+{
+       if (!imxusbmisc_data)
+               return -ENODEV;
+
+       if (!imxusbmisc_data->post_init)
+               return 0;
+
+       return imxusbmisc_data->post_init(usbmisc_base, port, flags);
 }
 
 static int imx_usbmisc_probe(struct device_d *dev)
 {
-       struct imx_serial_devtype_data *devtype;
+       struct imx_usb_misc_data *devtype;
        int ret;
 
        ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
@@ -402,7 +441,7 @@ static int imx_usbmisc_probe(struct device_d *dev)
        if (!usbmisc_base)
                return -ENOMEM;
 
-       __imx_usbmisc_port_init = (void *)devtype;
+       imxusbmisc_data = devtype;
 
        return 0;
 }
diff --git a/include/usb/chipidea-imx.h b/include/usb/chipidea-imx.h
index 252d488..3f9f61e 100644
--- a/include/usb/chipidea-imx.h
+++ b/include/usb/chipidea-imx.h
@@ -40,8 +40,10 @@ enum imx_usb_mode {
 struct imxusb_platformdata {
        unsigned long flags;
        enum imx_usb_mode mode;
+       int (*init)(int port);
 };
 
 int imx_usbmisc_port_init(int port, unsigned flags);
+int imx_usbmisc_port_post_init(int port, unsigned flags);
 
 #endif /* __USB_CHIPIDEA_IMX_H */
-- 
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to