usb: musb: support each dma controller driver built as module
authorRavi B <ravibabu@ti.com>
Tue, 14 Jun 2011 08:57:52 +0000 (14:27 +0530)
committerVaibhav Hiremath <hvaibhav@ti.com>
Mon, 23 Jan 2012 19:14:05 +0000 (00:44 +0530)
This patch provides support for building each dma controller driver
as standalone module, and this modules can be built into one same
image and can be used by each hw glue driver.

HW glue driver has the knowledge of which type of dma controller will
be used, and can pass the knowledge into musb core driver via glue ops,
so we can take runtime method to support all hw controller and its dma
controller in one binary musb driver.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
drivers/usb/musb/Kconfig
drivers/usb/musb/Makefile
drivers/usb/musb/blackfin.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_dma.h
drivers/usb/musb/musbhsdma.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010_omap.c

index 7724c6b4870fe06c211a903310975e26dc730e72..27cd35c92afffdd37aca6ea20da1a08d51e793d6 100644 (file)
@@ -93,36 +93,40 @@ config USB_MUSB_UX500
 
 choice
        prompt 'MUSB DMA mode'
-       default USB_UX500_DMA if USB_MUSB_UX500
-       default USB_INVENTRA_DMA if USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
-       default USB_TI_CPPI_DMA if USB_MUSB_DAVINCI
-       default USB_TUSB_OMAP_DMA if USB_MUSB_TUSB6010
+       default USB_UX500_DMA_HW if USB_MUSB_UX500
+       default USB_INVENTRA_DMA_HW if USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
+       default USB_TI_CPPI_DMA_HW if USB_MUSB_DAVINCI
+       default USB_TUSB_OMAP_DMA_HW if USB_MUSB_TUSB6010
        default MUSB_PIO_ONLY if USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X
        help
          Unfortunately, only one option can be enabled here. Ideally one
          should be able to build all these drivers into one kernel to
          allow using DMA on multiplatform kernels.
 
-config USB_UX500_DMA
-       bool 'ST Ericsson U8500 and U5500'
+config USB_UX500_DMA_HW
+       tristate 'ST Ericsson U8500 and U5500'
+       select USB_UX500_DMA
        depends on USB_MUSB_UX500
        help
          Enable DMA transfers on UX500 platforms.
 
-config USB_INVENTRA_DMA
-       bool 'Inventra'
+config USB_INVENTRA_DMA_HW
+       tristate 'Inventra'
+       select USB_INVENTRA_DMA
        depends on USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
        help
          Enable DMA transfers using Mentor's engine.
 
-config USB_TI_CPPI_DMA
-       bool 'TI CPPI (Davinci)'
+config USB_TI_CPPI_DMA_HW
+       tristate 'TI CPPI (Davinci)'
+       select USB_TI_CPPI_DMA
        depends on USB_MUSB_DAVINCI
        help
          Enable DMA transfers when TI CPPI DMA is available.
 
-config USB_TUSB_OMAP_DMA
-       bool 'TUSB 6010'
+config USB_TUSB_OMAP_DMA_HW
+       tristate 'TUSB 6010'
+       select USB_TUSB_OMAP_DMA
        depends on USB_MUSB_TUSB6010
        depends on ARCH_OMAP
        help
@@ -141,4 +145,20 @@ config MUSB_PIO_ONLY
 
 endchoice
 
+config USB_INVENTRA_DMA
+       bool
+       default n
+
+config USB_TI_CPPI_DMA
+       bool
+       default n
+
+config USB_TUSB_OMAP_DMA
+       bool
+       default n
+
+config USB_UX500_DMA
+       bool
+       default n
+
 endif # USB_MUSB_HDRC
index faf6a81efbe7a58f9efd3ee78136935849ec19ac..70d19299e41cbdf32896916288ae2fccd25a9617 100644 (file)
@@ -24,7 +24,7 @@ obj-$(CONFIG_USB_MUSB_UX500_GLUE)                     += ux500.o
 # PIO only, or DMA (several potential schemes).
 # though PIO is always there to back up DMA, and for ep0
 
