usb: gadget: mv_udc: refine the driver structure
authorNeil Zhang <zhangwm@marvell.com>
Wed, 12 Oct 2011 08:49:24 +0000 (16:49 +0800)
committerFelipe Balbi <balbi@ti.com>
Thu, 13 Oct 2011 17:41:56 +0000 (20:41 +0300)
This patch do the following things:

1. Add header and Copyright for marvell usb driver.
2. Add mv_usb.h in include/linux/platform_data, make the driver
   fits all the marvell platform using the same ChipIdea usb ip.
3. Some SOC may has mutiple clock sources, so let me define it
   in mv_usb_platform_data and give two helper functions named
   udc_clock_enable/udc_clock_disable to deal with the clocks.
4. Different SOCs will have some difference in PHY initialization,
   so we will remove file mv_udc_phy.c and add two funtions in
   mv_usb_platform_data, let the platform relative driver to realize it.
5. Rewrite probe function according to the modification list above. Find
   it will kernel panic when probe failed. The root cause is as follows:
When probe failed, the error handle may call device_unregister()
which in return will call gadget_release.In current code,
gadget_release have two issues:
1: the_controller is a NULL pointer.
2: if we free udc here, then the following code in probe
   will access NULL pointer.

Signed-off-by: Neil Zhang <zhangwm@marvell.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/Makefile
drivers/usb/gadget/mv_udc.h
drivers/usb/gadget/mv_udc_core.c
drivers/usb/gadget/mv_udc_phy.c [deleted file]
include/linux/platform_data/mv_usb.h [new file with mode: 0644]

index 9ba725a..c36da63 100644 (file)
@@ -28,7 +28,7 @@ obj-$(CONFIG_USB_S3C_HSUDC)   += s3c-hsudc.o
 obj-$(CONFIG_USB_LANGWELL)     += langwell_udc.o
 obj-$(CONFIG_USB_EG20T)                += pch_udc.o
 obj-$(CONFIG_USB_PXA_U2O)      += mv_udc.o
-mv_udc-y                       := mv_udc_core.o mv_udc_phy.o
+mv_udc-y                       := mv_udc_core.o
 obj-$(CONFIG_USB_CI13XXX_MSM)  += ci13xxx_msm.o
 obj-$(CONFIG_USB_FUSB300)      += fusb300_udc.o
 
index 65f1f7c..d3d2645 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
 
 #ifndef __MV_UDC_H
 #define __MV_UDC_H
@@ -201,7 +209,12 @@ struct mv_udc {
                                remote_wakeup:1,
                                softconnected:1,
                                force_fs:1;
-       struct clk              *clk;
+
+       struct mv_usb_platform_data     *pdata;
+
+       /* some SOC has mutiple clock sources for USB*/
+       unsigned int    clknum;
+       struct clk      *clk[0];
 };
 
 /* endpoint data structure */
@@ -289,6 +302,4 @@ struct mv_dtd {
        struct mv_dtd *next_dtd_virt;
 };
 
-extern int mv_udc_phy_init(unsigned int base);
-
 #endif
index 0d0e9e3..40a25e7 100644 (file)
@@ -1,3 +1,14 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ * Author: Chao Xie <chao.xie@marvell.com>
+ *        Neil Zhang <zhangwm@marvell.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -22,6 +33,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/platform_data/mv_usb.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
 
@@ -45,6 +57,8 @@
 #define LOOPS_USEC             (1 << LOOPS_USEC_SHIFT)
 #define LOOPS(timeout)         ((timeout) >> LOOPS_USEC_SHIFT)
 
+static DECLARE_COMPLETION(release_done);
+
 static const char driver_name[] = "mv_udc";
 static const char driver_desc[] = DRIVER_DESC;
 
@@ -987,6 +1001,22 @@ static struct usb_ep_ops mv_ep_ops = {
        .fifo_flush     = mv_ep_fifo_flush,     /* flush fifo */
 };
 
