Commit 99532559 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King

[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: default avatarNicolas Pitre <nico@cam.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent b7d7ef87
...@@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio, ...@@ -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 */ do {
for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { /* try grabbing a DMA channel with the requested priority */
if (!dma_channels[i].name) { pxa_for_each_dma_prio (i, prio) {
found = 1;
break;
}
}
if (!found) {
/* requested prio group is full, try hier priorities */
for (i = prio-1; i >= 0; i--) {
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;
......
...@@ -24,27 +24,29 @@ typedef struct pxa_dma_desc { ...@@ -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 { #define pxa_for_each_dma_prio(ch, prio) \
DMA_PRIO_HIGH = 0, for ( \
DMA_PRIO_MEDIUM = 8, ch = prio * 4; \
DMA_PRIO_LOW = 16 ch != (4 << prio) + 16; \
} pxa_dma_prio; 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 { #define pxa_for_each_dma_prio(ch, prio) \
DMA_PRIO_HIGH = 0, for (ch = prio * 4; ch != (4 << prio); ch++)
DMA_PRIO_MEDIUM = 4,
DMA_PRIO_LOW = 8
} pxa_dma_prio;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment