usb: musb: dma: Add a DMA completion platform callback
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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
7c92e5fbf4
commit
050dc900cf
@@ -217,6 +217,10 @@ static void cppi41_dma_callback(void *private_data)
|
|||||||
int is_hs = 0;
|
int is_hs = 0;
|
||||||
bool empty;
|
bool empty;
|
||||||
|
|
||||||
|
controller = cppi41_channel->controller;
|
||||||
|
if (controller->controller.dma_callback)
|
||||||
|
controller->controller.dma_callback(&controller->controller);
|
||||||
|
|
||||||
spin_lock_irqsave(&musb->lock, flags);
|
spin_lock_irqsave(&musb->lock, flags);
|
||||||
|
|
||||||
dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
|
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
|
* We spin on HS (no longer than than 25us and setup a timer on
|
||||||
* FS to check for the bit and complete the transfer.
|
* FS to check for the bit and complete the transfer.
|
||||||
*/
|
*/
|
||||||
controller = cppi41_channel->controller;
|
|
||||||
|
|
||||||
if (is_host_active(musb)) {
|
if (is_host_active(musb)) {
|
||||||
if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED)
|
if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED)
|
||||||
is_hs = 1;
|
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_program = cppi41_dma_channel_program;
|
||||||
controller->controller.channel_abort = cppi41_dma_channel_abort;
|
controller->controller.channel_abort = cppi41_dma_channel_abort;
|
||||||
controller->controller.is_compatible = cppi41_is_compatible;
|
controller->controller.is_compatible = cppi41_is_compatible;
|
||||||
|
controller->controller.musb = musb;
|
||||||
|
|
||||||
ret = cppi41_dma_controller_start(controller);
|
ret = cppi41_dma_controller_start(controller);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@@ -173,6 +173,7 @@ dma_channel_status(struct dma_channel *c)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dma_controller - A DMA Controller.
|
* struct dma_controller - A DMA Controller.
|
||||||
|
* @musb: the usb controller
|
||||||
* @start: call this to start a DMA controller;
|
* @start: call this to start a DMA controller;
|
||||||
* return 0 on success, else negative errno
|
* return 0 on success, else negative errno
|
||||||
* @stop: call this to stop a DMA controller
|
* @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_release: call this to release a DMA channel
|
||||||
* @channel_abort: call this to abort a pending DMA transaction,
|
* @channel_abort: call this to abort a pending DMA transaction,
|
||||||
* returning it to FREE (but allocated) state
|
* 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.
|
* Controllers manage dma channels.
|
||||||
*/
|
*/
|
||||||
struct dma_controller {
|
struct dma_controller {
|
||||||
|
struct musb *musb;
|
||||||
struct dma_channel *(*channel_alloc)(struct dma_controller *,
|
struct dma_channel *(*channel_alloc)(struct dma_controller *,
|
||||||
struct musb_hw_ep *, u8 is_tx);
|
struct musb_hw_ep *, u8 is_tx);
|
||||||
void (*channel_release)(struct dma_channel *);
|
void (*channel_release)(struct dma_channel *);
|
||||||
@@ -196,6 +200,7 @@ struct dma_controller {
|
|||||||
int (*is_compatible)(struct dma_channel *channel,
|
int (*is_compatible)(struct dma_channel *channel,
|
||||||
u16 maxpacket,
|
u16 maxpacket,
|
||||||
void *buf, u32 length);
|
void *buf, u32 length);
|
||||||
|
void (*dma_callback)(struct dma_controller *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* called after channel_program(), may indicate a fault */
|
/* called after channel_program(), may indicate a fault */
|
||||||
|
Reference in New Issue
Block a user