Merge ../linux-2.6-watchdog-mm
[linux-drm-fsl-dcu.git] / arch / sh / drivers / dma / dma-sh.c
index cbbe8bce3d679fd7d5b77e4f40363fd314dc3dee..66078601335009804e06213b82bef57a324b4765 100644 (file)
 #include <asm/io.h>
 #include "dma-sh.h"
 
-static inline unsigned int get_dmte_irq(unsigned int chan)
-{
-       unsigned int irq = 0;
 
+
+#ifdef CONFIG_CPU_SH4
+static struct ipr_data dmae_ipr_map[] = {
+       { DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+};
+#endif
+static struct ipr_data dmte_ipr_map[] = {
        /*
         * Normally we could just do DMTE0_IRQ + chan outright, though in the
         * case of the 7751R, the DMTE IRQs for channels > 4 start right above
         * the SCIF
         */
-       if (chan < 4) {
-               irq = DMTE0_IRQ + chan;
-       } else {
-#ifdef DMTE4_IRQ
-               irq = DMTE4_IRQ + chan - 4;
-#endif
-       }
+       { DMTE0_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE0_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE0_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE0_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+};
 
+static inline unsigned int get_dmte_irq(unsigned int chan)
+{
+       unsigned int irq = 0;
+       if (chan < ARRAY_SIZE(dmte_ipr_map))
+               irq = dmte_ipr_map[chan].irq;
        return irq;
 }
 
@@ -60,9 +71,9 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
  * Besides that it needs to waken any waiting process, which should handle
  * setting up the next transfer.
  */
-static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_tei(int irq, void *dev_id)
 {
-       struct dma_channel *chan = (struct dma_channel *)dev_id;
+       struct dma_channel *chan = dev_id;
        u32 chcr;
 
        chcr = ctrl_inl(CHCR[chan->chan]);
@@ -228,7 +239,7 @@ static inline int dmaor_reset(void)
 }
 
 #if defined(CONFIG_CPU_SH4)
-static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_err(int irq, void *dummy)
 {
        dmaor_reset();
        disable_irq(irq);
@@ -258,17 +269,16 @@ static int __init sh_dmac_init(void)
        int i;
 
 #ifdef CONFIG_CPU_SH4
-       make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+       make_ipr_irq(dmae_ipr_map, ARRAY_SIZE(dmae_ipr_map));
        i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
        if (unlikely(i < 0))
                return i;
 #endif
 
-       for (i = 0; i < info->nr_channels; i++) {
-               int irq = get_dmte_irq(i);
-
-               make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-       }
+       i = info->nr_channels;
+       if (i > ARRAY_SIZE(dmte_ipr_map))
+               i = ARRAY_SIZE(dmte_ipr_map);
+       make_ipr_irq(dmte_ipr_map, i);
 
        /*
         * Initialize DMAOR, and clean up any error flags that may have