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 /drivers/usb/musb/cppi_dma.c | |
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>
Diffstat (limited to 'drivers/usb/musb/cppi_dma.c')
-rw-r--r-- | drivers/usb/musb/cppi_dma.c | 34 |
1 files changed, 31 insertions, 3 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 | ||