13 #include <linux/module.h>
16 #include <linux/list.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
36 (chan >= info->first_vchannel_nr + info->nr_channels))
51 if (dmac_name && (
strcmp(dmac_name, info->
name) != 0))
61 static unsigned int get_nr_channels(
void)
66 if (
unlikely(list_empty(®istered_dmac_list)))
70 nr += info->nr_channels;
84 for (i = 0; i < info->nr_channels; i++) {
85 channel = &info->channels[
i];
86 if (channel->vchan == chan)
99 if (info->ops->get_residue)
100 return info->ops->get_residue(channel);
106 static int search_cap(
const char **haystack,
const char *needle)
110 for (p = haystack; *
p; p++)
111 if (
strcmp(*p, needle) == 0)
132 unsigned int found = 0;
148 for (i = 0; i < info->nr_channels; i++) {
154 for (p = caps; *
p; p++) {
155 if (!search_cap(channel->caps, *p))
158 return channel->chan;
172 for (i = 0; i < info->nr_channels; i++) {
173 channel = &info->channels[
i];
181 if (info->ops->request) {
182 int result = info->ops->request(channel);
187 return channel->chan;
203 strlcpy(channel->dev_id, dev_id,
sizeof(channel->dev_id));
205 if (info->ops->request) {
206 result = info->ops->request(channel);
223 info->ops->free(channel);
234 if (channel->flags & DMA_TEI_CAPABLE) {
236 (info->ops->get_residue(channel) == 0));
240 while (info->ops->get_residue(channel))
248 unsigned int found = 0;
260 for (i = 0; i < info->nr_channels; i++, caps++) {
263 if ((info->first_channel_nr + i) != caps->ch_num)
266 channel = &info->channels[
i];
267 channel->caps = caps->caplist;
279 if (info->ops->configure)
280 info->ops->configure(channel, flags);
285 unsigned long to,
size_t size,
unsigned int mode)
292 channel->count =
size;
293 channel->mode =
mode;
295 return info->ops->xfer(channel);
304 if (info->ops->extend)
305 return info->ops->extend(channel, op, param);
312 int len,
int *eof,
void *
data)
317 if (list_empty(®istered_dmac_list))
329 for (i = 0; i < info->nr_channels; i++) {
332 if (!(channel->flags & DMA_CONFIGURED))
335 p +=
sprintf(p,
"%2d: %14s %s\n", i,
336 info->
name, channel->dev_id);
345 unsigned int total_channels,
i;
347 INIT_LIST_HEAD(&info->list);
350 info->
name, info->nr_channels, info->nr_channels > 1 ?
"s" :
"");
352 BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
354 info->pdev = platform_device_register_simple(info->
name, -1,
356 if (IS_ERR(info->pdev))
357 return PTR_ERR(info->pdev);
362 if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) {
365 size =
sizeof(
struct dma_channel) * info->nr_channels;
372 total_channels = get_nr_channels();
373 info->first_vchannel_nr = total_channels;
374 for (i = 0; i < info->nr_channels; i++) {
379 chan->chan = info->first_channel_nr +
i;
380 chan->vchan = info->first_channel_nr + i + total_channels;
382 memcpy(chan->dev_id,
"Unused", 7);
384 if (info->flags & DMAC_CHANNELS_TEI_CAPABLE)
385 chan->flags |= DMA_TEI_CAPABLE;
391 list_add(&info->list, ®istered_dmac_list);
401 for (i = 0; i < info->nr_channels; i++)
404 if (!(info->flags & DMAC_CHANNELS_CONFIGURED))
405 kfree(info->channels);
412 static int __init dma_api_init(
void)
415 return create_proc_read_entry(
"dma", 0, 0, dma_read_proc, 0)