]> err.no Git - linux-2.6/commitdiff
[ARM] 3500/1: fix PXA27x DMA allocation priority
authorNicolas Pitre <nico@cam.org>
Fri, 5 May 2006 21:32:24 +0000 (22:32 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 5 May 2006 21:32:24 +0000 (22:32 +0100)
Patch from Nicolas Pitre

Intel PXA27x developers manual section 5.4.1.1 lists a priority
distribution for the DMA channels differently than what the code
currently assumes.  This patch fixes that.

Noticed by Simon Vogl <vogl@soft.uni-linz.ac.at>

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-pxa/dma.c
include/asm-arm/arch-pxa/dma.h

index 458112b21e25df5008783edab1d288d51e338dd5..7d8c85486c669065554d1857b4359ce94ee9b6c8 100644 (file)
@@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
 
        local_irq_save(flags);
 
-       /* try grabbing a DMA channel with the requested priority */
-       for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) {
-               if (!dma_channels[i].name) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (!found) {
-               /* requested prio group is full, try hier priorities */
-               for (i = prio-1; i >= 0; i--) {
+       do {
+               /* try grabbing a DMA channel with the requested priority */
+               pxa_for_each_dma_prio (i, prio) {
                        if (!dma_channels[i].name) {
                                found = 1;
                                break;
                        }
                }
-       }
+               /* if requested prio group is full, try a hier priority */
+       } while (!found && prio--);
 
        if (found) {
                DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
index 3e88a2a02a0fdd01186107439eed4711d38b9a7f..a008150abc59f2775e8ce25e03b3bb0f2b1476ec 100644 (file)
@@ -24,27 +24,29 @@ typedef struct pxa_dma_desc {
        volatile u32 dcmd;      /* DCMD value for the current transfer */
 } pxa_dma_desc;
 
+typedef enum {
+       DMA_PRIO_HIGH = 0,
+       DMA_PRIO_MEDIUM = 1,
+       DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
 #if defined(CONFIG_PXA27x)
 
 #define PXA_DMA_CHANNELS       32
-#define PXA_DMA_NBCH(prio)     ((prio == DMA_PRIO_LOW) ? 16 : 8)
 
-typedef enum {
-       DMA_PRIO_HIGH = 0,
-       DMA_PRIO_MEDIUM = 8,
-       DMA_PRIO_LOW = 16
-} pxa_dma_prio;
+#define pxa_for_each_dma_prio(ch, prio)                                        \
+for (                                                                  \
+       ch = prio * 4;                                                  \
+       ch != (4 << prio) + 16;                                         \
+       ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1)       \
+)
 
 #elif defined(CONFIG_PXA25x)
 
 #define PXA_DMA_CHANNELS       16
-#define PXA_DMA_NBCH(prio)     ((prio == DMA_PRIO_LOW) ? 8 : 4)
 
-typedef enum {
-       DMA_PRIO_HIGH = 0,
-       DMA_PRIO_MEDIUM = 4,
-       DMA_PRIO_LOW = 8
-} pxa_dma_prio;
+#define pxa_for_each_dma_prio(ch, prio)                                        \
+       for (ch = prio * 4; ch != (4 << prio); ch++)
 
 #endif