-musb_hdrc-$(CONFIG_USB_INVENTRA_DMA)           += musbhsdma.o
-musb_hdrc-$(CONFIG_USB_TI_CPPI_DMA)            += cppi_dma.o
-musb_hdrc-$(CONFIG_USB_TUSB_OMAP_DMA)          += tusb6010_omap.o
-musb_hdrc-$(CONFIG_USB_UX500_DMA)              += ux500_dma.o
+obj-$(CONFIG_USB_INVENTRA_DMA_HW)              += musbhsdma.o
+obj-$(CONFIG_USB_TI_CPPI_DMA_HW)               += cppi_dma.o
+obj-$(CONFIG_USB_TUSB_OMAP_DMA_HW)             += tusb6010_omap.o
+obj-$(CONFIG_USB_UX500_DMA_HW)                 += ux500_dma.o
index 69cf0890cb0ada4b94bdf7bff8ca3adebdda2234..bef9ef2ef3bc2a265610805d9d93b4a19f8aac03 100644 (file)
@@ -448,7 +448,8 @@ static int bfin_musb_exit(struct musb *musb)
 
 static const struct musb_platform_ops bfin_ops = {
        .fifo_mode      = 2,
-       .flags          = MUSB_GLUE_EP_ADDR_FLAT_MAPPING,
+       .flags          = MUSB_GLUE_EP_ADDR_FLAT_MAPPING |
+                               MUSB_GLUE_DMA_INVENTRA,
        .init           = bfin_musb_init,
        .exit           = bfin_musb_exit,
 
@@ -465,6 +466,9 @@ static const struct musb_platform_ops bfin_ops = {
        .set_vbus       = bfin_musb_set_vbus,
 
        .adjust_channel_params = bfin_musb_adjust_channel_params,
+
+       .dma_controller_create = inventra_dma_controller_create,
+       .dma_controller_destroy = inventra_dma_controller_destroy,
 };
 
 static u64 bfin_dmamask = DMA_BIT_MASK(32);
index 6b216bb62232c3638495bdd250b8bac4b9cc9415..94db2e9e7829b6c5322656d8b669377395efd25e 100644 (file)
@@ -1318,7 +1318,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
 
 /* Instantiate a software object representing a DMA controller. */
 struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *mregs)
+cppi_dma_controller_create(struct musb *musb, void __iomem *mregs)
 {
        struct cppi             *controller;
        struct device           *dev = musb->controller;
@@ -1357,7 +1357,7 @@ dma_controller_create(struct musb *musb, void __iomem *mregs)
        if (irq > 0) {
                if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) {
                        dev_err(dev, "request_irq %d failed!\n", irq);
-                       dma_controller_destroy(&controller->controller);
+                       cppi_dma_controller_destroy(&controller->controller);
                        return NULL;
                }
                controller->irq = irq;
@@ -1365,11 +1365,12 @@ dma_controller_create(struct musb *musb, void __iomem *mregs)
 
        return &controller->controller;
 }
+EXPORT_SYMBOL(cppi_dma_controller_create);
 
 /*
  *  Destroy a previously-instantiated DMA controller.
  */
-void dma_controller_destroy(struct dma_controller *c)
+void cppi_dma_controller_destroy(struct dma_controller *c)
 {
        struct cppi     *cppi;
 
@@ -1383,6 +1384,7 @@ void dma_controller_destroy(struct dma_controller *c)
 
        kfree(cppi);
 }
+EXPORT_SYMBOL(cppi_dma_controller_destroy);
 
 /*
  * Context: controller irqlocked, endpoint selected
@@ -1563,3 +1565,16 @@ static int cppi_channel_abort(struct dma_channel *channel)
  * Power Management ... probably turn off cppi during suspend, restart;
  * check state ram?  Clocking is presumably shared with usb core.
  */
