]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
usb: musb: dma: Add a DMA completion platform callback
authorAlexandre Bailon <abailon@baylibre.com>
Tue, 7 Feb 2017 04:53:51 +0000 (22:53 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Feb 2017 12:35:05 +0000 (13:35 +0100)
Currently, the CPPI 4.1 driver is not completely generic and
only works on DSPS. This is because of IRQ management.
Add a callback to dma_controller that could be invoked on DMA completion
to acknowledge the IRQ.

Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/musb/musb_cppi41.c
drivers/usb/musb/musb_dma.h

index 16363852c0346b28b6452e04eddedfc630635428..f7d3d27fd2c1ec9563f7e55dc1f0a2b4bc089ef3 100644 (file)
@@ -217,6 +217,10 @@ static void cppi41_dma_callback(void *private_data)
        int is_hs = 0;
        bool empty;
 
+       controller = cppi41_channel->controller;
+       if (controller->controller.dma_callback)
+               controller->controller.dma_callback(&controller->controller);
+
        spin_lock_irqsave(&musb->lock, flags);
 
        dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
@@ -249,8 +253,6 @@ static void cppi41_dma_callback(void *private_data)
         * We spin on HS (no longer than than 25us and setup a timer on
         * FS to check for the bit and complete the transfer.
         */
-       controller = cppi41_channel->controller;
-
        if (is_host_active(musb)) {
                if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED)
                        is_hs = 1;
@@ -695,6 +697,7 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base)
        controller->controller.channel_program = cppi41_dma_channel_program;
        controller->controller.channel_abort = cppi41_dma_channel_abort;
        controller->controller.is_compatible = cppi41_is_compatible;
+       controller->controller.musb = musb;
 
        ret = cppi41_dma_controller_start(controller);
        if (ret)
index 46357e183b4c8b764045091dd2153a09df2d3789..04c3bd86bd620e2ae1ebeaa778a52cf8abea2be2 100644 (file)
@@ -173,6 +173,7 @@ dma_channel_status(struct dma_channel *c)
 
 /**
  * struct dma_controller - A DMA Controller.
+ * @musb: the usb controller
  * @start: call this to start a DMA controller;
  *     return 0 on success, else negative errno
  * @stop: call this to stop a DMA controller
@@ -181,10 +182,13 @@ dma_channel_status(struct dma_channel *c)
  * @channel_release: call this to release a DMA channel
  * @channel_abort: call this to abort a pending DMA transaction,
  *     returning it to FREE (but allocated) state
+ * @dma_callback: invoked on DMA completion, useful to run platform
+ *     code such IRQ acknowledgment.
  *
  * Controllers manage dma channels.
  */
 struct dma_controller {
+       struct musb *musb;
        struct dma_channel      *(*channel_alloc)(struct dma_controller *,
                                        struct musb_hw_ep *, u8 is_tx);
        void                    (*channel_release)(struct dma_channel *);
@@ -196,6 +200,7 @@ struct dma_controller {
        int                     (*is_compatible)(struct dma_channel *channel,
                                                        u16 maxpacket,
                                                        void *buf, u32 length);
+       void                    (*dma_callback)(struct dma_controller *);
 };
 
 /* called after channel_program(), may indicate a fault */