]>
Commit | Line | Data |
---|---|---|
ff4a7481 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 LT |
2 | /* |
3 | * arch/sh/drivers/dma/dma-sysfs.c | |
4 | * | |
5 | * sysfs interface for SH DMA API | |
6 | * | |
4dfc119f | 7 | * Copyright (C) 2004 - 2006 Paul Mundt |
1da177e4 LT |
8 | */ |
9 | #include <linux/kernel.h> | |
10 | #include <linux/init.h> | |
0c43871b | 11 | #include <linux/stat.h> |
dc6876a2 | 12 | #include <linux/device.h> |
0d831770 | 13 | #include <linux/platform_device.h> |
0d831770 | 14 | #include <linux/err.h> |
4e57b681 | 15 | #include <linux/string.h> |
1da177e4 LT |
16 | #include <asm/dma.h> |
17 | ||
dc6876a2 | 18 | static struct bus_type dma_subsys = { |
af5ca3f4 | 19 | .name = "dma", |
dc6876a2 | 20 | .dev_name = "dma", |
1da177e4 | 21 | }; |
1da177e4 | 22 | |
dc6876a2 KS |
23 | static ssize_t dma_show_devices(struct device *dev, |
24 | struct device_attribute *attr, char *buf) | |
1da177e4 LT |
25 | { |
26 | ssize_t len = 0; | |
27 | int i; | |
28 | ||
e24cca19 | 29 | for (i = 0; i < 16; i++) { |
1da177e4 | 30 | struct dma_info *info = get_dma_info(i); |
4dfc119f PM |
31 | struct dma_channel *channel = get_dma_channel(i); |
32 | ||
33 | if (unlikely(!info) || !channel) | |
34 | continue; | |
1da177e4 LT |
35 | |
36 | len += sprintf(buf + len, "%2d: %14s %s\n", | |
37 | channel->chan, info->name, | |
38 | channel->dev_id); | |
39 | } | |
40 | ||
41 | return len; | |
42 | } | |
43 | ||
dc6876a2 | 44 | static DEVICE_ATTR(devices, S_IRUGO, dma_show_devices, NULL); |
1da177e4 | 45 | |
dc6876a2 | 46 | static int __init dma_subsys_init(void) |
1da177e4 LT |
47 | { |
48 | int ret; | |
49 | ||
dc6876a2 | 50 | ret = subsys_system_register(&dma_subsys, NULL); |
711fa809 PM |
51 | if (unlikely(ret)) |
52 | return ret; | |
1da177e4 | 53 | |
87c34ed3 | 54 | return device_create_file(dma_subsys.dev_root, &dev_attr_devices); |
1da177e4 | 55 | } |
dc6876a2 | 56 | postcore_initcall(dma_subsys_init); |
1da177e4 | 57 | |
dc6876a2 KS |
58 | static ssize_t dma_show_dev_id(struct device *dev, |
59 | struct device_attribute *attr, char *buf) | |
1da177e4 LT |
60 | { |
61 | struct dma_channel *channel = to_dma_channel(dev); | |
62 | return sprintf(buf, "%s\n", channel->dev_id); | |
63 | } | |
64 | ||
dc6876a2 KS |
65 | static ssize_t dma_store_dev_id(struct device *dev, |
66 | struct device_attribute *attr, | |
1da177e4 LT |
67 | const char *buf, size_t count) |
68 | { | |
69 | struct dma_channel *channel = to_dma_channel(dev); | |
70 | strcpy(channel->dev_id, buf); | |
71 | return count; | |
72 | } | |
73 | ||
dc6876a2 | 74 | static DEVICE_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); |
1da177e4 | 75 | |
dc6876a2 KS |
76 | static ssize_t dma_store_config(struct device *dev, |
77 | struct device_attribute *attr, | |
1da177e4 LT |
78 | const char *buf, size_t count) |
79 | { | |
80 | struct dma_channel *channel = to_dma_channel(dev); | |
81 | unsigned long config; | |
82 | ||
83 | config = simple_strtoul(buf, NULL, 0); | |
0d831770 | 84 | dma_configure_channel(channel->vchan, config); |
1da177e4 LT |
85 | |
86 | return count; | |
87 | } | |
88 | ||
dc6876a2 | 89 | static DEVICE_ATTR(config, S_IWUSR, NULL, dma_store_config); |
1da177e4 | 90 | |
dc6876a2 KS |
91 | static ssize_t dma_show_mode(struct device *dev, |
92 | struct device_attribute *attr, char *buf) | |
1da177e4 LT |
93 | { |
94 | struct dma_channel *channel = to_dma_channel(dev); | |
95 | return sprintf(buf, "0x%08x\n", channel->mode); | |
96 | } | |
97 | ||
dc6876a2 KS |
98 | static ssize_t dma_store_mode(struct device *dev, |
99 | struct device_attribute *attr, | |
1da177e4 LT |
100 | const char *buf, size_t count) |
101 | { | |
102 | struct dma_channel *channel = to_dma_channel(dev); | |
103 | channel->mode = simple_strtoul(buf, NULL, 0); | |
104 | return count; | |
105 | } | |
106 | ||
dc6876a2 | 107 | static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode); |
1da177e4 LT |
108 | |
109 | #define dma_ro_attr(field, fmt) \ | |
dc6876a2 KS |
110 | static ssize_t dma_show_##field(struct device *dev, \ |
111 | struct device_attribute *attr, char *buf)\ | |
1da177e4 LT |
112 | { \ |
113 | struct dma_channel *channel = to_dma_channel(dev); \ | |
114 | return sprintf(buf, fmt, channel->field); \ | |
115 | } \ | |
dc6876a2 | 116 | static DEVICE_ATTR(field, S_IRUGO, dma_show_##field, NULL); |
1da177e4 LT |
117 | |
118 | dma_ro_attr(count, "0x%08x\n"); | |
119 | dma_ro_attr(flags, "0x%08lx\n"); | |
120 | ||
0d831770 | 121 | int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) |
1da177e4 | 122 | { |
dc6876a2 | 123 | struct device *dev = &chan->dev; |
0d831770 | 124 | char name[16]; |
1da177e4 LT |
125 | int ret; |
126 | ||
0d831770 | 127 | dev->id = chan->vchan; |
dc6876a2 | 128 | dev->bus = &dma_subsys; |
1da177e4 | 129 | |
dc6876a2 | 130 | ret = device_register(dev); |
1da177e4 LT |
131 | if (ret) |
132 | return ret; | |
133 | ||
dc6876a2 KS |
134 | ret |= device_create_file(dev, &dev_attr_dev_id); |
135 | ret |= device_create_file(dev, &dev_attr_count); | |
136 | ret |= device_create_file(dev, &dev_attr_mode); | |
137 | ret |= device_create_file(dev, &dev_attr_flags); | |
138 | ret |= device_create_file(dev, &dev_attr_config); | |
4dfc119f PM |
139 | |
140 | if (unlikely(ret)) { | |
141 | dev_err(&info->pdev->dev, "Failed creating attrs\n"); | |
142 | return ret; | |
143 | } | |
1da177e4 | 144 | |
0d831770 PM |
145 | snprintf(name, sizeof(name), "dma%d", chan->chan); |
146 | return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); | |
147 | } | |
148 | ||
149 | void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info) | |
150 | { | |
dc6876a2 | 151 | struct device *dev = &chan->dev; |
0d831770 PM |
152 | char name[16]; |
153 | ||
dc6876a2 KS |
154 | device_remove_file(dev, &dev_attr_dev_id); |
155 | device_remove_file(dev, &dev_attr_count); | |
156 | device_remove_file(dev, &dev_attr_mode); | |
157 | device_remove_file(dev, &dev_attr_flags); | |
158 | device_remove_file(dev, &dev_attr_config); | |
0d831770 PM |
159 | |
160 | snprintf(name, sizeof(name), "dma%d", chan->chan); | |
161 | sysfs_remove_link(&info->pdev->dev.kobj, name); | |
162 | ||
dc6876a2 | 163 | device_unregister(dev); |
1da177e4 | 164 | } |