Ver Fonte

[ARM] 3500/1: fix PXA27x DMA allocation priority

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>
Nicolas Pitre há 19 anos atrás
pai
commit
99532559dc
2 ficheiros alterados com 19 adições e 24 exclusões
  1. 5 12
      arch/arm/mach-pxa/dma.c
  2. 14 12
      include/asm-arm/arch-pxa/dma.h

+ 5 - 12
arch/arm/mach-pxa/dma.c

@@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
 
 
 	local_irq_save(flags);
 	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) {
 			if (!dma_channels[i].name) {
 				found = 1;
 				found = 1;
 				break;
 				break;
 			}
 			}
 		}
 		}
-	}
+		/* if requested prio group is full, try a hier priority */
+	} while (!found && prio--);
 
 
 	if (found) {
 	if (found) {
 		DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
 		DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;

+ 14 - 12
include/asm-arm/arch-pxa/dma.h

@@ -24,27 +24,29 @@ typedef struct pxa_dma_desc {
 	volatile u32 dcmd;	/* DCMD value for the current transfer */
 	volatile u32 dcmd;	/* DCMD value for the current transfer */
 } pxa_dma_desc;
 } pxa_dma_desc;
 
 
+typedef enum {
+	DMA_PRIO_HIGH = 0,
+	DMA_PRIO_MEDIUM = 1,
+	DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
 #if defined(CONFIG_PXA27x)
 #if defined(CONFIG_PXA27x)
 
 
 #define PXA_DMA_CHANNELS	32
 #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)
 #elif defined(CONFIG_PXA25x)
 
 
 #define PXA_DMA_CHANNELS	16
 #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
 #endif