aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/musb/cppi_dma.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 13:06:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 13:06:10 -0700
commite1f5b94fd0c93c3e27ede88b7ab652d086dc960f (patch)
treee8de7a132eb88521dd1c19e128eba2d5349bdf4f /drivers/usb/musb/cppi_dma.c
parent6fd03301d76bc439382710e449f58efbb233df1b (diff)
parent1b6ed69f974f6f32c8be0d9a7fc952822eb83b6f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (143 commits) USB: xhci depends on PCI. USB: xhci: Add Makefile, MAINTAINERS, and Kconfig entries. USB: xhci: Respect critical sections. USB: xHCI: Fix interrupt moderation. USB: xhci: Remove packed attribute from structures. usb; xhci: Fix TRB offset calculations. USB: xhci: replace if-elseif-else with switch-case USB: xhci: Make xhci-mem.c include linux/dmapool.h USB: xhci: drop spinlock in xhci_urb_enqueue() error path. USB: Change names of SuperSpeed ep companion descriptor structs. USB: xhci: Avoid compiler reordering in Link TRB giveback. USB: xhci: Clean up xhci_irq() function. USB: xhci: Avoid global namespace pollution. USB: xhci: Fix Link TRB handoff bit twiddling. USB: xhci: Fix register write order. USB: xhci: fix some compiler warnings in xhci.h USB: xhci: fix lots of compiler warnings. USB: xhci: use xhci_handle_event instead of handle_event USB: xhci: URB cancellation support. USB: xhci: Scatter gather list support for bulk transfers. ...
Diffstat (limited to 'drivers/usb/musb/cppi_dma.c')
-rw-r--r--drivers/usb/musb/cppi_dma.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 1976e9b4180..c3577bbbae6 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;
@@ -1273,6 +1284,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. */
@@ -1280,6 +1293,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)
@@ -1310,6 +1326,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;
}
@@ -1322,6 +1347,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);