]> git.hungrycats.org Git - linux/commitdiff
[PATCH] sh: DMA API updates
authorPaul Mundt <paul.mundt@nokia.com>
Mon, 18 Oct 2004 15:59:07 +0000 (08:59 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 18 Oct 2004 15:59:07 +0000 (08:59 -0700)
This updates some of the sh DMA drivers and core API.  Previously modules had
to register for the channels they were interested in, but now it's dealt with
transparently by the API with only the number of physical channels needing to
be specified by each module.

Signed-off-by: Paul Mundt <paul.mundt@nokia.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/sh/drivers/dma/dma-api.c
arch/sh/drivers/dma/dma-g2.c
arch/sh/drivers/dma/dma-pvr2.c

index 3fc34e1cf7dfdb2bad07cb207eee40c2d7176bdc..7c3330f118d04aa7c6bd37d073c3b553728215c1 100644 (file)
@@ -211,8 +211,9 @@ int __init register_dmac(struct dma_info *info)
 
        INIT_LIST_HEAD(&info->list);
 
-       printk(KERN_INFO "DMA: Registering %s handler (%d channels).\n",
-              info->name, info->nr_channels);
+       printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n",
+              info->name, info->nr_channels,
+              info->nr_channels > 1 ? "s" : "");
 
        BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
 
@@ -282,7 +283,6 @@ MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(request_dma);
 EXPORT_SYMBOL(free_dma);
 EXPORT_SYMBOL(register_dmac);
-EXPORT_SYMBOL(unregister_dmac);
 EXPORT_SYMBOL(get_dma_residue);
 EXPORT_SYMBOL(get_dma_info);
 EXPORT_SYMBOL(get_dma_channel);
index f369e6c25cb32f40ea5a4cee4a4bddf00ff019bb..231e3f6fb28faa0e8602cb1bfb98c4687cad5c17 100644 (file)
@@ -3,7 +3,7 @@
  *
  * G2 bus DMA support
  *
- * Copyright (C) 2003  Paul Mundt
+ * Copyright (C) 2003, 2004  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -59,104 +59,102 @@ static struct irqaction g2_dma_irq = {
        .flags          = SA_INTERRUPT,
 };
 
-static int g2_enable_dma(struct dma_info *info)
+static int g2_enable_dma(struct dma_channel *chan)
 {
-       unsigned int chan = info->chan;
+       unsigned int chan_nr = chan->chan;
 
-       g2_dma->channel[chan].chan_enable = 1;
-       g2_dma->channel[chan].xfer_enable = 1;
+       g2_dma->channel[chan_nr].chan_enable = 1;
+       g2_dma->channel[chan_nr].xfer_enable = 1;
 
        return 0;
 }
 
-static int g2_disable_dma(struct dma_info *info)
+static int g2_disable_dma(struct dma_channel *chan)
 {
-       unsigned int chan = info->chan;
+       unsigned int chan_nr = chan->chan;
 
-       g2_dma->channel[chan].chan_enable = 0;
-       g2_dma->channel[chan].xfer_enable = 0;
+       g2_dma->channel[chan_nr].chan_enable = 0;
+       g2_dma->channel[chan_nr].xfer_enable = 0;
 
        return 0;
 }
 
