blob: 6e3b58bd8795f4790223fa74b2c914377a862c08 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * arch/sh/drivers/dma/dma-sysfs.c
3 *
4 * sysfs interface for SH DMA API
5 *
6 * Copyright (C) 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/kernel.h>
13#include <linux/init.h>
14#include <linux/sysdev.h>
15#include <linux/module.h>
Tim Schmielau4e57b682005-10-30 15:03:48 -080016#include <linux/string.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <asm/dma.h>
18
19static struct sysdev_class dma_sysclass = {
20 set_kset_name("dma"),
21};
22
23EXPORT_SYMBOL(dma_sysclass);
24
25static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
26{
27 ssize_t len = 0;
28 int i;
29
30 for (i = 0; i < MAX_DMA_CHANNELS; i++) {
31 struct dma_info *info = get_dma_info(i);
32 struct dma_channel *channel = &info->channels[i];
33
34 len += sprintf(buf + len, "%2d: %14s %s\n",
35 channel->chan, info->name,
36 channel->dev_id);
37 }
38
39 return len;
40}
41
42static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL);
43
44static int __init dma_sysclass_init(void)
45{
46 int ret;
47
48 ret = sysdev_class_register(&dma_sysclass);
49 if (ret == 0)
50 sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
51
52 return ret;
53}
54
55postcore_initcall(dma_sysclass_init);
56
57static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
58{
59 struct dma_channel *channel = to_dma_channel(dev);
60 return sprintf(buf, "%s\n", channel->dev_id);
61}
62
63static ssize_t dma_store_dev_id(struct sys_device *dev,
64 const char *buf, size_t count)
65{
66 struct dma_channel *channel = to_dma_channel(dev);
67 strcpy(channel->dev_id, buf);
68 return count;
69}
70
71static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id);
72
73static ssize_t dma_store_config(struct sys_device *dev,
74 const char *buf, size_t count)
75{
76 struct dma_channel *channel = to_dma_channel(dev);
77 unsigned long config;
78
79 config = simple_strtoul(buf, NULL, 0);
80 dma_configure_channel(channel->chan, config);
81
82 return count;
83}
84
85static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config);
86
87static ssize_t dma_show_mode(struct sys_device *dev, char *buf)
88{
89 struct dma_channel *channel = to_dma_channel(dev);
90 return sprintf(buf, "0x%08x\n", channel->mode);
91}
92
93static ssize_t dma_store_mode(struct sys_device *dev,
94 const char *buf, size_t count)
95{
96 struct dma_channel *channel = to_dma_channel(dev);
97 channel->mode = simple_strtoul(buf, NULL, 0);
98 return count;
99}
100
101static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode);
102
103#define dma_ro_attr(field, fmt) \
104static ssize_t dma_show_##field(struct sys_device *dev, char *buf) \
105{ \
106 struct dma_channel *channel = to_dma_channel(dev); \
107 return sprintf(buf, fmt, channel->field); \
108} \
109static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL);
110
111dma_ro_attr(count, "0x%08x\n");
112dma_ro_attr(flags, "0x%08lx\n");
113
114int __init dma_create_sysfs_files(struct dma_channel *chan)
115{
116 struct sys_device *dev = &chan->dev;
117 int ret;
118
119 dev->id = chan->chan;
120 dev->cls = &dma_sysclass;
121
122 ret = sysdev_register(dev);
123 if (ret)
124 return ret;
125
126 sysdev_create_file(dev, &attr_dev_id);
127 sysdev_create_file(dev, &attr_count);
128 sysdev_create_file(dev, &attr_mode);
129 sysdev_create_file(dev, &attr_flags);
130 sysdev_create_file(dev, &attr_config);
131
132 return 0;
133}
134