Commit ec14d7964bc3c89fb24c95af00d39033afc32f8e
Committed by
Russell King
1 parent
6b8777b468
Exists in
master
and in
7 other branches
[ARM] Export dma_channel_active()
dma_channel_active() is used by some modules and is part of our DMA API, so export it. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 1 changed file with 1 additions and 0 deletions Inline Diff
arch/arm/kernel/dma.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/kernel/dma.c | 2 | * linux/arch/arm/kernel/dma.c |
3 | * | 3 | * |
4 | * Copyright (C) 1995-2000 Russell King | 4 | * Copyright (C) 1995-2000 Russell King |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * Front-end to the DMA handling. This handles the allocation/freeing | 10 | * Front-end to the DMA handling. This handles the allocation/freeing |
11 | * of DMA channels, and provides a unified interface to the machines | 11 | * of DMA channels, and provides a unified interface to the machines |
12 | * DMA facilities. | 12 | * DMA facilities. |
13 | */ | 13 | */ |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | 18 | ||
19 | #include <asm/dma.h> | 19 | #include <asm/dma.h> |
20 | 20 | ||
21 | #include <asm/mach/dma.h> | 21 | #include <asm/mach/dma.h> |
22 | 22 | ||
23 | DEFINE_SPINLOCK(dma_spin_lock); | 23 | DEFINE_SPINLOCK(dma_spin_lock); |
24 | EXPORT_SYMBOL(dma_spin_lock); | 24 | EXPORT_SYMBOL(dma_spin_lock); |
25 | 25 | ||
26 | static dma_t dma_chan[MAX_DMA_CHANNELS]; | 26 | static dma_t dma_chan[MAX_DMA_CHANNELS]; |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Get dma list for /proc/dma | 29 | * Get dma list for /proc/dma |
30 | */ | 30 | */ |
31 | int get_dma_list(char *buf) | 31 | int get_dma_list(char *buf) |
32 | { | 32 | { |
33 | dma_t *dma; | 33 | dma_t *dma; |
34 | char *p = buf; | 34 | char *p = buf; |
35 | int i; | 35 | int i; |
36 | 36 | ||
37 | for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++) | 37 | for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++) |
38 | if (dma->lock) | 38 | if (dma->lock) |
39 | p += sprintf(p, "%2d: %14s %s\n", i, | 39 | p += sprintf(p, "%2d: %14s %s\n", i, |
40 | dma->d_ops->type, dma->device_id); | 40 | dma->d_ops->type, dma->device_id); |
41 | 41 | ||
42 | return p - buf; | 42 | return p - buf; |
43 | } | 43 | } |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * Request DMA channel | 46 | * Request DMA channel |
47 | * | 47 | * |
48 | * On certain platforms, we have to allocate an interrupt as well... | 48 | * On certain platforms, we have to allocate an interrupt as well... |
49 | */ | 49 | */ |
50 | int request_dma(dmach_t channel, const char *device_id) | 50 | int request_dma(dmach_t channel, const char *device_id) |
51 | { | 51 | { |
52 | dma_t *dma = dma_chan + channel; | 52 | dma_t *dma = dma_chan + channel; |
53 | int ret; | 53 | int ret; |
54 | 54 | ||
55 | if (channel >= MAX_DMA_CHANNELS || !dma->d_ops) | 55 | if (channel >= MAX_DMA_CHANNELS || !dma->d_ops) |
56 | goto bad_dma; | 56 | goto bad_dma; |
57 | 57 | ||
58 | if (xchg(&dma->lock, 1) != 0) | 58 | if (xchg(&dma->lock, 1) != 0) |
59 | goto busy; | 59 | goto busy; |
60 | 60 | ||
61 | dma->device_id = device_id; | 61 | dma->device_id = device_id; |
62 | dma->active = 0; | 62 | dma->active = 0; |
63 | dma->invalid = 1; | 63 | dma->invalid = 1; |
64 | 64 | ||
65 | ret = 0; | 65 | ret = 0; |
66 | if (dma->d_ops->request) | 66 | if (dma->d_ops->request) |
67 | ret = dma->d_ops->request(channel, dma); | 67 | ret = dma->d_ops->request(channel, dma); |
68 | 68 | ||
69 | if (ret) | 69 | if (ret) |
70 | xchg(&dma->lock, 0); | 70 | xchg(&dma->lock, 0); |
71 | 71 | ||
72 | return ret; | 72 | return ret; |
73 | 73 | ||
74 | bad_dma: | 74 | bad_dma: |
75 | printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel); | 75 | printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel); |
76 | return -EINVAL; | 76 | return -EINVAL; |
77 | 77 | ||
78 | busy: | 78 | busy: |
79 | return -EBUSY; | 79 | return -EBUSY; |
80 | } | 80 | } |
81 | EXPORT_SYMBOL(request_dma); | 81 | EXPORT_SYMBOL(request_dma); |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * Free DMA channel | 84 | * Free DMA channel |
85 | * | 85 | * |
86 | * On certain platforms, we have to free interrupt as well... | 86 | * On certain platforms, we have to free interrupt as well... |
87 | */ | 87 | */ |
88 | void free_dma(dmach_t channel) | 88 | void free_dma(dmach_t channel) |
89 | { | 89 | { |
90 | dma_t *dma = dma_chan + channel; | 90 | dma_t *dma = dma_chan + channel; |
91 | 91 | ||
92 | if (channel >= MAX_DMA_CHANNELS || !dma->d_ops) | 92 | if (channel >= MAX_DMA_CHANNELS || !dma->d_ops) |
93 | goto bad_dma; | 93 | goto bad_dma; |
94 | 94 | ||
95 | if (dma->active) { | 95 | if (dma->active) { |
96 | printk(KERN_ERR "dma%d: freeing active DMA\n", channel); | 96 | printk(KERN_ERR "dma%d: freeing active DMA\n", channel); |
97 | dma->d_ops->disable(channel, dma); | 97 | dma->d_ops->disable(channel, dma); |
98 | dma->active = 0; | 98 | dma->active = 0; |
99 | } | 99 | } |
100 | 100 | ||
101 | if (xchg(&dma->lock, 0) != 0) { | 101 | if (xchg(&dma->lock, 0) != 0) { |
102 | if (dma->d_ops->free) | 102 | if (dma->d_ops->free) |
103 | dma->d_ops->free(channel, dma); | 103 | dma->d_ops->free(channel, dma); |
104 | return; | 104 | return; |
105 | } | 105 | } |
106 | 106 | ||
107 | printk(KERN_ERR "dma%d: trying to free free DMA\n", channel); | 107 | printk(KERN_ERR "dma%d: trying to free free DMA\n", channel); |
108 | return; | 108 | return; |
109 | 109 | ||
110 | bad_dma: | 110 | bad_dma: |
111 | printk(KERN_ERR "dma: trying to free DMA%d\n", channel); | 111 | printk(KERN_ERR "dma: trying to free DMA%d\n", channel); |
112 | } | 112 | } |
113 | EXPORT_SYMBOL(free_dma); | 113 | EXPORT_SYMBOL(free_dma); |
114 | 114 | ||
115 | /* Set DMA Scatter-Gather list | 115 | /* Set DMA Scatter-Gather list |
116 | */ | 116 | */ |
117 | void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg) | 117 | void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg) |
118 | { | 118 | { |
119 | dma_t *dma = dma_chan + channel; | 119 | dma_t *dma = dma_chan + channel; |
120 | 120 | ||
121 | if (dma->active) | 121 | if (dma->active) |
122 | printk(KERN_ERR "dma%d: altering DMA SG while " | 122 | printk(KERN_ERR "dma%d: altering DMA SG while " |
123 | "DMA active\n", channel); | 123 | "DMA active\n", channel); |
124 | 124 | ||
125 | dma->sg = sg; | 125 | dma->sg = sg; |
126 | dma->sgcount = nr_sg; | 126 | dma->sgcount = nr_sg; |
127 | dma->invalid = 1; | 127 | dma->invalid = 1; |
128 | } | 128 | } |
129 | EXPORT_SYMBOL(set_dma_sg); | 129 | EXPORT_SYMBOL(set_dma_sg); |
130 | 130 | ||
131 | /* Set DMA address | 131 | /* Set DMA address |
132 | * | 132 | * |
133 | * Copy address to the structure, and set the invalid bit | 133 | * Copy address to the structure, and set the invalid bit |
134 | */ | 134 | */ |
135 | void __set_dma_addr (dmach_t channel, void *addr) | 135 | void __set_dma_addr (dmach_t channel, void *addr) |
136 | { | 136 | { |
137 | dma_t *dma = dma_chan + channel; | 137 | dma_t *dma = dma_chan + channel; |
138 | 138 | ||
139 | if (dma->active) | 139 | if (dma->active) |
140 | printk(KERN_ERR "dma%d: altering DMA address while " | 140 | printk(KERN_ERR "dma%d: altering DMA address while " |
141 | "DMA active\n", channel); | 141 | "DMA active\n", channel); |
142 | 142 | ||
143 | dma->sg = NULL; | 143 | dma->sg = NULL; |
144 | dma->addr = addr; | 144 | dma->addr = addr; |
145 | dma->invalid = 1; | 145 | dma->invalid = 1; |
146 | } | 146 | } |
147 | EXPORT_SYMBOL(__set_dma_addr); | 147 | EXPORT_SYMBOL(__set_dma_addr); |
148 | 148 | ||
149 | /* Set DMA byte count | 149 | /* Set DMA byte count |
150 | * | 150 | * |
151 | * Copy address to the structure, and set the invalid bit | 151 | * Copy address to the structure, and set the invalid bit |
152 | */ | 152 | */ |
153 | void set_dma_count (dmach_t channel, unsigned long count) | 153 | void set_dma_count (dmach_t channel, unsigned long count) |
154 | { | 154 | { |
155 | dma_t *dma = dma_chan + channel; | 155 | dma_t *dma = dma_chan + channel; |
156 | 156 | ||
157 | if (dma->active) | 157 | if (dma->active) |
158 | printk(KERN_ERR "dma%d: altering DMA count while " | 158 | printk(KERN_ERR "dma%d: altering DMA count while " |
159 | "DMA active\n", channel); | 159 | "DMA active\n", channel); |
160 | 160 | ||
161 | dma->sg = NULL; | 161 | dma->sg = NULL; |
162 | dma->count = count; | 162 | dma->count = count; |
163 | dma->invalid = 1; | 163 | dma->invalid = 1; |
164 | } | 164 | } |
165 | EXPORT_SYMBOL(set_dma_count); | 165 | EXPORT_SYMBOL(set_dma_count); |
166 | 166 | ||
167 | /* Set DMA direction mode | 167 | /* Set DMA direction mode |
168 | */ | 168 | */ |
169 | void set_dma_mode (dmach_t channel, dmamode_t mode) | 169 | void set_dma_mode (dmach_t channel, dmamode_t mode) |
170 | { | 170 | { |
171 | dma_t *dma = dma_chan + channel; | 171 | dma_t *dma = dma_chan + channel; |
172 | 172 | ||
173 | if (dma->active) | 173 | if (dma->active) |
174 | printk(KERN_ERR "dma%d: altering DMA mode while " | 174 | printk(KERN_ERR "dma%d: altering DMA mode while " |
175 | "DMA active\n", channel); | 175 | "DMA active\n", channel); |
176 | 176 | ||
177 | dma->dma_mode = mode; | 177 | dma->dma_mode = mode; |
178 | dma->invalid = 1; | 178 | dma->invalid = 1; |
179 | } | 179 | } |
180 | EXPORT_SYMBOL(set_dma_mode); | 180 | EXPORT_SYMBOL(set_dma_mode); |
181 | 181 | ||
182 | /* Enable DMA channel | 182 | /* Enable DMA channel |
183 | */ | 183 | */ |
184 | void enable_dma (dmach_t channel) | 184 | void enable_dma (dmach_t channel) |
185 | { | 185 | { |
186 | dma_t *dma = dma_chan + channel; | 186 | dma_t *dma = dma_chan + channel; |
187 | 187 | ||
188 | if (!dma->lock) | 188 | if (!dma->lock) |
189 | goto free_dma; | 189 | goto free_dma; |
190 | 190 | ||
191 | if (dma->active == 0) { | 191 | if (dma->active == 0) { |
192 | dma->active = 1; | 192 | dma->active = 1; |
193 | dma->d_ops->enable(channel, dma); | 193 | dma->d_ops->enable(channel, dma); |
194 | } | 194 | } |
195 | return; | 195 | return; |
196 | 196 | ||
197 | free_dma: | 197 | free_dma: |
198 | printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel); | 198 | printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel); |
199 | BUG(); | 199 | BUG(); |
200 | } | 200 | } |
201 | EXPORT_SYMBOL(enable_dma); | 201 | EXPORT_SYMBOL(enable_dma); |
202 | 202 | ||
203 | /* Disable DMA channel | 203 | /* Disable DMA channel |
204 | */ | 204 | */ |
205 | void disable_dma (dmach_t channel) | 205 | void disable_dma (dmach_t channel) |
206 | { | 206 | { |
207 | dma_t *dma = dma_chan + channel; | 207 | dma_t *dma = dma_chan + channel; |
208 | 208 | ||
209 | if (!dma->lock) | 209 | if (!dma->lock) |
210 | goto free_dma; | 210 | goto free_dma; |
211 | 211 | ||
212 | if (dma->active == 1) { | 212 | if (dma->active == 1) { |
213 | dma->active = 0; | 213 | dma->active = 0; |
214 | dma->d_ops->disable(channel, dma); | 214 | dma->d_ops->disable(channel, dma); |
215 | } | 215 | } |
216 | return; | 216 | return; |
217 | 217 | ||
218 | free_dma: | 218 | free_dma: |
219 | printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel); | 219 | printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel); |
220 | BUG(); | 220 | BUG(); |
221 | } | 221 | } |
222 | EXPORT_SYMBOL(disable_dma); | 222 | EXPORT_SYMBOL(disable_dma); |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * Is the specified DMA channel active? | 225 | * Is the specified DMA channel active? |
226 | */ | 226 | */ |
227 | int dma_channel_active(dmach_t channel) | 227 | int dma_channel_active(dmach_t channel) |
228 | { | 228 | { |
229 | return dma_chan[channel].active; | 229 | return dma_chan[channel].active; |
230 | } | 230 | } |
231 | EXPORT_SYMBOL(dma_channel_active); | ||
231 | 232 | ||
232 | void set_dma_page(dmach_t channel, char pagenr) | 233 | void set_dma_page(dmach_t channel, char pagenr) |
233 | { | 234 | { |
234 | printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel); | 235 | printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel); |
235 | } | 236 | } |
236 | EXPORT_SYMBOL(set_dma_page); | 237 | EXPORT_SYMBOL(set_dma_page); |
237 | 238 | ||
238 | void set_dma_speed(dmach_t channel, int cycle_ns) | 239 | void set_dma_speed(dmach_t channel, int cycle_ns) |
239 | { | 240 | { |
240 | dma_t *dma = dma_chan + channel; | 241 | dma_t *dma = dma_chan + channel; |
241 | int ret = 0; | 242 | int ret = 0; |
242 | 243 | ||
243 | if (dma->d_ops->setspeed) | 244 | if (dma->d_ops->setspeed) |
244 | ret = dma->d_ops->setspeed(channel, dma, cycle_ns); | 245 | ret = dma->d_ops->setspeed(channel, dma, cycle_ns); |
245 | dma->speed = ret; | 246 | dma->speed = ret; |
246 | } | 247 | } |
247 | EXPORT_SYMBOL(set_dma_speed); | 248 | EXPORT_SYMBOL(set_dma_speed); |
248 | 249 | ||
249 | int get_dma_residue(dmach_t channel) | 250 | int get_dma_residue(dmach_t channel) |
250 | { | 251 | { |
251 | dma_t *dma = dma_chan + channel; | 252 | dma_t *dma = dma_chan + channel; |
252 | int ret = 0; | 253 | int ret = 0; |
253 | 254 | ||
254 | if (dma->d_ops->residue) | 255 | if (dma->d_ops->residue) |
255 | ret = dma->d_ops->residue(channel, dma); | 256 | ret = dma->d_ops->residue(channel, dma); |
256 | 257 | ||
257 | return ret; | 258 | return ret; |
258 | } | 259 | } |
259 | EXPORT_SYMBOL(get_dma_residue); | 260 | EXPORT_SYMBOL(get_dma_residue); |
260 | 261 | ||
261 | static int __init init_dma(void) | 262 | static int __init init_dma(void) |
262 | { | 263 | { |
263 | arch_dma_init(dma_chan); | 264 | arch_dma_init(dma_chan); |
264 | return 0; | 265 | return 0; |
265 | } | 266 | } |
266 | 267 | ||
267 | core_initcall(init_dma); | 268 | core_initcall(init_dma); |
268 | 269 |