aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2012-01-22 16:31:15 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-22 16:31:15 -0500
commite9c688a3272fd4b659228f3880de8109a94540e2 (patch)
treec295a2db56a079a0f37703f186b44e57e1453527
parentdcd6c92267155e70a94b3927bce681ce74b80d1f (diff)
driver core: remove drivers/base/sys.c and include/linux/sysdev.h
Now that all users of 'struct sysdev' are removed from the kernel, we can safely remove the .h and .c files for this code, to ensure that no one accidentally starts to use it again. Many thanks for Kay who did all the hard work here on making this happen. Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/sys.c383
-rw-r--r--include/linux/sysdev.h164
3 files changed, 1 insertions, 548 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 2c8272dd93c4..610f9997a403 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,6 +1,6 @@
1# Makefile for the Linux device tree 1# Makefile for the Linux device tree
2 2
3obj-y := core.o sys.o bus.o dd.o syscore.o \ 3obj-y := core.o bus.o dd.o syscore.o \
4 driver.o class.o platform.o \ 4 driver.o class.o platform.o \
5 cpu.o firmware.o init.o map.o devres.o \ 5 cpu.o firmware.o init.o map.o devres.o \
6 attribute_container.o transport_class.o \ 6 attribute_container.o transport_class.o \
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
deleted file mode 100644
index 409f5ce78829..000000000000
--- a/drivers/base/sys.c
+++ /dev/null
@@ -1,383 +0,0 @@
1/*
2 * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
3 *
4 * Copyright (c) 2002-3 Patrick Mochel
5 * 2002-3 Open Source Development Lab
6 *
7 * This file is released under the GPLv2
8 *
9 * This exports a 'system' bus type.
10 * By default, a 'sys' bus gets added to the root of the system. There will
11 * always be core system devices. Devices can use sysdev_register() to
12 * add themselves as children of the system bus.
13 */
14
15#include <linux/sysdev.h>
16#include <linux/err.h>
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/string.h>
21#include <linux/pm.h>
22#include <linux/device.h>
23#include <linux/mutex.h>
24#include <linux/interrupt.h>
25
26#include "base.h"
27
28#define to_sysdev(k) container_of(k, struct sys_device, kobj)
29#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr)
30
31
32static ssize_t
33sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
34{
35 struct sys_device *sysdev = to_sysdev(kobj);
36 struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
37
38 if (sysdev_attr->show)
39 return sysdev_attr->show(sysdev, sysdev_attr, buffer);
40 return -EIO;
41}
42
43
44static ssize_t
45sysdev_store(struct kobject *kobj, struct attribute *attr,
46 const char *buffer, size_t count)
47{
48 struct sys_device *sysdev = to_sysdev(kobj);
49 struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
50
51 if (sysdev_attr->store)
52 return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
53 return -EIO;
54}
55
56static const struct sysfs_ops sysfs_ops = {
57 .show = sysdev_show,
58 .store = sysdev_store,
59};
60
61static struct kobj_type ktype_sysdev = {
62 .sysfs_ops = &sysfs_ops,
63};
64
65
66int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
67{
68 return sysfs_create_file(&s->kobj, &a->attr);
69}
70
71
72void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
73{
74 sysfs_remove_file(&s->kobj, &a->attr);
75}
76
77EXPORT_SYMBOL_GPL(sysdev_create_file);
78EXPORT_SYMBOL_GPL(sysdev_remove_file);
79
80#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj)
81#define to_sysdev_class_attr(a) container_of(a, \
82 struct sysdev_class_attribute, attr)
83
84static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
85 char *buffer)
86{
87 struct sysdev_class *class = to_sysdev_class(kobj);
88 struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
89
90 if (class_attr->show)
91 return class_attr->show(class, class_attr, buffer);
92 return -EIO;
93}
94
95static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
96 const char *buffer, size_t count)
97{
98 struct sysdev_class *class = to_sysdev_class(kobj);
99 struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
100
101 if (class_attr->store)
102 return class_attr->store(class, class_attr, buffer, count);
103 return -EIO;
104}
105
106static const struct sysfs_ops sysfs_class_ops = {
107 .show = sysdev_class_show,
108 .store = sysdev_class_store,
109};
110
111static struct kobj_type ktype_sysdev_class = {
112 .sysfs_ops = &sysfs_class_ops,
113};
114
115int sysdev_class_create_file(struct sysdev_class *c,
116 struct sysdev_class_attribute *a)
117{
118 return sysfs_create_file(&c->kset.kobj, &a->attr);
119}
120EXPORT_SYMBOL_GPL(sysdev_class_create_file);
121
122void sysdev_class_remove_file(struct sysdev_class *c,
123 struct sysdev_class_attribute *a)
124{
125 sysfs_remove_file(&c->kset.kobj, &a->attr);
126}
127EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
128
129extern struct kset *system_kset;
130
131int sysdev_class_register(struct sysdev_class *cls)
132{
133 int retval;
134
135 pr_debug("Registering sysdev class '%s'\n", cls->name);
136
137 INIT_LIST_HEAD(&cls->drivers);
138 memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
139 cls->kset.kobj.parent = &system_kset->kobj;
140 cls->kset.kobj.ktype = &ktype_sysdev_class;
141 cls->kset.kobj.kset = system_kset;
142
143 retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name);
144 if (retval)
145 return retval;
146
147 retval = kset_register(&cls->kset);
148 if (!retval && cls->attrs)
149 retval = sysfs_create_files(&cls->kset.kobj,
150 (const struct attribute **)cls->attrs);
151 return retval;
152}
153
154void sysdev_class_unregister(struct sysdev_class *cls)
155{
156 pr_debug("Unregistering sysdev class '%s'\n",
157 kobject_name(&cls->kset.kobj));
158 if (cls->attrs)
159 sysfs_remove_files(&cls->kset.kobj,
160 (const struct attribute **)cls->attrs);
161 kset_unregister(&cls->kset);
162}
163
164EXPORT_SYMBOL_GPL(sysdev_class_register);
165EXPORT_SYMBOL_GPL(sysdev_class_unregister);
166
167static DEFINE_MUTEX(sysdev_drivers_lock);
168
169/*
170 * @dev != NULL means that we're unwinding because some drv->add()
171 * failed for some reason. You need to grab sysdev_drivers_lock before
172 * calling this.
173 */
174static void __sysdev_driver_remove(struct sysdev_class *cls,
175 struct sysdev_driver *drv,
176 struct sys_device *from_dev)
177{
178 struct sys_device *dev = from_dev;
179
180 list_del_init(&drv->entry);
181 if (!cls)
182 return;
183
184 if (!drv->remove)
185 goto kset_put;
186
187 if (dev)
188 list_for_each_entry_continue_reverse(dev, &cls->kset.list,
189 kobj.entry)
190 drv->remove(dev);
191 else
192 list_for_each_entry(dev, &cls->kset.list, kobj.entry)
193 drv->remove(dev);
194
195kset_put:
196 kset_put(&cls->kset);
197}
198
199/**
200 * sysdev_driver_register - Register auxiliary driver
201 * @cls: Device class driver belongs to.
202 * @drv: Driver.
203 *
204 * @drv is inserted into @cls->drivers to be
205 * called on each operation on devices of that class. The refcount
206 * of @cls is incremented.
207 */
208int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
209{
210 struct sys_device *dev = NULL;
211 int err = 0;
212
213 if (!cls) {
214 WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n",
215 __func__);
216 return -EINVAL;
217 }
218
219 /* Check whether this driver has already been added to a class. */
220 if (drv->entry.next && !list_empty(&drv->entry))
221 WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already"
222 " been registered to a class, something is wrong, but "
223 "will forge on!\n", cls->name, drv);
224
225 mutex_lock(&sysdev_drivers_lock);
226 if (cls && kset_get(&cls->kset)) {
227 list_add_tail(&drv->entry, &cls->drivers);
228
229 /* If devices of this class already exist, tell the driver */
230 if (drv->add) {
231 list_for_each_entry(dev, &cls->kset.list, kobj.entry) {
232 err = drv->add(dev);
233 if (err)
234 goto unwind;
235 }
236 }
237 } else {
238 err = -EINVAL;
239 WARN(1, KERN_ERR "%s: invalid device class\n", __func__);
240 }
241
242 goto unlock;
243
244unwind:
245 __sysdev_driver_remove(cls, drv, dev);
246
247unlock:
248 mutex_unlock(&sysdev_drivers_lock);
249 return err;
250}
251
252/**
253 * sysdev_driver_unregister - Remove an auxiliary driver.
254 * @cls: Class driver belongs to.
255 * @drv: Driver.
256 */
257void sysdev_driver_unregister(struct sysdev_class *cls,
258 struct sysdev_driver *drv)
259{
260 mutex_lock(&sysdev_drivers_lock);
261 __sysdev_driver_remove(cls, drv, NULL);
262 mutex_unlock(&sysdev_drivers_lock);
263}
264EXPORT_SYMBOL_GPL(sysdev_driver_register);
265EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
266
267/**
268 * sysdev_register - add a system device to the tree
269 * @sysdev: device in question
270 *
271 */
272int sysdev_register(struct sys_device *sysdev)
273{
274 int error;
275 struct sysdev_class *cls = sysdev->cls;
276
277 if (!cls)
278 return -EINVAL;
279
280 pr_debug("Registering sys device of class '%s'\n",
281 kobject_name(&cls->kset.kobj));
282
283 /* initialize the kobject to 0, in case it had previously been used */
284 memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
285
286 /* Make sure the kset is set */
287 sysdev->kobj.kset = &cls->kset;
288
289 /* Register the object */
290 error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL,
291 "%s%d", kobject_name(&cls->kset.kobj),
292 sysdev->id);
293
294 if (!error) {
295 struct sysdev_driver *drv;
296
297 pr_debug("Registering sys device '%s'\n",
298 kobject_name(&sysdev->kobj));
299
300 mutex_lock(&sysdev_drivers_lock);
301 /* Generic notification is implicit, because it's that
302 * code that should have called us.
303 */
304
305 /* Notify class auxiliary drivers */
306 list_for_each_entry(drv, &cls->drivers, entry) {
307 if (drv->add)
308 drv->add(sysdev);
309 }
310 mutex_unlock(&sysdev_drivers_lock);
311 kobject_uevent(&sysdev->kobj, KOBJ_ADD);
312 }
313
314 return error;
315}
316
317void sysdev_unregister(struct sys_device *sysdev)
318{
319 struct sysdev_driver *drv;
320
321 mutex_lock(&sysdev_drivers_lock);
322 list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
323 if (drv->remove)
324 drv->remove(sysdev);
325 }
326 mutex_unlock(&sysdev_drivers_lock);
327
328 kobject_put(&sysdev->kobj);
329}
330
331EXPORT_SYMBOL_GPL(sysdev_register);
332EXPORT_SYMBOL_GPL(sysdev_unregister);
333
334#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
335
336ssize_t sysdev_store_ulong(struct sys_device *sysdev,
337 struct sysdev_attribute *attr,
338 const char *buf, size_t size)
339{
340 struct sysdev_ext_attribute *ea = to_ext_attr(attr);
341 char *end;
342 unsigned long new = simple_strtoul(buf, &end, 0);
343 if (end == buf)
344 return -EINVAL;
345 *(unsigned long *)(ea->var) = new;
346 /* Always return full write size even if we didn't consume all */
347 return size;
348}
349EXPORT_SYMBOL_GPL(sysdev_store_ulong);
350
351ssize_t sysdev_show_ulong(struct sys_device *sysdev,
352 struct sysdev_attribute *attr,
353 char *buf)
354{
355 struct sysdev_ext_attribute *ea = to_ext_attr(attr);
356 return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
357}
358EXPORT_SYMBOL_GPL(sysdev_show_ulong);
359
360ssize_t sysdev_store_int(struct sys_device *sysdev,
361 struct sysdev_attribute *attr,
362 const char *buf, size_t size)
363{
364 struct sysdev_ext_attribute *ea = to_ext_attr(attr);
365 char *end;
366 long new = simple_strtol(buf, &end, 0);
367 if (end == buf || new > INT_MAX || new < INT_MIN)
368 return -EINVAL;
369 *(int *)(ea->var) = new;
370 /* Always return full write size even if we didn't consume all */
371 return size;
372}
373EXPORT_SYMBOL_GPL(sysdev_store_int);
374
375ssize_t sysdev_show_int(struct sys_device *sysdev,
376 struct sysdev_attribute *attr,
377 char *buf)
378{
379 struct sysdev_ext_attribute *ea = to_ext_attr(attr);
380 return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
381}
382EXPORT_SYMBOL_GPL(sysdev_show_int);
383
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
deleted file mode 100644
index 20f63d3e6144..000000000000
--- a/include/linux/sysdev.h
+++ /dev/null
@@ -1,164 +0,0 @@
1/**
2 * System devices follow a slightly different driver model.
3 * They don't need to do dynammic driver binding, can't be probed,
4 * and don't reside on any type of peripheral bus.
5 * So, we represent and treat them a little differently.
6 *
7 * We still have a notion of a driver for a system device, because we still
8 * want to perform basic operations on these devices.
9 *
10 * We also support auxiliary drivers binding to devices of a certain class.
11 *
12 * This allows configurable drivers to register themselves for devices of
13 * a certain type. And, it allows class definitions to reside in generic
14 * code while arch-specific code can register specific drivers.
15 *
16 * Auxiliary drivers registered with a NULL cls are registered as drivers
17 * for all system devices, and get notification calls for each device.
18 */
19
20
21#ifndef _SYSDEV_H_
22#define _SYSDEV_H_
23
24#include <linux/kobject.h>
25#include <linux/pm.h>
26
27
28struct sys_device;
29struct sysdev_class_attribute;
30
31struct sysdev_class {
32 const char *name;
33 struct list_head drivers;
34 struct sysdev_class_attribute **attrs;
35 struct kset kset;
36};
37
38struct sysdev_class_attribute {
39 struct attribute attr;
40 ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *,
41 char *);
42 ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *,
43 const char *, size_t);
44};
45
46#define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \
47{ \
48 .attr = {.name = __stringify(_name), .mode = _mode }, \
49 .show = _show, \
50 .store = _store, \
51}
52
53#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \
54 struct sysdev_class_attribute attr_##_name = \
55 _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)
56
57
58extern int sysdev_class_register(struct sysdev_class *);
59extern void sysdev_class_unregister(struct sysdev_class *);
60
61extern int sysdev_class_create_file(struct sysdev_class *,
62 struct sysdev_class_attribute *);
63extern void sysdev_class_remove_file(struct sysdev_class *,
64 struct sysdev_class_attribute *);
65/**
66 * Auxiliary system device drivers.
67 */
68
69struct sysdev_driver {
70 struct list_head entry;
71 int (*add)(struct sys_device *);
72 int (*remove)(struct sys_device *);
73};
74
75
76extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
77extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);
78
79
80/**
81 * sys_devices can be simplified a lot from regular devices, because they're
82 * simply not as versatile.
83 */
84
85struct sys_device {
86 u32 id;
87 struct sysdev_class * cls;
88 struct kobject kobj;
89};
90
91extern int sysdev_register(struct sys_device *);
92extern void sysdev_unregister(struct sys_device *);
93
94
95struct sysdev_attribute {
96 struct attribute attr;
97 ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *);
98 ssize_t (*store)(struct sys_device *, struct sysdev_attribute *,
99 const char *, size_t);
100};
101
102
103#define _SYSDEV_ATTR(_name, _mode, _show, _store) \
104{ \
105 .attr = { .name = __stringify(_name), .mode = _mode }, \
106 .show = _show, \
107 .store = _store, \
108}
109
110#define SYSDEV_ATTR(_name, _mode, _show, _store) \
111 struct sysdev_attribute attr_##_name = \
112 _SYSDEV_ATTR(_name, _mode, _show, _store);
113
114extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
115extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
116
117/* Create/remove NULL terminated attribute list */
118static inline int
119sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a)
120{
121 return sysfs_create_files(&d->kobj, (const struct attribute **)a);
122}
123
124static inline void
125sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a)
126{
127 return sysfs_remove_files(&d->kobj, (const struct attribute **)a);
128}
129
130struct sysdev_ext_attribute {
131 struct sysdev_attribute attr;
132 void *var;
133};
134
135/*
136 * Support for simple variable sysdev attributes.
137 * The pointer to the variable is stored in a sysdev_ext_attribute
138 */
139
140/* Add more types as needed */
141
142extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *,
143 char *);
144extern ssize_t sysdev_store_ulong(struct sys_device *,
145 struct sysdev_attribute *, const char *, size_t);
146extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *,
147 char *);
148extern ssize_t sysdev_store_int(struct sys_device *,
149 struct sysdev_attribute *, const char *, size_t);
150
151#define _SYSDEV_ULONG_ATTR(_name, _mode, _var) \
152 { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \
153 &(_var) }
154#define SYSDEV_ULONG_ATTR(_name, _mode, _var) \
155 struct sysdev_ext_attribute attr_##_name = \
156 _SYSDEV_ULONG_ATTR(_name, _mode, _var);
157#define _SYSDEV_INT_ATTR(_name, _mode, _var) \
158 { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \
159 &(_var) }
160#define SYSDEV_INT_ATTR(_name, _mode, _var) \
161 struct sysdev_ext_attribute attr_##_name = \
162 _SYSDEV_INT_ATTR(_name, _mode, _var);
163
164#endif /* _SYSDEV_H_ */