+static void udc_clock_enable(struct mv_udc *udc)
+{
+       unsigned int i;
+
+       for (i = 0; i < udc->clknum; i++)
+               clk_enable(udc->clk[i]);
+}
+
+static void udc_clock_disable(struct mv_udc *udc)
+{
+       unsigned int i;
+
+       for (i = 0; i < udc->clknum; i++)
+               clk_disable(udc->clk[i]);
+}
+
 static void udc_stop(struct mv_udc *udc)
 {
        u32 tmp;
@@ -1877,18 +1907,15 @@ static void gadget_release(struct device *_dev)
        struct mv_udc *udc = the_controller;
 
        complete(udc->done);
-       kfree(udc);
 }
 
 static int mv_udc_remove(struct platform_device *dev)
 {
        struct mv_udc *udc = the_controller;
-       DECLARE_COMPLETION(done);
+       int clk_i;
 
        usb_del_gadget_udc(&udc->gadget);
 
-       udc->done = &done;
-
        /* free memory allocated in probe */
        if (udc->dtd_pool)
                dma_pool_destroy(udc->dtd_pool);
@@ -1915,10 +1942,14 @@ static int mv_udc_remove(struct platform_device *dev)
                kfree(udc->status_req);
        }
 
+       for (clk_i = 0; clk_i <= udc->clknum; clk_i++)
+               clk_put(udc->clk[clk_i]);
+
        device_unregister(&udc->gadget.dev);
 
        /* free dev, wait for the release() finished */
-       wait_for_completion(&done);
+       wait_for_completion(udc->done);
+       kfree(udc);
 
        the_controller = NULL;
 
@@ -1927,33 +1958,46 @@ static int mv_udc_remove(struct platform_device *dev)
 
 int mv_udc_probe(struct platform_device *dev)
 {
+       struct mv_usb_platform_data *pdata = dev->dev.platform_data;
        struct mv_udc *udc;
        int retval = 0;
+       int clk_i = 0;
        struct resource *r;
        size_t size;
 
-       udc = kzalloc(sizeof *udc, GFP_KERNEL);
+       if (pdata == NULL) {
+               dev_err(&dev->dev, "missing platform_data\n");
+               return -ENODEV;
+       }
+
+       size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum;
+       udc = kzalloc(size, GFP_KERNEL);
        if (udc == NULL) {
                dev_err(&dev->dev, "failed to allocate memory for udc\n");
-               retval = -ENOMEM;
-               goto error;
+               return -ENOMEM;
        }
 
+       the_controller = udc;
+       udc->done = &release_done;
+       udc->pdata = dev->dev.platform_data;
        spin_lock_init(&udc->lock);
 
        udc->dev = dev;
 
-       udc->clk = clk_get(&dev->dev, "U2OCLK");
-       if (IS_ERR(udc->clk)) {
-               retval = PTR_ERR(udc->clk);
-               goto error;
+       udc->clknum = pdata->clknum;
+       for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
+               udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]);
+               if (IS_ERR(udc->clk[clk_i])) {
+                       retval = PTR_ERR(udc->clk[clk_i]);
+                       goto err_put_clk;
+               }
        }
 
-       r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2o");
+       r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs");
        if (r == NULL) {
                dev_err(&dev->dev, "no I/O memory resource defined\n");
                retval = -ENODEV;
-               goto error;
+               goto err_put_clk;
        }
 
        udc->cap_regs = (struct mv_cap_regs __iomem *)
@@ -1961,29 +2005,31 @@ int mv_udc_probe(struct platform_device *dev)
        if (udc->cap_regs == NULL) {
                dev_err(&dev->dev, "failed to map I/O memory\n");
                retval = -EBUSY;
-               goto error;
+               goto err_put_clk;
        }
 
-       r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2ophy");
+       r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs");
        if (r == NULL) {
                dev_err(&dev->dev, "no phy I/O memory resource defined\n");
                retval = -ENODEV;
-               goto error;
+               goto err_iounmap_capreg;
        }
 
        udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r));
        if (udc->phy_regs == 0) {
                dev_err(&dev->dev, "failed to map phy I/O memory\n");
                retval = -EBUSY;
-               goto error;
+               goto err_iounmap_capreg;
        }
 
        /* we will acces controller register, so enable the clk */
