Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f53f066c25036210036730d64c876ea586114425
Commit:     f53f066c25036210036730d64c876ea586114425
Parent:     cd49104d99b56383a3b1fdce2f31018197093c31
Author:     Eric Miao <[EMAIL PROTECTED]>
AuthorDate: Fri Jun 22 05:40:17 2007 +0100
Committer:  Russell King <[EMAIL PROTECTED]>
CommitDate: Thu Jul 12 14:28:16 2007 +0100

    [ARM] 4451/1: pxa: make dma.c generic and remove cpu specific dma code
    
    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 <[EMAIL PROTECTED]>
    Acked-by: Nicolas Pitre <[EMAIL PROTECTED]>
    Signed-off-by: Russell King <[EMAIL PROTECTED]>
---
 arch/arm/mach-pxa/dma.c        |   44 ++++++++++++++++++++++++++++-----------
 arch/arm/mach-pxa/pxa25x.c     |    5 ++++
 arch/arm/mach-pxa/pxa27x.c     |    3 ++
 include/asm-arm/arch-pxa/dma.h |   22 +------------------
 4 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index 4440bab..93c4f31 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -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 *),
@@ -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;
                        }
@@ -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) {
@@ -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);
-
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index a8796ae..1343758 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -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"
 
@@ -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
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 1407985..5b819e2 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -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"
 
@@ -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
diff --git a/include/asm-arm/arch-pxa/dma.h b/include/asm-arm/arch-pxa/dma.h
index bed042d..3280ee2 100644
--- a/include/asm-arm/arch-pxa/dma.h
+++ b/include/asm-arm/arch-pxa/dma.h
@@ -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 *),
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to