~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/sh/drivers/dma/dma-pvr2.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * arch/sh/drivers/dma/dma-pvr2.c
 
3
 *
 
4
 * NEC PowerVR 2 (Dreamcast) DMA support
 
5
 *
 
6
 * Copyright (C) 2003, 2004  Paul Mundt
 
7
 *
 
8
 * This file is subject to the terms and conditions of the GNU General Public
 
9
 * License.  See the file "COPYING" in the main directory of this archive
 
10
 * for more details.
 
11
 */
 
12
#include <linux/init.h>
 
13
#include <linux/kernel.h>
 
14
#include <linux/module.h>
 
15
#include <linux/interrupt.h>
 
16
#include <mach/sysasic.h>
 
17
#include <mach/dma.h>
 
18
#include <asm/dma.h>
 
19
#include <asm/io.h>
 
20
 
 
21
static unsigned int xfer_complete;
 
22
static int count;
 
23
 
 
24
static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id)
 
25
{
 
26
        if (get_dma_residue(PVR2_CASCADE_CHAN)) {
 
27
                printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
 
28
                       "on channel %d, waiting..\n", PVR2_CASCADE_CHAN);
 
29
                dma_wait_for_completion(PVR2_CASCADE_CHAN);
 
30
        }
 
31
 
 
32
        if (count++ < 10)
 
33
                pr_debug("Got a pvr2 dma interrupt for channel %d\n",
 
34
                         irq - HW_EVENT_PVR2_DMA);
 
35
 
 
36
        xfer_complete = 1;
 
37
 
 
38
        return IRQ_HANDLED;
 
39
}
 
40
 
 
41
static int pvr2_request_dma(struct dma_channel *chan)
 
42
{
 
43
        if (__raw_readl(PVR2_DMA_MODE) != 0)
 
44
                return -EBUSY;
 
45
 
 
46
        __raw_writel(0, PVR2_DMA_LMMODE0);
 
47
 
 
48
        return 0;
 
49
}
 
50
 
 
51
static int pvr2_get_dma_residue(struct dma_channel *chan)
 
52
{
 
53
        return xfer_complete == 0;
 
54
}
 
55
 
 
56
static int pvr2_xfer_dma(struct dma_channel *chan)
 
57
{
 
58
        if (chan->sar || !chan->dar)
 
59
                return -EINVAL;
 
60
 
 
61
        xfer_complete = 0;
 
62
 
 
63
        __raw_writel(chan->dar, PVR2_DMA_ADDR);
 
64
        __raw_writel(chan->count, PVR2_DMA_COUNT);
 
65
        __raw_writel(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
 
66
 
 
67
        return 0;
 
68
}
 
69
 
 
70
static struct irqaction pvr2_dma_irq = {
 
71
        .name           = "pvr2 DMA handler",
 
72
        .handler        = pvr2_dma_interrupt,
 
73
};
 
74
 
 
75
static struct dma_ops pvr2_dma_ops = {
 
76
        .request        = pvr2_request_dma,
 
77
        .get_residue    = pvr2_get_dma_residue,
 
78
        .xfer           = pvr2_xfer_dma,
 
79
};
 
80
 
 
81
static struct dma_info pvr2_dma_info = {
 
82
        .name           = "pvr2_dmac",
 
83
        .nr_channels    = 1,
 
84
        .ops            = &pvr2_dma_ops,
 
85
        .flags          = DMAC_CHANNELS_TEI_CAPABLE,
 
86
};
 
87
 
 
88
static int __init pvr2_dma_init(void)
 
89
{
 
90
        setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
 
91
        request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
 
92
 
 
93
        return register_dmac(&pvr2_dma_info);
 
94
}
 
95
 
 
96
static void __exit pvr2_dma_exit(void)
 
97
{
 
98
        free_dma(PVR2_CASCADE_CHAN);
 
99
        free_irq(HW_EVENT_PVR2_DMA, 0);
 
100
        unregister_dmac(&pvr2_dma_info);
 
101
}
 
102
 
 
103
subsys_initcall(pvr2_dma_init);
 
104
module_exit(pvr2_dma_exit);
 
105
 
 
106
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
 
107
MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
 
108
MODULE_LICENSE("GPL");