+MODULE_DESCRIPTION("CPPI dma controller driver for musb");
+MODULE_LICENSE("GPL v2");
+
+static int __init cppi_dma_init(void)
+{
+       return 0;
+}
+module_init(cppi_dma_init);
+
+static void __exit cppi_dma__exit(void)
+{
+}
+module_exit(cppi_dma__exit);
index f8b92ad575f6e74adad648f2bd54d9a856f3eb31..ba181dcb6f1908a879ef47e57005851b7547da5b 100644 (file)
@@ -502,7 +502,7 @@ static int davinci_musb_exit(struct musb *musb)
 
 static const struct musb_platform_ops davinci_ops = {
        .fifo_mode      = 2,
-       .flags          = MUSB_GLUE_EP_ADDR_FLAT_MAPPING,
+       .flags          = MUSB_GLUE_EP_ADDR_FLAT_MAPPING | MUSB_GLUE_DMA_CPPI,
        .init           = davinci_musb_init,
        .exit           = davinci_musb_exit,
 
@@ -515,6 +515,9 @@ static const struct musb_platform_ops davinci_ops = {
 
        .read_fifo      = musb_read_fifo,
        .write_fifo     = musb_write_fifo,
+
+       .dma_controller_create = cppi_dma_controller_create,
+       .dma_controller_destroy = cppi_dma_controller_destroy,
 };
 
 static u64 davinci_dmamask = DMA_BIT_MASK(32);
index aa8f23fb590e60192a79213257b42c7f6fdfb969..3cb4efc5d054320cce1ff9cf58a05af7ab7c41b4 100644 (file)
@@ -1872,7 +1872,7 @@ static void musb_free(struct musb *musb)
                struct dma_controller   *c = musb->dma_controller;
 
                (void) c->stop(c);
-               dma_controller_destroy(c);
+               musb->ops->dma_controller_destroy(c);
        }
 
        kfree(musb);
@@ -1959,7 +1959,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        if (use_dma && dev->dma_mask) {
                struct dma_controller   *c;
 
-               c = dma_controller_create(musb, musb->mregs);
+               if (!musb->ops->dma_controller_create) {
+                       dev_err(dev, "no dma_controller_create for non-PIO mode!\n");
+                       status = -ENODEV;
+                       goto fail3;
+               }
+               c = musb->ops->dma_controller_create(musb, musb->mregs);
                musb->dma_controller = c;
                if (c)
                        (void) c->start(c);
index 24d39210d4abf7a855b8ac8ffd74c3eef989fc0b..a6d96138e88d49e02ae68300d53a77cfa17044e6 100644 (file)
@@ -178,9 +178,55 @@ struct dma_controller {
 extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
 
 
+#ifdef CONFIG_USB_TI_CPPI_DMA
 extern struct dma_controller *__devinit
-dma_controller_create(struct musb *, void __iomem *);
+cppi_dma_controller_create(struct musb *, void __iomem *);
+
+extern void cppi_dma_controller_destroy(struct dma_controller *);
+#else
+static inline struct dma_controller *__devinit
+cppi_dma_controller_create(struct musb *musb, void __iomem *mregs)
+{
+       return NULL;
+}
+
+static inline void cppi_dma_controller_destroy(struct dma_controller *c)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+extern struct dma_controller *__devinit
+inventra_dma_controller_create(struct musb *, void __iomem *);
+
+extern void inventra_dma_controller_destroy(struct dma_controller *);
+#else
+static inline struct dma_controller *__devinit
+inventra_dma_controller_create(struct musb *musb, void __iomem *mregs)
+{
+       return NULL;
+}
 
-extern void dma_controller_destroy(struct dma_controller *);
+static inline void inventra_dma_controller_destroy(struct dma_controller *c)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_TUSB_OMAP_DMA
+extern struct dma_controller *__devinit
+tusb_dma_controller_create(struct musb *, void __iomem *);
+
+extern void tusb_dma_controller_destroy(struct dma_controller *);
+#else
+static inline struct dma_controller *__devinit
+tusb_dma_controller_create(struct musb *musb, void __iomem *mregs)
+{
+       return NULL;
+}
+
+static inline void tusb_dma_controller_destroy(struct dma_controller *c)
+{
+}
+#endif
 
 #endif /* __MUSB_DMA_H__ */
index 4d7d83bf47db4312977ddb6887e91559d7864d93..9ba7a30cffdb01f49492bbeeebd8b231fb02aa5a 100644 (file)
@@ -30,6 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
@@ -366,7 +367,7 @@ done:
        return retval;
 }
 
-void dma_controller_destroy(struct dma_controller *c)
+void inventra_dma_controller_destroy(struct dma_controller *c)
 {
        struct musb_dma_controller *controller = container_of(c,
                        struct musb_dma_controller, controller);
@@ -379,9 +380,10 @@ void dma_controller_destroy(struct dma_controller *c)
 
        kfree(controller);
 }
+EXPORT_SYMBOL(inventra_dma_controller_destroy);
 
 struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *base)