-static int g2_xfer_dma(struct dma_info *info)
+static int g2_xfer_dma(struct dma_channel *chan)
 {
-       unsigned int chan = info->chan;
+       unsigned int chan_nr = chan->chan;
 
-       if (info->sar & 31) {
-               printk("g2dma: unaligned source 0x%lx\n", info->sar);
+       if (chan->sar & 31) {
+               printk("g2dma: unaligned source 0x%lx\n", chan->sar);
                return -EINVAL;
        }
 
-       if (info->dar & 31) {
-               printk("g2dma: unaligned dest 0x%lx\n", info->dar);
+       if (chan->dar & 31) {
+               printk("g2dma: unaligned dest 0x%lx\n", chan->dar);
                return -EINVAL;
        }
 
        /* Align the count */
-       if (info->count & 31)
-               info->count = (info->count + (32 - 1)) & ~(32 - 1);
+       if (chan->count & 31)
+               chan->count = (chan->count + (32 - 1)) & ~(32 - 1);
 
        /* Fixup destination */
-       info->dar += 0xa0800000;
+       chan->dar += 0xa0800000;
 
        /* Fixup direction */
-       info->mode = !info->mode;
+       chan->mode = !chan->mode;
 
-       flush_icache_range((unsigned long)info->sar, info->count);
+       flush_icache_range((unsigned long)chan->sar, chan->count);
 
-       g2_disable_dma(info);
+       g2_disable_dma(chan);
 
-       g2_dma->channel[chan].g2_addr   = info->dar & 0x1fffffe0;
-       g2_dma->channel[chan].root_addr = info->sar & 0x1fffffe0;
-       g2_dma->channel[chan].size      = (info->count & ~31) | 0x80000000;
-       g2_dma->channel[chan].direction = info->mode;
+       g2_dma->channel[chan_nr].g2_addr   = chan->dar & 0x1fffffe0;
+       g2_dma->channel[chan_nr].root_addr = chan->sar & 0x1fffffe0;
+       g2_dma->channel[chan_nr].size      = (chan->count & ~31) | 0x80000000;
+       g2_dma->channel[chan_nr].direction = chan->mode;
 
        /*
         * bit 0 - ???
         * bit 1 - if set, generate a hardware event on transfer completion
         * bit 2 - ??? something to do with suspend?
         */
-       g2_dma->channel[chan].ctrl      = 5; /* ?? */
+       g2_dma->channel[chan_nr].ctrl   = 5; /* ?? */
+
+       g2_enable_dma(chan);
 
-       g2_enable_dma(info);
-       
        /* debug cruft */
        pr_debug("count, sar, dar, mode, ctrl, chan, xfer: %ld, 0x%08lx, "
                 "0x%08lx, %ld, %ld, %ld, %ld\n",
-                g2_dma->channel[chan].size,
-                g2_dma->channel[chan].root_addr,
-                g2_dma->channel[chan].g2_addr,
-                g2_dma->channel[chan].direction,
-                g2_dma->channel[chan].ctrl,
-                g2_dma->channel[chan].chan_enable,
-                g2_dma->channel[chan].xfer_enable);
+                g2_dma->channel[chan_nr].size,
+                g2_dma->channel[chan_nr].root_addr,
+                g2_dma->channel[chan_nr].g2_addr,
+                g2_dma->channel[chan_nr].direction,
+                g2_dma->channel[chan_nr].ctrl,
+                g2_dma->channel[chan_nr].chan_enable,
+                g2_dma->channel[chan_nr].xfer_enable);
 
        return 0;
 }
 
 static struct dma_ops g2_dma_ops = {
-       .name           = "G2 DMA",
        .xfer           = g2_xfer_dma,
 };
 
+static struct dma_info g2_dma_info = {
+       .name           = "G2 DMA",
+       .nr_channels    = 4,
+       .ops            = &g2_dma_ops,
+       .flags          = DMAC_CHANNELS_TEI_CAPABLE,
+};
+
 static int __init g2_dma_init(void)
 {
-       int i, base;
-
        setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq);
 
        /* Magic */
        g2_dma->wait_state      = 27;
        g2_dma->magic           = 0x4659404f;
 
-       /* G2 channels come after on-chip and pvr2 */
-       base = ONCHIP_NR_DMA_CHANNELS + PVR2_NR_DMA_CHANNELS;
-
-       for (i = 0; i < G2_NR_DMA_CHANNELS; i++)
-               dma_info[base + i].ops = &g2_dma_ops;
-       
-       return register_dmac(&g2_dma_ops);
+       return register_dmac(&g2_dma_info);
 }
 
 static void __exit g2_dma_exit(void)
index ee54adae2171665ba720c01eb742a4cd48916c79..2e1d58f2d1b94564e50be83cecb46770e26d1ad7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * NEC PowerVR 2 (Dreamcast) DMA support
  *
- * Copyright (C) 2003  Paul Mundt
+ * Copyright (C) 2003, 2004  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -38,7 +38,7 @@ static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *reg
        return IRQ_HANDLED;
 }
 
-static int pvr2_request_dma(struct dma_info *info)
+static int pvr2_request_dma(struct dma_channel *chan)
 {
        if (ctrl_inl(PVR2_DMA_MODE) != 0)
                return -EBUSY;
@@ -48,21 +48,21 @@ static int pvr2_request_dma(struct dma_info *info)
        return 0;
 }
 
-static int pvr2_get_dma_residue(struct dma_info *info)
+static int pvr2_get_dma_residue(struct dma_channel *chan)
 {
        return xfer_complete == 0;
 }
 
-static int pvr2_xfer_dma(struct dma_info *info)
+static int pvr2_xfer_dma(struct dma_channel *chan)
 {
-       if (info->sar || !info->dar)
+       if (chan->sar || !chan->dar)
                return -EINVAL;
 
        xfer_complete = 0;
 
-       ctrl_outl(info->dar, PVR2_DMA_ADDR);
-       ctrl_outl(info->count, PVR2_DMA_COUNT);
-       ctrl_outl(info->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
+       ctrl_outl(chan->dar, PVR2_DMA_ADDR);
+       ctrl_outl(chan->count, PVR2_DMA_COUNT);
+       ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
 
        return 0;
 }
@@ -74,26 +74,24 @@ static struct irqaction pvr2_dma_irq = {
 };
 
 static struct dma_ops pvr2_dma_ops = {
-       .name           = "PowerVR 2 DMA",
        .request        = pvr2_request_dma,
        .get_residue    = pvr2_get_dma_residue,
        .xfer           = pvr2_xfer_dma,
 };
 
+static struct dma_info pvr2_dma_info = {
+       .name           = "PowerVR 2 DMA",
+       .nr_channels    = 1,
+       .ops            = &pvr2_dma_ops,
+       .flags          = DMAC_CHANNELS_TEI_CAPABLE,
+};
+
 static int __init pvr2_dma_init(void)
 {
-       int i, base;
-
        setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
        request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
 
-       /* PVR2 cascade comes after on-chip DMAC */
-       base = ONCHIP_NR_DMA_CHANNELS;
-
-       for (i = 0; i < PVR2_NR_DMA_CHANNELS; i++)
-               dma_info[base + i].ops = &pvr2_dma_ops;
-
-       return register_dmac(&pvr2_dma_ops);
+       return register_dmac(&pvr2_dma_info);
 }
 
 static void __exit pvr2_dma_exit(void)