aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-03-27 15:59:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:40 -0400
commit91e9c4fec7ee777213859aa1a18bf0b885527637 (patch)
treedb35bc238f2fb6e81d453b23b6acd3f0ec239957 /drivers/usb/musb
parentc9cd06b3d6ea825c62e277def929cc4315802b48 (diff)
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>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/cppi_dma.c34
-rw-r--r--drivers/usb/musb/cppi_dma.h6
-rw-r--r--drivers/usb/musb/davinci.c14
3 files changed, 39 insertions, 15 deletions
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 1976e9b41800..c3577bbbae6c 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -6,6 +6,7 @@
6 * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci. 6 * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci.
7 */ 7 */
8 8
9#include <linux/platform_device.h>
9#include <linux/usb.h> 10#include <linux/usb.h>
10 11
11#include "musb_core.h" 12#include "musb_core.h"
@@ -1145,17 +1146,27 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
1145 return completed; 1146 return completed;
1146} 1147}
1147 1148
1148void cppi_completion(struct musb *musb, u32 rx, u32 tx) 1149irqreturn_t cppi_interrupt(int irq, void *dev_id)
1149{ 1150{
1150 void __iomem *tibase; 1151 struct musb *musb = dev_id;
1151 int i, index;
1152 struct cppi *cppi; 1152 struct cppi *cppi;
1153 void __iomem *tibase;
1153 struct musb_hw_ep *hw_ep = NULL; 1154 struct musb_hw_ep *hw_ep = NULL;
1155 u32 rx, tx;
1156 int i, index;
1154 1157
1155 cppi = container_of(musb->dma_controller, struct cppi, controller); 1158 cppi = container_of(musb->dma_controller, struct cppi, controller);
1156 1159
1157 tibase = musb->ctrl_base; 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 /* process TX channels */ 1170 /* process TX channels */
1160 for (index = 0; tx; tx = tx >> 1, index++) { 1171 for (index = 0; tx; tx = tx >> 1, index++) {
1161 struct cppi_channel *tx_ch; 1172 struct cppi_channel *tx_ch;
@@ -1273,6 +1284,8 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx)
1273 1284
1274 /* write to CPPI EOI register to re-enable interrupts */ 1285 /* write to CPPI EOI register to re-enable interrupts */
1275 musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); 1286 musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0);
1287
1288 return IRQ_HANDLED;
1276} 1289}
1277 1290
1278/* Instantiate a software object representing a DMA controller. */ 1291/* Instantiate a software object representing a DMA controller. */
@@ -1280,6 +1293,9 @@ struct dma_controller *__init
1280dma_controller_create(struct musb *musb, void __iomem *mregs) 1293dma_controller_create(struct musb *musb, void __iomem *mregs)
1281{ 1294{
1282 struct cppi *controller; 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 controller = kzalloc(sizeof *controller, GFP_KERNEL); 1300 controller = kzalloc(sizeof *controller, GFP_KERNEL);
1285 if (!controller) 1301 if (!controller)
@@ -1310,6 +1326,15 @@ dma_controller_create(struct musb *musb, void __iomem *mregs)
1310 return NULL; 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 return &controller->controller; 1338 return &controller->controller;
1314} 1339}
1315 1340
@@ -1322,6 +1347,9 @@ void dma_controller_destroy(struct dma_controller *c)
1322 1347
1323 cppi = container_of(c, struct cppi, controller); 1348 cppi = container_of(c, struct cppi, controller);
1324 1349
1350 if (cppi->irq)
1351 free_irq(cppi->irq, cppi->musb);
1352
1325 /* assert: caller stopped the controller first */ 1353 /* assert: caller stopped the controller first */
1326 dma_pool_destroy(cppi->pool); 1354 dma_pool_destroy(cppi->pool);
1327 1355
diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h
index 729b4071787b..8a39de3e6e47 100644
--- a/drivers/usb/musb/cppi_dma.h
+++ b/drivers/usb/musb/cppi_dma.h
@@ -119,6 +119,8 @@ struct cppi {
119 void __iomem *mregs; /* Mentor regs */ 119 void __iomem *mregs; /* Mentor regs */
120 void __iomem *tibase; /* TI/CPPI regs */ 120 void __iomem *tibase; /* TI/CPPI regs */
121 121
122 int irq;
123
122 struct cppi_channel tx[4]; 124 struct cppi_channel tx[4];
123 struct cppi_channel rx[4]; 125 struct cppi_channel rx[4];
124 126
@@ -127,7 +129,7 @@ struct cppi {
127 struct list_head tx_complete; 129 struct list_head tx_complete;
128}; 130};
129 131
130/* irq handling hook */ 132/* CPPI IRQ handler */
131extern void cppi_completion(struct musb *, u32 rx, u32 tx); 133extern irqreturn_t cppi_interrupt(int, void *);
132 134
133#endif /* end of ifndef _CPPI_DMA_H_ */ 135#endif /* end of ifndef _CPPI_DMA_H_ */
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 898b52fcff5d..6e14e06ff820 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -265,6 +265,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
265 irqreturn_t retval = IRQ_NONE; 265 irqreturn_t retval = IRQ_NONE;
266 struct musb *musb = __hci; 266 struct musb *musb = __hci;
267 void __iomem *tibase = musb->ctrl_base; 267 void __iomem *tibase = musb->ctrl_base;
268 struct cppi *cppi;
268 u32 tmp; 269 u32 tmp;
269 270
270 spin_lock_irqsave(&musb->lock, flags); 271 spin_lock_irqsave(&musb->lock, flags);
@@ -281,16 +282,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
281 /* CPPI interrupts share the same IRQ line, but have their own 282 /* CPPI interrupts share the same IRQ line, but have their own
282 * mask, state, "vector", and EOI registers. 283 * mask, state, "vector", and EOI registers.
283 */ 284 */
284 if (is_cppi_enabled()) { 285 cppi = container_of(musb->dma_controller, struct cppi, controller);
285 u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); 286 if (is_cppi_enabled() && musb->dma_controller && !cppi->irq)
286 u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); 287 retval = cppi_interrupt(irq, __hci);
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 }
294 288
295 /* ack and handle non-CPPI interrupts */ 289 /* ack and handle non-CPPI interrupts */
296 tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); 290 tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG);