OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [armnommu/] [kernel/] [dma.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * linux/arch/arm/kernel/dma.c
3
 *
4
 * Copyright (C) 1995-1998 Russell King
5
 *
6
 * Front-end to the DMA handling.  You must provide the following
7
 * architecture-specific routines:
8
 *
9
 *  int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id);
10
 *  void arch_free_dma(dmach_t channel, dma_t *dma);
11
 *  void arch_enable_dma(dmach_t channel, dma_t *dma);
12
 *  void arch_disable_dma(dmach_t channel, dma_t *dma);
13
 *  int arch_get_dma_residue(dmach_t channel, dma_t *dma);
14
 *
15
 * Moved DMA resource allocation here...
16
 */
17
#include <linux/sched.h>
18
#include <linux/malloc.h>
19
#include <linux/mman.h>
20
 
21
#include <asm/page.h>
22
#include <asm/pgtable.h>
23
#include <asm/irq.h>
24
#include <asm/hardware.h>
25
#include <asm/io.h>
26
#include <asm/dma.h>
27
 
28
#include "dma.h"
29
 
30
static dma_t dma_chan[MAX_DMA_CHANNELS];
31
 
32
/* Get dma list
33
 * for /proc/dma
34
 */
35
int get_dma_list(char *buf)
36
{
37
        int i, len = 0;
38
 
39
        for (i = 0; i < MAX_DMA_CHANNELS; i++) {
40
                if (dma_chan[i].lock)
41
                        len += sprintf(buf + len, "%2d: %s\n",
42
                                       i, dma_chan[i].device_id);
43
        }
44
        return len;
45
}
46
 
47
/* Request DMA channel
48
 *
49
 * On certain platforms, we have to allocate an interrupt as well...
50
 */
51
int request_dma(dmach_t channel, const char *device_id)
52
{
53
        if (channel < MAX_DMA_CHANNELS) {
54
                int ret;
55
 
56
                if (xchg(&dma_chan[channel].lock, 1) != 0)
57
                        return -EBUSY;
58
 
59
                ret = arch_request_dma(channel, &dma_chan[channel], device_id);
60
                if (!ret) {
61
                        dma_chan[channel].device_id = device_id;
62
                        dma_chan[channel].active    = 0;
63
                        dma_chan[channel].invalid   = 1;
64
                } else
65
                        xchg(&dma_chan[channel].lock, 0);
66
 
67
                return ret;
68
        } else {
69
                printk(KERN_ERR "Trying to allocate DMA%d\n", channel);
70
                return -EINVAL;
71
        }
72
}
73
 
74
/* Free DMA channel
75
 *
76
 * On certain platforms, we have to free interrupt as well...
77
 */
78
void free_dma(dmach_t channel)
79
{
80
        if (channel >= MAX_DMA_CHANNELS) {
81
                printk(KERN_ERR "Trying to free DMA%d\n", channel);
82
                return;
83
        }
84
 
85
        if (xchg(&dma_chan[channel].lock, 0) == 0) {
86
                if (dma_chan[channel].active) {
87
                        printk(KERN_ERR "Freeing active DMA%d\n", channel);
88
                        arch_disable_dma(channel, &dma_chan[channel]);
89
                        dma_chan[channel].active = 0;
90
                }
91
 
92
                printk(KERN_ERR "Trying to free free DMA%d\n", channel);
93
                return;
94
        }
95
        arch_free_dma(channel, &dma_chan[channel]);
96
}
97
 
98
/* Set DMA Scatter-Gather list
99
 */
100
void set_dma_sg(dmach_t channel, dmasg_t *sg, int nr_sg)
101
{
102
        if (channel < MAX_DMA_CHANNELS) {
103
                dma_chan[channel].sg = sg;
104
                dma_chan[channel].sgcount = nr_sg;
105
                dma_chan[channel].invalid = 1;
106
        } else
107
                printk(KERN_ERR "Trying to set_dma_sg DMA%d\n",
108
                        channel);
109
}
110
 
