aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/dma.c
diff options
context:
space:
mode:
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