@@ -36,6 +36,8 @@ struct cppi41_dma_controller {
u32 rx_mode;
u32 tx_mode;
u32 auto_req;
+
+ cppi41_platform_dma_callback dma_callback;
};
static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
@@ -217,6 +219,10 @@ static void cppi41_dma_callback(void *private_data)
int is_hs = 0;
bool empty;
+ controller = cppi41_channel->controller;
+ if (controller->dma_callback)
+ controller->dma_callback(musb);
+
spin_lock_irqsave(&musb->lock, flags);
dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
@@ -249,8 +255,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;
@@ -288,6 +292,16 @@ static void cppi41_dma_callback(void *private_data)
spin_unlock_irqrestore(&musb->lock, flags);
}
+void cppi41_register_dma_callback(struct dma_controller *c,
+ cppi41_platform_dma_callback callback)
+{
+ struct cppi41_dma_controller *controller = container_of(c,
+ struct cppi41_dma_controller, controller);
+
+ controller->dma_callback = callback;
+}
+EXPORT_SYMBOL_GPL(cppi41_register_dma_callback);
+
static u32 update_ep_mode(unsigned ep, unsigned mode, u32 old)
{
unsigned shift;
@@ -709,3 +723,12 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base)
return NULL;
}
EXPORT_SYMBOL_GPL(cppi41_dma_controller_create);
+
+struct musb *cppi41_dma_controller_to_musb(struct dma_controller *c)
+{
+ struct cppi41_dma_controller *controller = container_of(c,
+ struct cppi41_dma_controller, controller);
+
+ return controller->musb;
+}
+EXPORT_SYMBOL_GPL(cppi41_dma_controller_to_musb);
@@ -231,9 +231,13 @@ extern struct dma_controller *
cppi_dma_controller_create(struct musb *musb, void __iomem *base);
extern void cppi_dma_controller_destroy(struct dma_controller *c);
+typedef void (*cppi41_platform_dma_callback)(struct musb *musb);
extern struct dma_controller *
cppi41_dma_controller_create(struct musb *musb, void __iomem *base);
extern void cppi41_dma_controller_destroy(struct dma_controller *c);
+extern struct musb *cppi41_dma_controller_to_musb(struct dma_controller *c);
+extern void cppi41_register_dma_callback(struct dma_controller *c,
+ cppi41_platform_dma_callback callback);
extern struct dma_controller *
ux500_dma_controller_create(struct musb *musb, void __iomem *base);
Currently, the CPPI 4.1 driver is not completely generic and only work on dsps. Add two methods which will help to move platform code from CPPI 4.1 to MUSB glue driver: - cppi41_register_dma_callback() to register a platform dma_callback (e.g to acknowledge interrupt on DMA completion). - cppi41_dma_controller_to_musb() to convert a dma_controller pointer to a musb pointer. This required to get a musb pointer from DMA callbacks. Signed-off-by: Alexandre Bailon <abailon@baylibre.com> --- drivers/usb/musb/musb_cppi41.c | 27 +++++++++++++++++++++++++-- drivers/usb/musb/musb_dma.h | 4 ++++ 2 files changed, 29 insertions(+), 2 deletions(-)