111
/* Set DMA address
112
 *
113
 * Copy address to the structure, and set the invalid bit
114
 */
115
void set_dma_addr(dmach_t channel, unsigned long physaddr)
116
{
117
        if (channel < MAX_DMA_CHANNELS) {
118
                if (dma_chan[channel].active)
119
                        printk(KERN_ERR "set_dma_addr: altering DMA%d"
120
                               " address while DMA active\n",
121
                               channel);
122
 
123
                dma_chan[channel].sg = &dma_chan[channel].buf;
124
                dma_chan[channel].sgcount = 1;
125
                dma_chan[channel].buf.address = physaddr;
126
                dma_chan[channel].invalid = 1;
127
        } else
128
                printk(KERN_ERR "Trying to set_dma_addr DMA%d\n",
129
                        channel);
130
}
131
 
132
/* Set DMA byte count
133
 *
134
 * Copy address to the structure, and set the invalid bit
135
 */
136
void set_dma_count(dmach_t channel, unsigned long count)
137
{
138
        if (channel < MAX_DMA_CHANNELS) {
139
                if (dma_chan[channel].active)
140
                        printk(KERN_ERR "set_dma_count: altering DMA%d"
141
                               " count while DMA active\n",
142
                               channel);
143
 
144
                dma_chan[channel].sg = &dma_chan[channel].buf;
145
                dma_chan[channel].sgcount = 1;
146
                dma_chan[channel].buf.length = count;
147
                dma_chan[channel].invalid = 1;
148
        } else
149
                printk(KERN_ERR "Trying to set_dma_count DMA%d\n",
150
                        channel);
151
}
152
 
153
/* Set DMA direction mode
154
 */
155
void set_dma_mode(dmach_t channel, dmamode_t mode)
156
{
157
        if (channel < MAX_DMA_CHANNELS) {
158
                if (dma_chan[channel].active)
159
                        printk(KERN_ERR "set_dma_mode: altering DMA%d"
160
                               " mode while DMA active\n",
161
                               channel);
162
 
163
                dma_chan[channel].dma_mode = mode;
164
                dma_chan[channel].invalid = 1;
165
        } else
166
                printk(KERN_ERR "Trying to set_dma_mode DMA%d\n",
167
                        channel);
168
}
169
 
170
/* Enable DMA channel
171
 */
172
void enable_dma(dmach_t channel)
173
{
174
        if (channel < MAX_DMA_CHANNELS && dma_chan[channel].lock) {
175
                if (dma_chan[channel].active == 0) {
176
                        dma_chan[channel].active = 1;
177
                        arch_enable_dma(channel, &dma_chan[channel]);
178
                }
179
        } else
180
                printk(KERN_ERR "Trying to enable%s DMA%d\n",
181
                        channel < MAX_DMA_CHANNELS ? " free" : "", channel);
182
}
183
 
184
/* Disable DMA channel
185
 */
186
void disable_dma(dmach_t channel)
187
{
188
        if (channel < MAX_DMA_CHANNELS && dma_chan[channel].lock) {
189
                if (dma_chan[channel].active == 1) {
190
                        dma_chan[channel].active = 0;
191
                        arch_disable_dma(channel, &dma_chan[channel]);
192
                }
193
        } else
194
                printk(KERN_ERR "Trying to disable%s DMA%d\n",
195
                        channel < MAX_DMA_CHANNELS ? " free" : "", channel);
196
}
197
 
198
int get_dma_residue(dmach_t channel)
199
{
200
        if (channel < MAX_DMA_CHANNELS)
201
                return arch_get_dma_residue(channel, &dma_chan[channel]);
202
        else
203
                printk(KERN_ERR "Trying to get_dma_residue DMA%d\n",
204
                        channel);
205
}
206
 
207
void init_dma(void)
208
{
209
        arch_dma_init(dma_chan);
210
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.