diff options
| author | Paul Mundt <paul.mundt@nokia.com> | 2004-10-18 08:59:07 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-10-18 08:59:07 -0700 |
| commit | db9fd0a89082fa2c9d617ea2d0bf64f6b7892a62 (patch) | |
| tree | 3927cb8afa62945bd3466713d111887a8c0a2537 /arch/sh | |
| parent | ef43cf8888ef0c3a3f4121e6747cce44c0ec9c26 (diff) | |
[PATCH] sh: DMA API updates
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>
Diffstat (limited to 'arch/sh')
| -rw-r--r-- | arch/sh/drivers/dma/dma-api.c | 6 | ||||
| -rw-r--r-- | arch/sh/drivers/dma/dma-g2.c | 88 | ||||
| -rw-r--r-- | arch/sh/drivers/dma/dma-pvr2.c | 34 |
3 files changed, 62 insertions, 66 deletions
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index 3fc34e1cf7df..7c3330f118d0 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c @@ -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); diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c index f369e6c25cb3..231e3f6fb28f 100644 --- a/arch/sh/drivers/dma/dma-g2.c +++ b/arch/sh/drivers/dma/dma-g2.c @@ -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) diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index ee54adae2171..2e1d58f2d1b9 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c @@ -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) |
