diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-01-10 23:10:08 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-01-10 23:10:08 -0500 |
commit | eed0ba0b4ab2d1668588219a8efa81bf8636a12d (patch) | |
tree | f5aa3c732e7830a1b24e6071f8bed0f799881187 /drivers/dma | |
parent | 98b14d6b290d96b24ae993ceaccc59b2aa4b130c (diff) | |
parent | c9de9333f5a860cab82052bce6ac28bcac9b2c26 (diff) |
Merge remote branch 'gcl/next' into next
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/Kconfig | 2 | ||||
-rw-r--r-- | drivers/dma/Makefile | 4 | ||||
-rw-r--r-- | drivers/dma/at_hdmac.c | 2 | ||||
-rw-r--r-- | drivers/dma/fsldma.c | 6 | ||||
-rw-r--r-- | drivers/dma/fsldma.h | 9 | ||||
-rw-r--r-- | drivers/dma/imx-dma.c | 2 | ||||
-rw-r--r-- | drivers/dma/imx-sdma.c | 4 | ||||
-rw-r--r-- | drivers/dma/intel_mid_dma.c | 8 | ||||
-rw-r--r-- | drivers/dma/ioat/Makefile | 2 | ||||
-rw-r--r-- | drivers/dma/mpc512x_dma.c | 187 | ||||
-rw-r--r-- | drivers/dma/pch_dma.c | 15 | ||||
-rw-r--r-- | drivers/dma/ppc4xx/adma.c | 5 | ||||
-rw-r--r-- | drivers/dma/shdma.c | 1 |
13 files changed, 156 insertions, 91 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 6ee23592700a..ef138731c0ea 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -109,7 +109,7 @@ config FSL_DMA | |||
109 | 109 | ||
110 | config MPC512X_DMA | 110 | config MPC512X_DMA |
111 | tristate "Freescale MPC512x built-in DMA engine support" | 111 | tristate "Freescale MPC512x built-in DMA engine support" |
112 | depends on PPC_MPC512x | 112 | depends on PPC_MPC512x || PPC_MPC831x |
113 | select DMA_ENGINE | 113 | select DMA_ENGINE |
114 | ---help--- | 114 | ---help--- |
115 | Enable support for the Freescale MPC512x built-in DMA engine. | 115 | Enable support for the Freescale MPC512x built-in DMA engine. |
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a8a84f4587f2..64b21f5cd740 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
@@ -1,8 +1,8 @@ | |||
1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) | 1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) |
2 | EXTRA_CFLAGS += -DDEBUG | 2 | ccflags-y += -DDEBUG |
3 | endif | 3 | endif |
4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) | 4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) |
5 | EXTRA_CFLAGS += -DVERBOSE_DEBUG | 5 | ccflags-y += -DVERBOSE_DEBUG |
6 | endif | 6 | endif |
7 | 7 | ||
8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o | 8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index a0f3e6a06e06..ea0ee81cff53 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
722 | desc->lli.daddr = mem; | 722 | desc->lli.daddr = mem; |
723 | desc->lli.ctrla = ctrla | 723 | desc->lli.ctrla = ctrla |
724 | | ATC_DST_WIDTH(mem_width) | 724 | | ATC_DST_WIDTH(mem_width) |
725 | | len >> mem_width; | 725 | | len >> reg_width; |
726 | desc->lli.ctrlb = ctrlb; | 726 | desc->lli.ctrlb = ctrlb; |
727 | 727 | ||
728 | if (!first) { | 728 | if (!first) { |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 286c3ac6bdcc..e5e172d21692 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan) | |||
50 | * EIE - Error interrupt enable | 50 | * EIE - Error interrupt enable |
51 | * EOSIE - End of segments interrupt enable (basic mode) | 51 | * EOSIE - End of segments interrupt enable (basic mode) |
52 | * EOLNIE - End of links interrupt enable | 52 | * EOLNIE - End of links interrupt enable |
53 | * BWC - Bandwidth sharing among channels | ||
53 | */ | 54 | */ |
54 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE | 55 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC |
55 | | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); | 56 | | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE |
57 | | FSL_DMA_MR_EOSIE, 32); | ||
56 | break; | 58 | break; |
57 | case FSL_DMA_IP_83XX: | 59 | case FSL_DMA_IP_83XX: |
58 | /* Set the channel to below modes: | 60 | /* Set the channel to below modes: |
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index cb4d6ff51597..ba9f403c0fbe 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. | 2 | * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * Author: | 4 | * Author: |
5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 | 5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 |
@@ -36,6 +36,13 @@ | |||
36 | #define FSL_DMA_MR_DAHE 0x00002000 | 36 | #define FSL_DMA_MR_DAHE 0x00002000 |
37 | #define FSL_DMA_MR_SAHE 0x00001000 | 37 | #define FSL_DMA_MR_SAHE 0x00001000 |
38 | 38 | ||
39 | /* | ||
40 | * Bandwidth/pause control determines how many bytes a given | ||
41 | * channel is allowed to transfer before the DMA engine pauses | ||
42 | * the current channel and switches to the next channel | ||
43 | */ | ||
44 | #define FSL_DMA_MR_BWC 0x08000000 | ||
45 | |||
39 | /* Special MR definition for MPC8349 */ | 46 | /* Special MR definition for MPC8349 */ |
40 | #define FSL_DMA_MR_EOTIE 0x00000080 | 47 | #define FSL_DMA_MR_EOTIE 0x00000080 |
41 | #define FSL_DMA_MR_PRC_RM 0x00000800 | 48 | #define FSL_DMA_MR_PRC_RM 0x00000800 |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f629e4961af5..e53d438142bb 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
379 | return 0; | 379 | return 0; |
380 | 380 | ||
381 | err_init: | 381 | err_init: |
382 | while (i-- >= 0) { | 382 | while (--i >= 0) { |
383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; | 383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; |
384 | imx_dma_free(imxdmac->imxdma_channel); | 384 | imx_dma_free(imxdmac->imxdma_channel); |
385 | } | 385 | } |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 0834323a0599..d0602dd5d1b2 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
951 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; | 951 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; |
952 | int param; | 952 | int param; |
953 | 953 | ||
954 | bd->buffer_addr = sgl->dma_address; | 954 | bd->buffer_addr = sg->dma_address; |
955 | 955 | ||
956 | count = sg->length; | 956 | count = sg->length; |
957 | 957 | ||
@@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void) | |||
1385 | { | 1385 | { |
1386 | return platform_driver_probe(&sdma_driver, sdma_probe); | 1386 | return platform_driver_probe(&sdma_driver, sdma_probe); |
1387 | } | 1387 | } |
1388 | subsys_initcall(sdma_module_init); | 1388 | module_init(sdma_module_init); |
1389 | 1389 | ||
1390 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); | 1390 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); |
1391 | MODULE_DESCRIPTION("i.MX SDMA driver"); | 1391 | MODULE_DESCRIPTION("i.MX SDMA driver"); |
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f3..3109bd94bc4f 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
@@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev) | |||
1075 | if (NULL == dma->dma_pool) { | 1075 | if (NULL == dma->dma_pool) { |
1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); | 1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); |
1077 | err = -ENOMEM; | 1077 | err = -ENOMEM; |
1078 | kfree(dma); | ||
1079 | goto err_dma_pool; | 1078 | goto err_dma_pool; |
1080 | } | 1079 | } |
1081 | 1080 | ||
@@ -1186,7 +1185,6 @@ err_engine: | |||
1186 | free_irq(pdev->irq, dma); | 1185 | free_irq(pdev->irq, dma); |
1187 | err_irq: | 1186 | err_irq: |
1188 | pci_pool_destroy(dma->dma_pool); | 1187 | pci_pool_destroy(dma->dma_pool); |
1189 | kfree(dma); | ||
1190 | err_dma_pool: | 1188 | err_dma_pool: |
1191 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); | 1189 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); |
1192 | return err; | 1190 | return err; |
@@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = { | |||
1413 | .runtime_idle = dma_runtime_idle, | 1411 | .runtime_idle = dma_runtime_idle, |
1414 | }; | 1412 | }; |
1415 | 1413 | ||
1416 | static struct pci_driver intel_mid_dma_pci = { | 1414 | static struct pci_driver intel_mid_dma_pci_driver = { |
1417 | .name = "Intel MID DMA", | 1415 | .name = "Intel MID DMA", |
1418 | .id_table = intel_mid_dma_ids, | 1416 | .id_table = intel_mid_dma_ids, |
1419 | .probe = intel_mid_dma_probe, | 1417 | .probe = intel_mid_dma_probe, |
@@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void) | |||
1431 | { | 1429 | { |
1432 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", | 1430 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", |
1433 | INTEL_MID_DMA_DRIVER_VERSION); | 1431 | INTEL_MID_DMA_DRIVER_VERSION); |
1434 | return pci_register_driver(&intel_mid_dma_pci); | 1432 | return pci_register_driver(&intel_mid_dma_pci_driver); |
1435 | } | 1433 | } |
1436 | fs_initcall(intel_mid_dma_init); | 1434 | fs_initcall(intel_mid_dma_init); |
1437 | 1435 | ||
1438 | static void __exit intel_mid_dma_exit(void) | 1436 | static void __exit intel_mid_dma_exit(void) |
1439 | { | 1437 | { |
1440 | pci_unregister_driver(&intel_mid_dma_pci); | 1438 | pci_unregister_driver(&intel_mid_dma_pci_driver); |
1441 | } | 1439 | } |
1442 | module_exit(intel_mid_dma_exit); | 1440 | module_exit(intel_mid_dma_exit); |
1443 | 1441 | ||
diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile index 8997d3fb9051..0ff7270af25b 100644 --- a/drivers/dma/ioat/Makefile +++ b/drivers/dma/ioat/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o | 1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o |
2 | ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o | 2 | ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o |
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 4e9cbf300594..59c270192ccc 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008. | 2 | * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008. |
3 | * Copyright (C) Semihalf 2009 | 3 | * Copyright (C) Semihalf 2009 |
4 | * Copyright (C) Ilya Yanok, Emcraft Systems 2010 | ||
4 | * | 5 | * |
5 | * Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description | 6 | * Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description |
6 | * (defines, structures and comments) was taken from MPC5121 DMA driver | 7 | * (defines, structures and comments) was taken from MPC5121 DMA driver |
@@ -70,6 +71,8 @@ | |||
70 | #define MPC_DMA_DMAES_SBE (1 << 1) | 71 | #define MPC_DMA_DMAES_SBE (1 << 1) |
71 | #define MPC_DMA_DMAES_DBE (1 << 0) | 72 | #define MPC_DMA_DMAES_DBE (1 << 0) |
72 | 73 | ||
74 | #define MPC_DMA_DMAGPOR_SNOOP_ENABLE (1 << 6) | ||
75 | |||
73 | #define MPC_DMA_TSIZE_1 0x00 | 76 | #define MPC_DMA_TSIZE_1 0x00 |
74 | #define MPC_DMA_TSIZE_2 0x01 | 77 | #define MPC_DMA_TSIZE_2 0x01 |
75 | #define MPC_DMA_TSIZE_4 0x02 | 78 | #define MPC_DMA_TSIZE_4 0x02 |
@@ -104,7 +107,10 @@ struct __attribute__ ((__packed__)) mpc_dma_regs { | |||
104 | /* 0x30 */ | 107 | /* 0x30 */ |
105 | u32 dmahrsh; /* DMA hw request status high(ch63~32) */ | 108 | u32 dmahrsh; /* DMA hw request status high(ch63~32) */ |
106 | u32 dmahrsl; /* DMA hardware request status low(ch31~0) */ | 109 | u32 dmahrsl; /* DMA hardware request status low(ch31~0) */ |
107 | u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */ | 110 | union { |
111 | u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */ | ||
112 | u32 dmagpor; /* (General purpose register on MPC8308) */ | ||
113 | }; | ||
108 | u32 dmailsa; /* DMA interrupt low select AXE(ch31~0) */ | 114 | u32 dmailsa; /* DMA interrupt low select AXE(ch31~0) */ |
109 | /* 0x40 ~ 0xff */ | 115 | /* 0x40 ~ 0xff */ |
110 | u32 reserve0[48]; /* Reserved */ | 116 | u32 reserve0[48]; /* Reserved */ |
@@ -195,7 +201,9 @@ struct mpc_dma { | |||
195 | struct mpc_dma_regs __iomem *regs; | 201 | struct mpc_dma_regs __iomem *regs; |
196 | struct mpc_dma_tcd __iomem *tcd; | 202 | struct mpc_dma_tcd __iomem *tcd; |
197 | int irq; | 203 | int irq; |
204 | int irq2; | ||
198 | uint error_status; | 205 | uint error_status; |
206 | int is_mpc8308; | ||
199 | 207 | ||
200 | /* Lock for error_status field in this structure */ | 208 | /* Lock for error_status field in this structure */ |
201 | spinlock_t error_status_lock; | 209 | spinlock_t error_status_lock; |
@@ -252,11 +260,13 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan) | |||
252 | prev = mdesc; | 260 | prev = mdesc; |
253 | } | 261 | } |
254 | 262 | ||
255 | prev->tcd->start = 0; | ||
256 | prev->tcd->int_maj = 1; | 263 | prev->tcd->int_maj = 1; |
257 | 264 | ||
258 | /* Send first descriptor in chain into hardware */ | 265 | /* Send first descriptor in chain into hardware */ |
259 | memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd)); | 266 | memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd)); |
267 | |||
268 | if (first != prev) | ||
269 | mdma->tcd[cid].e_sg = 1; | ||
260 | out_8(&mdma->regs->dmassrt, cid); | 270 | out_8(&mdma->regs->dmassrt, cid); |
261 | } | 271 | } |
262 | 272 | ||
@@ -274,6 +284,9 @@ static void mpc_dma_irq_process(struct mpc_dma *mdma, u32 is, u32 es, int off) | |||
274 | 284 | ||
275 | spin_lock(&mchan->lock); | 285 | spin_lock(&mchan->lock); |
276 | 286 | ||
287 | out_8(&mdma->regs->dmacint, ch + off); | ||
288 | out_8(&mdma->regs->dmacerr, ch + off); | ||
289 | |||
277 | /* Check error status */ | 290 | /* Check error status */ |
278 | if (es & (1 << ch)) | 291 | if (es & (1 << ch)) |
279 | list_for_each_entry(mdesc, &mchan->active, node) | 292 | list_for_each_entry(mdesc, &mchan->active, node) |
@@ -302,36 +315,68 @@ static irqreturn_t mpc_dma_irq(int irq, void *data) | |||
302 | spin_unlock(&mdma->error_status_lock); | 315 | spin_unlock(&mdma->error_status_lock); |
303 | 316 | ||
304 | /* Handle interrupt on each channel */ | 317 | /* Handle interrupt on each channel */ |
305 | mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth), | 318 | if (mdma->dma.chancnt > 32) { |
319 | mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth), | ||
306 | in_be32(&mdma->regs->dmaerrh), 32); | 320 | in_be32(&mdma->regs->dmaerrh), 32); |
321 | } | ||
307 | mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmaintl), | 322 | mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmaintl), |
308 | in_be32(&mdma->regs->dmaerrl), 0); | 323 | in_be32(&mdma->regs->dmaerrl), 0); |
309 | 324 | ||
310 | /* Ack interrupt on all channels */ | ||
311 | out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); | ||
312 | out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); | ||
313 | out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); | ||
314 | out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); | ||
315 | |||
316 | /* Schedule tasklet */ | 325 | /* Schedule tasklet */ |
317 | tasklet_schedule(&mdma->tasklet); | 326 | tasklet_schedule(&mdma->tasklet); |
318 | 327 | ||
319 | return IRQ_HANDLED; | 328 | return IRQ_HANDLED; |
320 | } | 329 | } |
321 | 330 | ||
322 | /* DMA Tasklet */ | 331 | /* proccess completed descriptors */ |
323 | static void mpc_dma_tasklet(unsigned long data) | 332 | static void mpc_dma_process_completed(struct mpc_dma *mdma) |
324 | { | 333 | { |
325 | struct mpc_dma *mdma = (void *)data; | ||
326 | dma_cookie_t last_cookie = 0; | 334 | dma_cookie_t last_cookie = 0; |
327 | struct mpc_dma_chan *mchan; | 335 | struct mpc_dma_chan *mchan; |
328 | struct mpc_dma_desc *mdesc; | 336 | struct mpc_dma_desc *mdesc; |
329 | struct dma_async_tx_descriptor *desc; | 337 | struct dma_async_tx_descriptor *desc; |
330 | unsigned long flags; | 338 | unsigned long flags; |
331 | LIST_HEAD(list); | 339 | LIST_HEAD(list); |
332 | uint es; | ||
333 | int i; | 340 | int i; |
334 | 341 | ||
342 | for (i = 0; i < mdma->dma.chancnt; i++) { | ||
343 | mchan = &mdma->channels[i]; | ||
344 | |||
345 | /* Get all completed descriptors */ | ||
346 | spin_lock_irqsave(&mchan->lock, flags); | ||
347 | if (!list_empty(&mchan->completed)) | ||
348 | list_splice_tail_init(&mchan->completed, &list); | ||
349 | spin_unlock_irqrestore(&mchan->lock, flags); | ||
350 | |||
351 | if (list_empty(&list)) | ||
352 | continue; | ||
353 | |||
354 | /* Execute callbacks and run dependencies */ | ||
355 | list_for_each_entry(mdesc, &list, node) { | ||
356 | desc = &mdesc->desc; | ||
357 | |||
358 | if (desc->callback) | ||
359 | desc->callback(desc->callback_param); | ||
360 | |||
361 | last_cookie = desc->cookie; | ||
362 | dma_run_dependencies(desc); | ||
363 | } | ||
364 | |||
365 | /* Free descriptors */ | ||
366 | spin_lock_irqsave(&mchan->lock, flags); | ||
367 | list_splice_tail_init(&list, &mchan->free); | ||
368 | mchan->completed_cookie = last_cookie; | ||
369 | spin_unlock_irqrestore(&mchan->lock, flags); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* DMA Tasklet */ | ||
374 | static void mpc_dma_tasklet(unsigned long data) | ||
375 | { | ||
376 | struct mpc_dma *mdma = (void *)data; | ||
377 | unsigned long flags; | ||
378 | uint es; | ||
379 | |||
335 | spin_lock_irqsave(&mdma->error_status_lock, flags); | 380 | spin_lock_irqsave(&mdma->error_status_lock, flags); |
336 | es = mdma->error_status; | 381 | es = mdma->error_status; |
337 | mdma->error_status = 0; | 382 | mdma->error_status = 0; |
@@ -370,35 +415,7 @@ static void mpc_dma_tasklet(unsigned long data) | |||
370 | dev_err(mdma->dma.dev, "- Destination Bus Error\n"); | 415 | dev_err(mdma->dma.dev, "- Destination Bus Error\n"); |
371 | } | 416 | } |
372 | 417 | ||
373 | for (i = 0; i < mdma->dma.chancnt; i++) { | 418 | mpc_dma_process_completed(mdma); |
374 | mchan = &mdma->channels[i]; | ||
375 | |||
376 | /* Get all completed descriptors */ | ||
377 | spin_lock_irqsave(&mchan->lock, flags); | ||
378 | if (!list_empty(&mchan->completed)) | ||
379 | list_splice_tail_init(&mchan->completed, &list); | ||
380 | spin_unlock_irqrestore(&mchan->lock, flags); | ||
381 | |||
382 | if (list_empty(&list)) | ||
383 | continue; | ||
384 | |||
385 | /* Execute callbacks and run dependencies */ | ||
386 | list_for_each_entry(mdesc, &list, node) { | ||
387 | desc = &mdesc->desc; | ||
388 | |||
389 | if (desc->callback) | ||
390 | desc->callback(desc->callback_param); | ||
391 | |||
392 | last_cookie = desc->cookie; | ||
393 | dma_run_dependencies(desc); | ||
394 | } | ||
395 | |||
396 | /* Free descriptors */ | ||
397 | spin_lock_irqsave(&mchan->lock, flags); | ||
398 | list_splice_tail_init(&list, &mchan->free); | ||
399 | mchan->completed_cookie = last_cookie; | ||
400 | spin_unlock_irqrestore(&mchan->lock, flags); | ||
401 | } | ||
402 | } | 419 | } |
403 | 420 | ||
404 | /* Submit descriptor to hardware */ | 421 | /* Submit descriptor to hardware */ |
@@ -563,6 +580,7 @@ static struct dma_async_tx_descriptor * | |||
563 | mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, | 580 | mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, |
564 | size_t len, unsigned long flags) | 581 | size_t len, unsigned long flags) |
565 | { | 582 | { |
583 | struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan); | ||
566 | struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); | 584 | struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); |
567 | struct mpc_dma_desc *mdesc = NULL; | 585 | struct mpc_dma_desc *mdesc = NULL; |
568 | struct mpc_dma_tcd *tcd; | 586 | struct mpc_dma_tcd *tcd; |
@@ -577,8 +595,11 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, | |||
577 | } | 595 | } |
578 | spin_unlock_irqrestore(&mchan->lock, iflags); | 596 | spin_unlock_irqrestore(&mchan->lock, iflags); |
579 | 597 | ||
580 | if (!mdesc) | 598 | if (!mdesc) { |
599 | /* try to free completed descriptors */ | ||
600 | mpc_dma_process_completed(mdma); | ||
581 | return NULL; | 601 | return NULL; |
602 | } | ||
582 | 603 | ||
583 | mdesc->error = 0; | 604 | mdesc->error = 0; |
584 | tcd = mdesc->tcd; | 605 | tcd = mdesc->tcd; |
@@ -591,7 +612,8 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, | |||
591 | tcd->dsize = MPC_DMA_TSIZE_32; | 612 | tcd->dsize = MPC_DMA_TSIZE_32; |
592 | tcd->soff = 32; | 613 | tcd->soff = 32; |
593 | tcd->doff = 32; | 614 | tcd->doff = 32; |
594 | } else if (IS_ALIGNED(src | dst | len, 16)) { | 615 | } else if (!mdma->is_mpc8308 && IS_ALIGNED(src | dst | len, 16)) { |
616 | /* MPC8308 doesn't support 16 byte transfers */ | ||
595 | tcd->ssize = MPC_DMA_TSIZE_16; | 617 | tcd->ssize = MPC_DMA_TSIZE_16; |
596 | tcd->dsize = MPC_DMA_TSIZE_16; | 618 | tcd->dsize = MPC_DMA_TSIZE_16; |
597 | tcd->soff = 16; | 619 | tcd->soff = 16; |
@@ -651,6 +673,15 @@ static int __devinit mpc_dma_probe(struct platform_device *op, | |||
651 | return -EINVAL; | 673 | return -EINVAL; |
652 | } | 674 | } |
653 | 675 | ||
676 | if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) { | ||
677 | mdma->is_mpc8308 = 1; | ||
678 | mdma->irq2 = irq_of_parse_and_map(dn, 1); | ||
679 | if (mdma->irq2 == NO_IRQ) { | ||
680 | dev_err(dev, "Error mapping IRQ!\n"); | ||
681 | return -EINVAL; | ||
682 | } | ||
683 | } | ||
684 | |||
654 | retval = of_address_to_resource(dn, 0, &res); | 685 | retval = of_address_to_resource(dn, 0, &res); |
655 | if (retval) { | 686 | if (retval) { |
656 | dev_err(dev, "Error parsing memory region!\n"); | 687 | dev_err(dev, "Error parsing memory region!\n"); |
@@ -681,11 +712,23 @@ static int __devinit mpc_dma_probe(struct platform_device *op, | |||
681 | return -EINVAL; | 712 | return -EINVAL; |
682 | } | 713 | } |
683 | 714 | ||
715 | if (mdma->is_mpc8308) { | ||
716 | retval = devm_request_irq(dev, mdma->irq2, &mpc_dma_irq, 0, | ||
717 | DRV_NAME, mdma); | ||
718 | if (retval) { | ||
719 | dev_err(dev, "Error requesting IRQ2!\n"); | ||
720 | return -EINVAL; | ||
721 | } | ||
722 | } | ||
723 | |||
684 | spin_lock_init(&mdma->error_status_lock); | 724 | spin_lock_init(&mdma->error_status_lock); |
685 | 725 | ||
686 | dma = &mdma->dma; | 726 | dma = &mdma->dma; |
687 | dma->dev = dev; | 727 | dma->dev = dev; |
688 | dma->chancnt = MPC_DMA_CHANNELS; | 728 | if (!mdma->is_mpc8308) |
729 | dma->chancnt = MPC_DMA_CHANNELS; | ||
730 | else | ||
731 | dma->chancnt = 16; /* MPC8308 DMA has only 16 channels */ | ||
689 | dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; | 732 | dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; |
690 | dma->device_free_chan_resources = mpc_dma_free_chan_resources; | 733 | dma->device_free_chan_resources = mpc_dma_free_chan_resources; |
691 | dma->device_issue_pending = mpc_dma_issue_pending; | 734 | dma->device_issue_pending = mpc_dma_issue_pending; |
@@ -721,26 +764,40 @@ static int __devinit mpc_dma_probe(struct platform_device *op, | |||
721 | * - Round-robin group arbitration, | 764 | * - Round-robin group arbitration, |
722 | * - Round-robin channel arbitration. | 765 | * - Round-robin channel arbitration. |
723 | */ | 766 | */ |
724 | out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG | | 767 | if (!mdma->is_mpc8308) { |
725 | MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA); | 768 | out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG | |
726 | 769 | MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA); | |
727 | /* Disable hardware DMA requests */ | 770 | |
728 | out_be32(&mdma->regs->dmaerqh, 0); | 771 | /* Disable hardware DMA requests */ |
729 | out_be32(&mdma->regs->dmaerql, 0); | 772 | out_be32(&mdma->regs->dmaerqh, 0); |
730 | 773 | out_be32(&mdma->regs->dmaerql, 0); | |
731 | /* Disable error interrupts */ | 774 | |
732 | out_be32(&mdma->regs->dmaeeih, 0); | 775 | /* Disable error interrupts */ |
733 | out_be32(&mdma->regs->dmaeeil, 0); | 776 | out_be32(&mdma->regs->dmaeeih, 0); |
734 | 777 | out_be32(&mdma->regs->dmaeeil, 0); | |
735 | /* Clear interrupts status */ | 778 | |
736 | out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); | 779 | /* Clear interrupts status */ |
737 | out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); | 780 | out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); |
738 | out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); | 781 | out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); |
739 | out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); | 782 | out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); |
740 | 783 | out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); | |
741 | /* Route interrupts to IPIC */ | 784 | |
742 | out_be32(&mdma->regs->dmaihsa, 0); | 785 | /* Route interrupts to IPIC */ |
743 | out_be32(&mdma->regs->dmailsa, 0); | 786 | out_be32(&mdma->regs->dmaihsa, 0); |
787 | out_be32(&mdma->regs->dmailsa, 0); | ||
788 | } else { | ||
789 | /* MPC8308 has 16 channels and lacks some registers */ | ||
790 | out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_ERCA); | ||
791 | |||
792 | /* enable snooping */ | ||
793 | out_be32(&mdma->regs->dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE); | ||
794 | /* Disable error interrupts */ | ||
795 | out_be32(&mdma->regs->dmaeeil, 0); | ||
796 | |||
797 | /* Clear interrupts status */ | ||
798 | out_be32(&mdma->regs->dmaintl, 0xFFFF); | ||
799 | out_be32(&mdma->regs->dmaerrl, 0xFFFF); | ||
800 | } | ||
744 | 801 | ||
745 | /* Register DMA engine */ | 802 | /* Register DMA engine */ |
746 | dev_set_drvdata(dev, mdma); | 803 | dev_set_drvdata(dev, mdma); |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 92b679024fed..c064c89420d0 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
259 | return; | 259 | return; |
260 | } | 260 | } |
261 | 261 | ||
262 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
263 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
264 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
265 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
266 | |||
267 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", | 262 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", |
268 | pd_chan->chan.chan_id, desc->regs.dev_addr); | 263 | pd_chan->chan.chan_id, desc->regs.dev_addr); |
269 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", | 264 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", |
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
273 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", | 268 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", |
274 | pd_chan->chan.chan_id, desc->regs.next); | 269 | pd_chan->chan.chan_id, desc->regs.next); |
275 | 270 | ||
276 | if (list_empty(&desc->tx_list)) | 271 | if (list_empty(&desc->tx_list)) { |
272 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
273 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
274 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
275 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
277 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); | 276 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); |
278 | else | 277 | } else { |
278 | channel_writel(pd_chan, NEXT, desc->txd.phys); | ||
279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
280 | } | ||
280 | 281 | ||
281 | val = dma_readl(pd, CTL2); | 282 | val = dma_readl(pd, CTL2); |
282 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | 283 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); |
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 0d58a4a4487f..cef584533ee8 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev, | |||
4449 | 4449 | ||
4450 | if (!request_mem_region(res.start, resource_size(&res), | 4450 | if (!request_mem_region(res.start, resource_size(&res), |
4451 | dev_driver_string(&ofdev->dev))) { | 4451 | dev_driver_string(&ofdev->dev))) { |
4452 | dev_err(&ofdev->dev, "failed to request memory region " | 4452 | dev_err(&ofdev->dev, "failed to request memory region %pR\n", |
4453 | "(0x%016llx-0x%016llx)\n", | 4453 | &res); |
4454 | (u64)res.start, (u64)res.end); | ||
4455 | initcode = PPC_ADMA_INIT_MEMREG; | 4454 | initcode = PPC_ADMA_INIT_MEMREG; |
4456 | ret = -EBUSY; | 4455 | ret = -EBUSY; |
4457 | goto out; | 4456 | goto out; |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index eb6b54dbb806..85ffd5e38c50 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -1213,3 +1213,4 @@ module_exit(sh_dmae_exit); | |||
1213 | MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>"); | 1213 | MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>"); |
1214 | MODULE_DESCRIPTION("Renesas SH DMA Engine driver"); | 1214 | MODULE_DESCRIPTION("Renesas SH DMA Engine driver"); |
1215 | MODULE_LICENSE("GPL"); | 1215 | MODULE_LICENSE("GPL"); |
1216 | MODULE_ALIAS("platform:sh-dma-engine"); | ||