diff options
Diffstat (limited to 'recipes/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch b/recipes/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch new file mode 100644 index 0000000000..bf3d6e7021 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch @@ -0,0 +1,167 @@ +From b91b067c531c9322f3719951b07303e790b13475 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> +Date: Fri, 27 Mar 2009 12:59:46 -0700 +Subject: [PATCH] musb: split out CPPI interrupt handler + +As DaVinci DM646x has a dedicated CPPI DMA interrupt, replace +cppi_completion() (which has always been kind of layering +violation) by a complete CPPI interrupt handler. + +[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: only cppi_dma.c needs platform +device header, not cppi_dma.h ] + +Signed-off-by: Dmitry Krivoschekov <dkrivoschekov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> +Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> +Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> +--- + drivers/usb/musb/cppi_dma.c | 34 +++++++++++++++++++++++++++++++--- + drivers/usb/musb/cppi_dma.h | 6 ++++-- + drivers/usb/musb/davinci.c | 14 ++++---------- + 3 files changed, 39 insertions(+), 15 deletions(-) + +diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c +index ac7227c..6ff3c67 100644 +--- a/drivers/usb/musb/cppi_dma.c ++++ b/drivers/usb/musb/cppi_dma.c +@@ -6,6 +6,7 @@ + * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci. + */ + ++#include <linux/platform_device.h> + #include <linux/usb.h> + + #include "musb_core.h" +@@ -1145,17 +1146,27 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) + return completed; + } + +-void cppi_completion(struct musb *musb, u32 rx, u32 tx) ++irqreturn_t cppi_interrupt(int irq, void *dev_id) + { +- void __iomem *tibase; +- int i, index; ++ struct musb *musb = dev_id; + struct cppi *cppi; ++ void __iomem *tibase; + struct musb_hw_ep *hw_ep = NULL; ++ u32 rx, tx; ++ int i, index; + + cppi = container_of(musb->dma_controller, struct cppi, controller); + + tibase = musb->ctrl_base; + ++ tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); ++ rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); ++ ++ if (!tx && !rx) ++ return IRQ_NONE; ++ ++ DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx); ++ + /* process TX channels */ + for (index = 0; tx; tx = tx >> 1, index++) { + struct cppi_channel *tx_ch; +@@ -1293,6 +1304,8 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx) + + /* write to CPPI EOI register to re-enable interrupts */ + musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); ++ ++ return IRQ_HANDLED; + } + + /* Instantiate a software object representing a DMA controller. */ +@@ -1300,6 +1313,9 @@ struct dma_controller *__init + dma_controller_create(struct musb *musb, void __iomem *mregs) + { + struct cppi *controller; ++ struct device *dev = musb->controller; ++ struct platform_device *pdev = to_platform_device(dev); ++ int irq = platform_get_irq(pdev, 1); + + controller = kzalloc(sizeof *controller, GFP_KERNEL); + if (!controller) +@@ -1330,6 +1346,15 @@ dma_controller_create(struct musb *musb, void __iomem *mregs) + return NULL; + } + ++ 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); ++ return NULL; ++ } ++ controller->irq = irq; ++ } ++ + return &controller->controller; + } + +@@ -1342,6 +1367,9 @@ void dma_controller_destroy(struct dma_controller *c) + + cppi = container_of(c, struct cppi, controller); + ++ if (cppi->irq) ++ free_irq(cppi->irq, cppi->musb); ++ + /* assert: caller stopped the controller first */ + dma_pool_destroy(cppi->pool); + +diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h +index 729b407..8a39de3 100644 +--- a/drivers/usb/musb/cppi_dma.h ++++ b/drivers/usb/musb/cppi_dma.h +@@ -119,6 +119,8 @@ struct cppi { + void __iomem *mregs; /* Mentor regs */ + void __iomem *tibase; /* TI/CPPI regs */ + ++ int irq; ++ + struct cppi_channel tx[4]; + struct cppi_channel rx[4]; + +@@ -127,7 +129,7 @@ struct cppi { + struct list_head tx_complete; + }; + +-/* irq handling hook */ +-extern void cppi_completion(struct musb *, u32 rx, u32 tx); ++/* CPPI IRQ handler */ ++extern irqreturn_t cppi_interrupt(int, void *); + + #endif /* end of ifndef _CPPI_DMA_H_ */ +diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c +index 399c435..9fd74bf 100644 +--- a/drivers/usb/musb/davinci.c ++++ b/drivers/usb/musb/davinci.c +@@ -250,6 +250,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) + irqreturn_t retval = IRQ_NONE; + struct musb *musb = __hci; + void __iomem *tibase = musb->ctrl_base; ++ struct cppi *cppi; + u32 tmp; + + spin_lock_irqsave(&musb->lock, flags); +@@ -266,16 +267,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) + /* CPPI interrupts share the same IRQ line, but have their own + * mask, state, "vector", and EOI registers. + */ +- if (is_cppi_enabled()) { +- u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); +- u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); +- +- if (cppi_tx || cppi_rx) { +- DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx); +- cppi_completion(musb, cppi_rx, cppi_tx); +- retval = IRQ_HANDLED; +- } +- } ++ cppi = container_of(musb->dma_controller, struct cppi, controller); ++ if (is_cppi_enabled() && musb->dma_controller && !cppi->irq) ++ retval = cppi_interrupt(irq, __hci); + + /* ack and handle non-CPPI interrupts */ + tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); +-- +1.6.0.4 + |