-       clk_enable(udc->clk);
-       retval = mv_udc_phy_init(udc->phy_regs);
-       if (retval) {
-               dev_err(&dev->dev, "phy initialization error %d\n", retval);
-               goto error;
+       udc_clock_enable(udc);
+       if (pdata->phy_init) {
+               retval = pdata->phy_init(udc->phy_regs);
+               if (retval) {
+                       dev_err(&dev->dev, "phy init error %d\n", retval);
+                       goto err_iounmap_phyreg;
+               }
        }
 
        udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs
@@ -1999,7 +2045,7 @@ int mv_udc_probe(struct platform_device *dev)
        if (udc->ep_dqh == NULL) {
                dev_err(&dev->dev, "allocate dQH memory failed\n");
                retval = -ENOMEM;
-               goto error;
+               goto err_disable_clock;
        }
        udc->ep_dqh_size = size;
 
@@ -2012,7 +2058,7 @@ int mv_udc_probe(struct platform_device *dev)
 
        if (!udc->dtd_pool) {
                retval = -ENOMEM;
-               goto error;
+               goto err_free_dma;
        }
 
        size = udc->max_eps * sizeof(struct mv_ep) *2;
@@ -2020,7 +2066,7 @@ int mv_udc_probe(struct platform_device *dev)
        if (udc->eps == NULL) {
                dev_err(&dev->dev, "allocate ep memory failed\n");
                retval = -ENOMEM;
-               goto error;
+               goto err_destroy_dma;
        }
 
        /* initialize ep0 status request structure */
@@ -2028,7 +2074,7 @@ int mv_udc_probe(struct platform_device *dev)
        if (!udc->status_req) {
                dev_err(&dev->dev, "allocate status_req memory failed\n");
                retval = -ENOMEM;
-               goto error;
+               goto err_free_eps;
        }
        INIT_LIST_HEAD(&udc->status_req->queue);
 
@@ -2045,7 +2091,7 @@ int mv_udc_probe(struct platform_device *dev)
        if (r == NULL) {
                dev_err(&dev->dev, "no IRQ resource defined\n");
                retval = -ENODEV;
-               goto error;
+               goto err_free_status_req;
        }
        udc->irq = r->start;
        if (request_irq(udc->irq, mv_udc_irq,
@@ -2053,7 +2099,7 @@ int mv_udc_probe(struct platform_device *dev)
                dev_err(&dev->dev, "Request irq %d for UDC failed\n",
                        udc->irq);
                retval = -ENODEV;
-               goto error;
+               goto err_free_status_req;
        }
 
        /* initialize gadget structure */
@@ -2072,18 +2118,43 @@ int mv_udc_probe(struct platform_device *dev)
 
        retval = device_register(&udc->gadget.dev);
        if (retval)
-               goto error;
+               goto err_free_irq;
 
        eps_init(udc);
 
-       the_controller = udc;
-
        retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
-       if (!retval)
-               return retval;
-error:
-       if (udc)
-               mv_udc_remove(udc->dev);
+       if (retval)
+               goto err_unregister;
+
+       return 0;
+
+err_unregister:
+       device_unregister(&udc->gadget.dev);
+err_free_irq:
+       free_irq(udc->irq, &dev->dev);
+err_free_status_req:
+       kfree(udc->status_req->req.buf);
+       kfree(udc->status_req);
+err_free_eps:
+       kfree(udc->eps);
+err_destroy_dma:
+       dma_pool_destroy(udc->dtd_pool);
+err_free_dma:
+       dma_free_coherent(&dev->dev, udc->ep_dqh_size,
+                       udc->ep_dqh, udc->ep_dqh_dma);
+err_disable_clock:
+       if (udc->pdata->phy_deinit)
+               udc->pdata->phy_deinit(udc->phy_regs);
+       udc_clock_disable(udc);
+err_iounmap_phyreg:
+       iounmap((void *)udc->phy_regs);
+err_iounmap_capreg:
+       iounmap(udc->cap_regs);
+err_put_clk:
+       for (clk_i--; clk_i >= 0; clk_i--)
+               clk_put(udc->clk[clk_i]);
+       the_controller = NULL;
+       kfree(udc);
        return retval;
 }
 
@@ -2102,11 +2173,16 @@ static int mv_udc_resume(struct device *_dev)
        struct mv_udc *udc = the_controller;
        int retval;
 
-       retval = mv_udc_phy_init(udc->phy_regs);
-       if (retval) {
-               dev_err(_dev, "phy initialization error %d\n", retval);
-               return retval;
+       if (udc->pdata->phy_init) {
+               retval = udc->pdata->phy_init(udc->phy_regs);
+               if (retval) {
+                       dev_err(&udc->dev->dev,
+                               "init phy error %d when resume back\n",
+                               retval);
+                       return retval;
+               }
        }
+
        udc_reset(udc);
        ep0_reset(udc);
        udc_start(udc);
diff --git a/drivers/usb/gadget/mv_udc_phy.c b/drivers/usb/gadget/mv_udc_phy.c
deleted file mode 100644 (file)
index d4dea97..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/io.h>
-#include <linux/errno.h>
-
-#include <mach/cputype.h>
-
-#ifdef CONFIG_ARCH_MMP
-
-#define UTMI_REVISION          0x0
-#define UTMI_CTRL              0x4
-#define UTMI_PLL               0x8
-#define UTMI_TX                        0xc
-#define UTMI_RX                        0x10
-#define UTMI_IVREF             0x14
-#define UTMI_T0                        0x18
-#define UTMI_T1                        0x1c
-#define UTMI_T2                        0x20
-#define UTMI_T3                        0x24
-#define UTMI_T4                        0x28
-#define UTMI_T5                        0x2c
-#define UTMI_RESERVE           0x30
-#define UTMI_USB_INT           0x34
-#define UTMI_DBG_CTL           0x38
-#define UTMI_OTG_ADDON         0x3c
-
-/* For UTMICTRL Register */
-#define UTMI_CTRL_USB_CLK_EN                   (1 << 31)
-/* pxa168 */
-#define UTMI_CTRL_SUSPEND_SET1                 (1 << 30)
-#define UTMI_CTRL_SUSPEND_SET2                 (1 << 29)
-#define UTMI_CTRL_RXBUF_PDWN                   (1 << 24)
-#define UTMI_CTRL_TXBUF_PDWN                   (1 << 11)
-
-#define UTMI_CTRL_INPKT_DELAY_SHIFT            30
-#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT                28
-#define UTMI_CTRL_PU_REF_SHIFT                 20
-#define UTMI_CTRL_ARC_PULLDN_SHIFT             12
-#define UTMI_CTRL_PLL_PWR_UP_SHIFT             1
-#define UTMI_CTRL_PWR_UP_SHIFT                 0
-/* For UTMI_PLL Register */
-#define UTMI_PLL_CLK_BLK_EN_SHIFT              24
-#define UTMI_PLL_FBDIV_SHIFT                   4
-#define UTMI_PLL_REFDIV_SHIFT                  0
-#define UTMI_PLL_FBDIV_MASK                    0x00000FF0
-#define UTMI_PLL_REFDIV_MASK                   0x0000000F
-#define UTMI_PLL_ICP_MASK                      0x00007000
-#define UTMI_PLL_KVCO_MASK                     0x00031000
-#define UTMI_PLL_PLLCALI12_SHIFT               29
-#define UTMI_PLL_PLLCALI12_MASK                        (0x3 << 29)
-#define UTMI_PLL_PLLVDD18_SHIFT                        27
-#define UTMI_PLL_PLLVDD18_MASK                 (0x3 << 27)
-#define UTMI_PLL_PLLVDD12_SHIFT                        25
-#define UTMI_PLL_PLLVDD12_MASK                 (0x3 << 25)
-#define UTMI_PLL_KVCO_SHIFT                    15
-#define UTMI_PLL_ICP_SHIFT                     12
-/* For UTMI_TX Register */
-#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT          27
-#define UTMI_TX_REG_EXT_FS_RCAL_MASK           (0xf << 27)
-#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK                26
-#define UTMI_TX_REG_EXT_FS_RCAL_EN             (0x1 << 26)
-#define UTMI_TX_LOW_VDD_EN_SHIFT               11
-#define UTMI_TX_IMPCAL_VTH_SHIFT               14
-#define UTMI_TX_IMPCAL_VTH_MASK                        (0x7 << 14)
-#define UTMI_TX_CK60_PHSEL_SHIFT               17
-#define UTMI_TX_CK60_PHSEL_MASK                        (0xf << 17)
-#define UTMI_TX_TXVDD12_SHIFT                   22
-#define UTMI_TX_TXVDD12_MASK                   (0x3 << 22)
-#define UTMI_TX_AMP_SHIFT                      0
-#define UTMI_TX_AMP_MASK                       (0x7 << 0)
-/* For UTMI_RX Register */
-#define UTMI_RX_SQ_THRESH_SHIFT                        4
-#define UTMI_RX_SQ_THRESH_MASK                 (0xf << 4)
-#define UTMI_REG_SQ_LENGTH_SHIFT               15
-#define UTMI_REG_SQ_LENGTH_MASK                        (0x3 << 15)
-
-#define REG_RCAL_START                         0x00001000
-#define VCOCAL_START                           0x00200000
-#define KVCO_EXT                               0x00400000
-#define PLL_READY                              0x00800000
-#define CLK_BLK_EN                             0x01000000
-#endif
-
-static unsigned int u2o_read(unsigned int base, unsigned int offset)
-{
-       return readl(base + offset);
-}
-
-static void u2o_set(unsigned int base, unsigned int offset, unsigned int value)
-{
-       unsigned int reg;
-
-       reg = readl(base + offset);
-       reg |= value;
-       writel(reg, base + offset);
-       readl(base + offset);
-}
-
-static void u2o_clear(unsigned int base, unsigned int offset,
-       unsigned int value)
-{
-       unsigned int reg;
-
-       reg = readl(base + offset);
-       reg &= ~value;
-       writel(reg, base + offset);
-       readl(base + offset);
-}
-
-static void u2o_write(unsigned int base, unsigned int offset,
-       unsigned int value)
-{
-       writel(value, base + offset);
-       readl(base + offset);
-}
-
-#ifdef CONFIG_ARCH_MMP
-int mv_udc_phy_init(unsigned int base)
-{
-       unsigned long timeout;
-
-       /* Initialize the USB PHY power */
-       if (cpu_is_pxa910()) {
-               u2o_set(base, UTMI_CTRL, (1 << UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
-                       | (1 << UTMI_CTRL_PU_REF_SHIFT));
-       }
-
-       u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PLL_PWR_UP_SHIFT);
-       u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PWR_UP_SHIFT);
-
-       /* UTMI_PLL settings */
-       u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
-               | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
-               | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
-               | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
-
-       u2o_set(base, UTMI_PLL, (0xee << UTMI_PLL_FBDIV_SHIFT)
-               | (0xb << UTMI_PLL_REFDIV_SHIFT)
-               | (3 << UTMI_PLL_PLLVDD18_SHIFT)
-               | (3 << UTMI_PLL_PLLVDD12_SHIFT)
-               | (3 << UTMI_PLL_PLLCALI12_SHIFT)
-               | (1 << UTMI_PLL_ICP_SHIFT) | (3 << UTMI_PLL_KVCO_SHIFT));
-
-       /* UTMI_TX */
-       u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
-               | UTMI_TX_TXVDD12_MASK
-               | UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK
-               | UTMI_TX_REG_EXT_FS_RCAL_MASK | UTMI_TX_AMP_MASK);
-       u2o_set(base, UTMI_TX, (3 << UTMI_TX_TXVDD12_SHIFT)
-               | (4 << UTMI_TX_CK60_PHSEL_SHIFT)
-               | (4 << UTMI_TX_IMPCAL_VTH_SHIFT)
-               | (8 << UTMI_TX_REG_EXT_FS_RCAL_SHIFT)
-               | (3 << UTMI_TX_AMP_SHIFT));
-
-       /* UTMI_RX */
-       u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
-               | UTMI_REG_SQ_LENGTH_MASK);
-       if (cpu_is_pxa168())
-               u2o_set(base, UTMI_RX, (7 << UTMI_RX_SQ_THRESH_SHIFT)
-                       | (2 << UTMI_REG_SQ_LENGTH_SHIFT));
-       else
-               u2o_set(base, UTMI_RX, (0x7 << UTMI_RX_SQ_THRESH_SHIFT)
-                       | (2 << UTMI_REG_SQ_LENGTH_SHIFT));
-
-       /* UTMI_IVREF */
-       if (cpu_is_pxa168())
-               /*
-                * fixing Microsoft Altair board interface with NEC hub issue -
-                * Set UTMI_IVREF from 0x4a3 to 0x4bf
-                */
-               u2o_write(base, UTMI_IVREF, 0x4bf);
-
-       /* calibrate */
-       timeout = jiffies + 100;
-       while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) {
-               if (time_after(jiffies, timeout))
-                       return -ETIME;
-               cpu_relax();
-       }
-
-       /* toggle VCOCAL_START bit of UTMI_PLL */
-       udelay(200);
-       u2o_set(base, UTMI_PLL, VCOCAL_START);
-       udelay(40);
-       u2o_clear(base, UTMI_PLL, VCOCAL_START);
-
-       /* toggle REG_RCAL_START bit of UTMI_TX */
-       udelay(200);
-       u2o_set(base, UTMI_TX, REG_RCAL_START);
-       udelay(40);
-       u2o_clear(base, UTMI_TX, REG_RCAL_START);
-       udelay(200);
-
-       /* make sure phy is ready */
-       timeout = jiffies + 100;
-       while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) {
-               if (time_after(jiffies, timeout))
-                       return -ETIME;
-               cpu_relax();
-       }
-
-       if (cpu_is_pxa168()) {
-               u2o_set(base, UTMI_RESERVE, 1 << 5);
-               /* Turn on UTMI PHY OTG extension */
-               u2o_write(base, UTMI_OTG_ADDON, 1);
-       }
-       return 0;
-}
-#else
-int mv_udc_phy_init(unsigned int base)
-{
-       return 0;
-}
-#endif
diff --git a/include/linux/platform_data/mv_usb.h b/include/linux/platform_data/mv_usb.h
new file mode 100644 (file)
index 0000000..e9d9149
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MV_PLATFORM_USB_H
+#define __MV_PLATFORM_USB_H
+
+enum pxa_ehci_type {
+       EHCI_UNDEFINED = 0,
+       PXA_U2OEHCI,    /* pxa 168, 9xx */
+       PXA_SPH,        /* pxa 168, 9xx SPH */
+       MMP3_HSIC,      /* mmp3 hsic */
+       MMP3_FSIC,      /* mmp3 fsic */
+};
+
+enum {
+       MV_USB_MODE_OTG,
+       MV_USB_MODE_HOST,
+};
+
+enum {
+       VBUS_LOW        = 0,
+       VBUS_HIGH       = 1 << 0,
+};
+
+struct mv_usb_addon_irq {
+       unsigned int    irq;
+       int             (*poll)(void);
+};
+
+struct mv_usb_platform_data {
+       unsigned int            clknum;
+       char                    **clkname;
+       struct mv_usb_addon_irq *id;    /* Only valid for OTG. ID pin change*/
+       struct mv_usb_addon_irq *vbus;  /* valid for OTG/UDC. VBUS change*/
+
+       /* only valid for HCD. OTG or Host only*/
+       unsigned int            mode;
+
+       int     (*phy_init)(unsigned int regbase);
+       void    (*phy_deinit)(unsigned int regbase);
+       int     (*set_vbus)(unsigned int vbus);
+};
+
+#endif