+inventra_dma_controller_create(struct musb *musb, void __iomem *base)
 {
        struct musb_dma_controller *controller;
        struct device *dev = musb->controller;
@@ -411,7 +413,7 @@ dma_controller_create(struct musb *musb, void __iomem *base)
        if (request_irq(irq, dma_controller_irq, 0,
                        dev_name(musb->controller), &controller->controller)) {
                dev_err(dev, "request_irq %d failed!\n", irq);
-               dma_controller_destroy(&controller->controller);
+               inventra_dma_controller_destroy(&controller->controller);
 
                return NULL;
        }
@@ -420,3 +422,18 @@ dma_controller_create(struct musb *musb, void __iomem *base)
 
        return &controller->controller;
 }
+EXPORT_SYMBOL(inventra_dma_controller_create);
+
+MODULE_DESCRIPTION("MUSB Inventra dma controller driver");
+MODULE_LICENSE("GPL v2");
+
+static int __init inventra_dma_init(void)
+{
+       return 0;
+}
+module_init(inventra_dma_init);
+
+static void __exit inventra_dma__exit(void)
+{
+}
+module_exit(inventra_dma__exit);
index 9c7ae912e7fdd2af7b3378e4a45cb81723da33ad..afd420cccbb9a45377c365165ac360d5ceb426b9 100644 (file)
@@ -395,7 +395,8 @@ static int omap2430_musb_exit(struct musb *musb)
 
 static const struct musb_platform_ops omap2430_ops = {
        .fifo_mode      = 4,
-       .flags          = MUSB_GLUE_EP_ADDR_FLAT_MAPPING,
+       .flags          = MUSB_GLUE_EP_ADDR_FLAT_MAPPING |
+                               MUSB_GLUE_DMA_INVENTRA,
        .init           = omap2430_musb_init,
        .exit           = omap2430_musb_exit,
 
@@ -409,6 +410,9 @@ static const struct musb_platform_ops omap2430_ops = {
 
        .enable         = omap2430_musb_enable,
        .disable        = omap2430_musb_disable,
+
+       .dma_controller_create = inventra_dma_controller_create,
+       .dma_controller_destroy = inventra_dma_controller_destroy,
 };
 
 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
index 235c5b86f496504da45b65da1d328726ac996c40..fff998563e04a24a6e55588ba6c51fa2a7d955f6 100644 (file)
@@ -1169,6 +1169,9 @@ static const struct musb_platform_ops tusb_ops = {
        .set_vbus       = tusb_musb_set_vbus,
        .read_fifo      = tusb_musb_read_fifo,
        .write_fifo     = tusb_musb_write_fifo,
+
+       .dma_controller_create = tusb_dma_controller_create,
+       .dma_controller_destroy = tusb_dma_controller_destroy,
 };
 
 static u64 tusb_dmamask = DMA_BIT_MASK(32);
index 74fa695b0a5c7672d573acc833c7fa502cd7dfcb..4af0c2d8281be79347017bbf8665af1e64d1ff31 100644 (file)
@@ -642,7 +642,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
        channel = NULL;
 }
 
-void dma_controller_destroy(struct dma_controller *c)
+void tusb_dma_controller_destroy(struct dma_controller *c)
 {
        struct tusb_omap_dma    *tusb_dma;
        int                     i;
@@ -661,9 +661,10 @@ void dma_controller_destroy(struct dma_controller *c)
 
        kfree(tusb_dma);
 }
+EXPORT_SYMBOL(tusb_dma_controller_destroy);
 
 struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *base)
+tusb_dma_controller_create(struct musb *musb, void __iomem *base)
 {
        void __iomem            *tbase = musb->ctrl_base;
        struct tusb_omap_dma    *tusb_dma;
@@ -721,7 +722,22 @@ dma_controller_create(struct musb *musb, void __iomem *base)
        return &tusb_dma->controller;
 
 cleanup:
-       dma_controller_destroy(&tusb_dma->controller);
+       tusb_dma_controller_destroy(&tusb_dma->controller);
 out:
        return NULL;
 }
+EXPORT_SYMBOL(tusb_dma_controller_create);
+
+MODULE_DESCRIPTION("TUSB dma controller driver for musb");
+MODULE_LICENSE("GPL v2");
+
+static int __init tusb_dma_init(void)
+{
+       return 0;
+}
+module_init(tusb_dma_init);
+
+static void __exit tusb_dma__exit(void)
+{
+}
+module_exit(tusb_dma__exit);