aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/dma.c
diff options
context:
space:
mode:
authorEric Miao <eric.y.miao@gmail.com>2007-06-22 00:40:17 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-07-12 09:28:16 -0400
commitf53f066c25036210036730d64c876ea586114425 (patch)
treee680deb53ff12ec09f5c64421a3f13eecb7aed41 /arch/arm/mach-pxa/dma.c
parentcd49104d99b56383a3b1fdce2f31018197093c31 (diff)
[ARM] 4451/1: pxa: make dma.c generic and remove cpu specific dma code
Since the number of dma channels varies between pxa25x and pxa27x, it introduces some specific code in dma.c. This patch moves the specific code to pxa25x.c and pxa27x.c and makes dma.c more generic. 1. add pxa_init_dma() for dma initialization, the number of channels are passed in by the argument 2. add a "prio" field to the "struct pxa_dma_channel" for the channel priority, and is initialized in pxa_init_dma() 3. use a general priority comparison with the channels "prio" field so to remove the processor specific pxa_for_each_dma_prio macro, this is not lightning fast as the original one, but it is acceptable as it happens when requesting dma, which is usually not so performance critical Signed-off-by: eric miao <eric.miao@marvell.com> Acked-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa/dma.c')
-rw-r--r--arch/arm/mach-pxa/dma.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index 4440babe7b97..93c4f31f127f 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -25,12 +25,15 @@
25 25
26#include <asm/arch/pxa-regs.h> 26#include <asm/arch/pxa-regs.h>
27 27
28static struct dma_channel { 28struct dma_channel {
29 char *name; 29 char *name;
30 pxa_dma_prio prio;
30 void (*irq_handler)(int, void *); 31 void (*irq_handler)(int, void *);
31 void *data; 32 void *data;
32} dma_channels[PXA_DMA_CHANNELS]; 33};
33 34
35static struct dma_channel *dma_channels;
36static int num_dma_channels;
34 37
35int pxa_request_dma (char *name, pxa_dma_prio prio, 38int pxa_request_dma (char *name, pxa_dma_prio prio,
36 void (*irq_handler)(int, void *), 39 void (*irq_handler)(int, void *),
@@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
47 50
48 do { 51 do {
49 /* try grabbing a DMA channel with the requested priority */ 52 /* try grabbing a DMA channel with the requested priority */
50 pxa_for_each_dma_prio (i, prio) { 53 for (i = 0; i < num_dma_channels; i++) {
51 if (!dma_channels[i].name) { 54 if ((dma_channels[i].prio == prio) &&
55 !dma_channels[i].name) {
52 found = 1; 56 found = 1;
53 break; 57 break;
54 } 58 }
@@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
91{ 95{
92 int i, dint = DINT; 96 int i, dint = DINT;
93 97
94 for (i = 0; i < PXA_DMA_CHANNELS; i++) { 98 for (i = 0; i < num_dma_channels; i++) {
95 if (dint & (1 << i)) { 99 if (dint & (1 << i)) {
96 struct dma_channel *channel = &dma_channels[i]; 100 struct dma_channel *channel = &dma_channels[i];
97 if (channel->name && channel->irq_handler) { 101 if (channel->name && channel->irq_handler) {
@@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
109 return IRQ_HANDLED; 113 return IRQ_HANDLED;
110} 114}
111 115
112static int __init pxa_dma_init (void) 116int __init pxa_init_dma(int num_ch)
113{ 117{
114 int ret; 118 int i, ret;
115 119
116 ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL); 120 dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
117 if (ret) 121 if (dma_channels == NULL)
122 return -ENOMEM;
123
124 ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
125 if (ret) {
118 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); 126 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
119 return ret; 127 kfree(dma_channels);
120} 128 return ret;
129 }
121 130
122arch_initcall(pxa_dma_init); 131 /* dma channel priorities on pxa2xx processors:
132 * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
133 * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
134 * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
135 */
136 for (i = 0; i < num_ch; i++)
137 dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
138
139 num_dma_channels = num_ch;
140 return 0;
141}
123 142
124EXPORT_SYMBOL(pxa_request_dma); 143EXPORT_SYMBOL(pxa_request_dma);
125EXPORT_SYMBOL(pxa_free_dma); 144EXPORT_SYMBOL(pxa_free_dma);
126