Commit 91e9c4fec7ee777213859aa1a18bf0b885527637

Authored by Sergei Shtylyov
Committed by Greg Kroah-Hartman
1 parent c9cd06b3d6

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@users.sourceforge.net: only cppi_dma.c needs platform
device header, not cppi_dma.h ]

Signed-off-by: Dmitry Krivoschekov <dkrivoschekov@ru.mvista.com>
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 3 changed files with 39 additions and 15 deletions Side-by-side Diff

drivers/usb/musb/cppi_dma.c
... ... @@ -6,6 +6,7 @@
6 6 * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci.
7 7 */
8 8  
  9 +#include <linux/platform_device.h>
9 10 #include <linux/usb.h>
10 11  
11 12 #include "musb_core.h"
12 13  
13 14  
14 15  
15 16  
... ... @@ -1145,17 +1146,27 @@
1145 1146 return completed;
1146 1147 }
1147 1148  
1148   -void cppi_completion(struct musb *musb, u32 rx, u32 tx)
  1149 +irqreturn_t cppi_interrupt(int irq, void *dev_id)
1149 1150 {
1150   - void __iomem *tibase;
1151   - int i, index;
  1151 + struct musb *musb = dev_id;
1152 1152 struct cppi *cppi;
  1153 + void __iomem *tibase;
1153 1154 struct musb_hw_ep *hw_ep = NULL;
  1155 + u32 rx, tx;
  1156 + int i, index;
1154 1157  
1155 1158 cppi = container_of(musb->dma_controller, struct cppi, controller);
1156 1159  
1157 1160 tibase = musb->ctrl_base;
1158 1161  
  1162 + tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
  1163 + rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
  1164 +
  1165 + if (!tx && !rx)
  1166 + return IRQ_NONE;
  1167 +
  1168 + DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx);
  1169 +
1159 1170 /* process TX channels */
1160 1171 for (index = 0; tx; tx = tx >> 1, index++) {
1161 1172 struct cppi_channel *tx_ch;
... ... @@ -1273,6 +1284,8 @@
1273 1284  
1274 1285 /* write to CPPI EOI register to re-enable interrupts */
1275 1286 musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0);
  1287 +
  1288 + return IRQ_HANDLED;
1276 1289 }
1277 1290  
1278 1291 /* Instantiate a software object representing a DMA controller. */
... ... @@ -1280,6 +1293,9 @@
1280 1293 dma_controller_create(struct musb *musb, void __iomem *mregs)
1281 1294 {
1282 1295 struct cppi *controller;
  1296 + struct device *dev = musb->controller;
  1297 + struct platform_device *pdev = to_platform_device(dev);
  1298 + int irq = platform_get_irq(pdev, 1);
1283 1299  
1284 1300 controller = kzalloc(sizeof *controller, GFP_KERNEL);
1285 1301 if (!controller)
... ... @@ -1310,6 +1326,15 @@
1310 1326 return NULL;
1311 1327 }
1312 1328  
  1329 + if (irq > 0) {
  1330 + if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) {
  1331 + dev_err(dev, "request_irq %d failed!\n", irq);
  1332 + dma_controller_destroy(&controller->controller);
  1333 + return NULL;
  1334 + }
  1335 + controller->irq = irq;
  1336 + }
  1337 +
1313 1338 return &controller->controller;
1314 1339 }
1315 1340  
... ... @@ -1321,6 +1346,9 @@
1321 1346 struct cppi *cppi;
1322 1347  
1323 1348 cppi = container_of(c, struct cppi, controller);
  1349 +
  1350 + if (cppi->irq)
  1351 + free_irq(cppi->irq, cppi->musb);
1324 1352  
1325 1353 /* assert: caller stopped the controller first */
1326 1354 dma_pool_destroy(cppi->pool);
drivers/usb/musb/cppi_dma.h
... ... @@ -119,6 +119,8 @@
119 119 void __iomem *mregs; /* Mentor regs */
120 120 void __iomem *tibase; /* TI/CPPI regs */
121 121  
  122 + int irq;
  123 +
122 124 struct cppi_channel tx[4];
123 125 struct cppi_channel rx[4];
124 126  
... ... @@ -127,8 +129,8 @@
127 129 struct list_head tx_complete;
128 130 };
129 131  
130   -/* irq handling hook */
131   -extern void cppi_completion(struct musb *, u32 rx, u32 tx);
  132 +/* CPPI IRQ handler */
  133 +extern irqreturn_t cppi_interrupt(int, void *);
132 134  
133 135 #endif /* end of ifndef _CPPI_DMA_H_ */
drivers/usb/musb/davinci.c
... ... @@ -265,6 +265,7 @@
265 265 irqreturn_t retval = IRQ_NONE;
266 266 struct musb *musb = __hci;
267 267 void __iomem *tibase = musb->ctrl_base;
  268 + struct cppi *cppi;
268 269 u32 tmp;
269 270  
270 271 spin_lock_irqsave(&musb->lock, flags);
... ... @@ -281,16 +282,9 @@
281 282 /* CPPI interrupts share the same IRQ line, but have their own
282 283 * mask, state, "vector", and EOI registers.
283 284 */
284   - if (is_cppi_enabled()) {
285   - u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
286   - u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
287   -
288   - if (cppi_tx || cppi_rx) {
289   - DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx);
290   - cppi_completion(musb, cppi_rx, cppi_tx);
291   - retval = IRQ_HANDLED;
292   - }
293   - }
  285 + cppi = container_of(musb->dma_controller, struct cppi, controller);
  286 + if (is_cppi_enabled() && musb->dma_controller && !cppi->irq)
  287 + retval = cppi_interrupt(irq, __hci);
294 288  
295 289 /* ack and handle non-CPPI interrupts */
296 290 tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG);