diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-03-27 15:59:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:40 -0400 |
commit | 91e9c4fec7ee777213859aa1a18bf0b885527637 (patch) | |
tree | db35bc238f2fb6e81d453b23b6acd3f0ec239957 | |
parent | c9cd06b3d6ea825c62e277def929cc4315802b48 (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>
-rw-r--r-- | drivers/usb/musb/cppi_dma.c | 34 | ||||
-rw-r--r-- | drivers/usb/musb/cppi_dma.h | 6 | ||||
-rw-r--r-- | 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 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 | ||
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 | 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 | |||
1280 | dma_controller_create(struct musb *musb, void __iomem *mregs) | 1293 | dma_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 */ |
131 | extern void cppi_completion(struct musb *, u32 rx, u32 tx); | 133 | extern 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); |