Skip to content

Commit

Permalink
[ARM] 4451/1: pxa: make dma.c generic and remove cpu specific dma code
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eric Miao authored and Russell King committed Jul 12, 2007
1 parent cd49104 commit f53f066
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 33 deletions.
44 changes: 31 additions & 13 deletions arch/arm/mach-pxa/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@

#include <asm/arch/pxa-regs.h>

static struct dma_channel {
struct dma_channel {
char *name;
pxa_dma_prio prio;
void (*irq_handler)(int, void *);
void *data;
} dma_channels[PXA_DMA_CHANNELS];
};

static struct dma_channel *dma_channels;
static int num_dma_channels;

int pxa_request_dma (char *name, pxa_dma_prio prio,
void (*irq_handler)(int, void *),
Expand All @@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,

do {
/* try grabbing a DMA channel with the requested priority */
pxa_for_each_dma_prio (i, prio) {
if (!dma_channels[i].name) {
for (i = 0; i < num_dma_channels; i++) {
if ((dma_channels[i].prio == prio) &&
!dma_channels[i].name) {
found = 1;
break;
}
Expand Down Expand Up @@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
{
int i, dint = DINT;

for (i = 0; i < PXA_DMA_CHANNELS; i++) {
for (i = 0; i < num_dma_channels; i++) {
if (dint & (1 << i)) {
struct dma_channel *channel = &dma_channels[i];
if (channel->name && channel->irq_handler) {
Expand All @@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}

static int __init pxa_dma_init (void)
int __init pxa_init_dma(int num_ch)
{
int ret;
int i, ret;

ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
if (ret)
dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
if (dma_channels == NULL)
return -ENOMEM;

ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
if (ret) {
printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
return ret;
}
kfree(dma_channels);
return ret;
}

arch_initcall(pxa_dma_init);
/* dma channel priorities on pxa2xx processors:
* ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
* ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
* ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
*/
for (i = 0; i < num_ch; i++)
dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);

num_dma_channels = num_ch;
return 0;
}

EXPORT_SYMBOL(pxa_request_dma);
EXPORT_SYMBOL(pxa_free_dma);

5 changes: 5 additions & 0 deletions arch/arm/mach-pxa/pxa25x.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <asm/arch/irqs.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pm.h>
#include <asm/arch/dma.h>

#include "generic.h"

Expand Down Expand Up @@ -137,7 +138,11 @@ void __init pxa25x_init_irq(void)

static int __init pxa25x_init(void)
{
int ret = 0;

if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
if ((ret = pxa_init_dma(16)))
return ret;
#ifdef CONFIG_PM
pm_set_ops(&pxa25x_pm_ops);
#endif
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/mach-pxa/pxa27x.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/ohci.h>
#include <asm/arch/pm.h>
#include <asm/arch/dma.h>

#include "generic.h"

Expand Down Expand Up @@ -214,6 +215,8 @@ static int __init pxa27x_init(void)
{
int ret = 0;
if (cpu_is_pxa27x()) {
if ((ret = pxa_init_dma(32)))
return ret;
#ifdef CONFIG_PM
pm_set_ops(&pxa27x_pm_ops);
#endif
Expand Down
22 changes: 2 additions & 20 deletions include/asm-arm/arch-pxa/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,12 @@ typedef enum {
DMA_PRIO_LOW = 2
} pxa_dma_prio;

#if defined(CONFIG_PXA27x)

#define PXA_DMA_CHANNELS 32

#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_for_each_dma_prio(ch, prio) \
for (ch = prio * 4; ch != (4 << prio); ch++)

#endif

/*
* DMA registration
*/

int __init pxa_init_dma(int num_ch);

int pxa_request_dma (char *name,
pxa_dma_prio prio,
void (*irq_handler)(int, void *),
Expand Down

0 comments on commit f53f066

Please sign in to comment.