[PATCH] DVB: Update documentation and credits
[linux-2.6/history.git] / drivers / base / class.c
blob4858ba62428c13128e30fd895c612242f7dead51
1 /*
2 * class.c - basic device class management
4 * Copyright (c) 2002-3 Patrick Mochel
5 * Copyright (c) 2002-3 Open Source Development Labs
6 * Copyright (c) 2003 Greg Kroah-Hartman
7 * Copyright (c) 2003 IBM Corp.
8 *
9 * This file is released under the GPLv2
13 #undef DEBUG
15 #include <linux/device.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/string.h>
19 #include "base.h"
21 #define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr)
22 #define to_class(obj) container_of(obj,struct class,subsys.kset.kobj)
24 static ssize_t
25 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
27 struct class_attribute * class_attr = to_class_attr(attr);
28 struct class * dc = to_class(kobj);
29 ssize_t ret = 0;
31 if (class_attr->show)
32 ret = class_attr->show(dc,buf);
33 return ret;
36 static ssize_t
37 class_attr_store(struct kobject * kobj, struct attribute * attr,
38 const char * buf, size_t count)
40 struct class_attribute * class_attr = to_class_attr(attr);
41 struct class * dc = to_class(kobj);
42 ssize_t ret = 0;
44 if (class_attr->store)
45 ret = class_attr->store(dc,buf,count);
46 return ret;
49 static struct sysfs_ops class_sysfs_ops = {
50 .show = class_attr_show,
51 .store = class_attr_store,
54 static struct kobj_type ktype_class = {
55 .sysfs_ops = &class_sysfs_ops,
58 /* Hotplug events for classes go to the class_obj subsys */
59 static decl_subsys(class,&ktype_class,NULL);
62 int class_create_file(struct class * cls, const struct class_attribute * attr)
64 int error;
65 if (cls) {
66 error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
67 } else
68 error = -EINVAL;
69 return error;
72 void class_remove_file(struct class * cls, const struct class_attribute * attr)
74 if (cls)
75 sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
78 struct class * class_get(struct class * cls)
80 if (cls)
81 return container_of(subsys_get(&cls->subsys),struct class,subsys);
82 return NULL;
85 void class_put(struct class * cls)
87 subsys_put(&cls->subsys);
90 int class_register(struct class * cls)
92 pr_debug("device class '%s': registering\n",cls->name);
94 INIT_LIST_HEAD(&cls->children);
95 INIT_LIST_HEAD(&cls->interfaces);
96 kobject_set_name(&cls->subsys.kset.kobj,cls->name);
97 subsys_set_kset(cls,class_subsys);
98 subsystem_register(&cls->subsys);
100 return 0;
103 void class_unregister(struct class * cls)
105 pr_debug("device class '%s': unregistering\n",cls->name);
106 subsystem_unregister(&cls->subsys);
109 /* Class Device Stuff */
111 int class_device_create_file(struct class_device * class_dev,
112 const struct class_device_attribute * attr)
114 int error = -EINVAL;
115 if (class_dev)
116 error = sysfs_create_file(&class_dev->kobj, &attr->attr);
117 return error;
120 void class_device_remove_file(struct class_device * class_dev,
121 const struct class_device_attribute * attr)
123 if (class_dev)
124 sysfs_remove_file(&class_dev->kobj, &attr->attr);
127 static int class_device_dev_link(struct class_device * class_dev)
129 if (class_dev->dev)
130 return sysfs_create_link(&class_dev->kobj,
131 &class_dev->dev->kobj, "device");
132 return 0;
135 static void class_device_dev_unlink(struct class_device * class_dev)
137 if (class_dev->dev)
138 sysfs_remove_link(&class_dev->kobj, "device");
141 static int class_device_driver_link(struct class_device * class_dev)
143 if ((class_dev->dev) && (class_dev->dev->driver))
144 return sysfs_create_link(&class_dev->kobj,
145 &class_dev->dev->driver->kobj, "driver");
146 return 0;
149 static void class_device_driver_unlink(struct class_device * class_dev)
151 if ((class_dev->dev) && (class_dev->dev->driver))
152 sysfs_remove_link(&class_dev->kobj, "driver");
156 static ssize_t
157 class_device_attr_show(struct kobject * kobj, struct attribute * attr,
158 char * buf)
160 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
161 struct class_device * cd = to_class_dev(kobj);
162 ssize_t ret = 0;
164 if (class_dev_attr->show)
165 ret = class_dev_attr->show(cd,buf);
166 return ret;
169 static ssize_t
170 class_device_attr_store(struct kobject * kobj, struct attribute * attr,
171 const char * buf, size_t count)
173 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
174 struct class_device * cd = to_class_dev(kobj);
175 ssize_t ret = 0;
177 if (class_dev_attr->store)
178 ret = class_dev_attr->store(cd,buf,count);
179 return ret;
182 static struct sysfs_ops class_dev_sysfs_ops = {
183 .show = class_device_attr_show,
184 .store = class_device_attr_store,
187 static void class_dev_release(struct kobject * kobj)
189 struct class_device *cd = to_class_dev(kobj);
190 struct class * cls = cd->class;
192 pr_debug("device class '%s': release.\n",cd->class_id);
194 if (cls->release)
195 cls->release(cd);
196 else {
197 printk(KERN_ERR "Device class '%s' does not have a release() function, "
198 "it is broken and must be fixed.\n",
199 cd->class_id);
200 WARN_ON(1);
204 static struct kobj_type ktype_class_device = {
205 .sysfs_ops = &class_dev_sysfs_ops,
206 .release = class_dev_release,
209 static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
211 struct kobj_type *ktype = get_ktype(kobj);
213 if (ktype == &ktype_class_device) {
214 struct class_device *class_dev = to_class_dev(kobj);
215 if (class_dev->class)
216 return 1;
218 return 0;
221 static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
223 struct class_device *class_dev = to_class_dev(kobj);
225 return class_dev->class->name;
228 static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
229 int num_envp, char *buffer, int buffer_size)
231 struct class_device *class_dev = to_class_dev(kobj);
232 int retval = 0;
234 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
235 if (class_dev->class->hotplug) {
236 /* have the bus specific function add its stuff */
237 retval = class_dev->class->hotplug (class_dev, envp, num_envp,
238 buffer, buffer_size);
239 if (retval) {
240 pr_debug ("%s - hotplug() returned %d\n",
241 __FUNCTION__, retval);
245 return retval;
248 static struct kset_hotplug_ops class_hotplug_ops = {
249 .filter = class_hotplug_filter,
250 .name = class_hotplug_name,
251 .hotplug = class_hotplug,
254 static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
256 void class_device_initialize(struct class_device *class_dev)
258 kobj_set_kset_s(class_dev, class_obj_subsys);
259 kobject_init(&class_dev->kobj);
260 INIT_LIST_HEAD(&class_dev->node);
263 int class_device_add(struct class_device *class_dev)
265 struct class * parent;
266 struct class_interface * class_intf;
267 struct list_head * entry;
268 int error;
270 class_dev = class_device_get(class_dev);
271 if (!class_dev || !strlen(class_dev->class_id))
272 return -EINVAL;
274 parent = class_get(class_dev->class);
276 pr_debug("CLASS: registering class device: ID = '%s'\n",
277 class_dev->class_id);
279 /* first, register with generic layer. */
280 kobject_set_name(&class_dev->kobj, class_dev->class_id);
281 if (parent)
282 class_dev->kobj.parent = &parent->subsys.kset.kobj;
284 if ((error = kobject_add(&class_dev->kobj)))
285 goto register_done;
287 /* now take care of our own registration */
288 if (parent) {
289 down_write(&parent->subsys.rwsem);
290 list_add_tail(&class_dev->node, &parent->children);
291 list_for_each(entry, &parent->interfaces) {
292 class_intf = container_of(entry, struct class_interface, node);
293 if (class_intf->add)
294 class_intf->add(class_dev);
296 up_write(&parent->subsys.rwsem);
299 class_device_dev_link(class_dev);
300 class_device_driver_link(class_dev);
302 register_done:
303 if (error && parent)
304 class_put(parent);
305 class_device_put(class_dev);
306 return error;
309 int class_device_register(struct class_device *class_dev)
311 class_device_initialize(class_dev);
312 return class_device_add(class_dev);
315 void class_device_del(struct class_device *class_dev)
317 struct class * parent = class_dev->class;
318 struct class_interface * class_intf;
319 struct list_head * entry;
321 if (parent) {
322 down_write(&parent->subsys.rwsem);
323 list_del_init(&class_dev->node);
324 list_for_each(entry, &parent->interfaces) {
325 class_intf = container_of(entry, struct class_interface, node);
326 if (class_intf->remove)
327 class_intf->remove(class_dev);
329 up_write(&parent->subsys.rwsem);
332 class_device_dev_unlink(class_dev);
333 class_device_driver_unlink(class_dev);
335 kobject_del(&class_dev->kobj);
337 if (parent)
338 class_put(parent);
341 void class_device_unregister(struct class_device *class_dev)
343 pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
344 class_dev->class_id);
345 class_device_del(class_dev);
346 class_device_put(class_dev);
349 int class_device_rename(struct class_device *class_dev, char *new_name)
351 class_dev = class_device_get(class_dev);
352 if (!class_dev)
353 return -EINVAL;
355 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
356 new_name);
358 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
360 kobject_rename(&class_dev->kobj, new_name);
362 class_device_put(class_dev);
364 return 0;
367 struct class_device * class_device_get(struct class_device *class_dev)
369 if (class_dev)
370 return to_class_dev(kobject_get(&class_dev->kobj));
371 return NULL;
374 void class_device_put(struct class_device *class_dev)
376 kobject_put(&class_dev->kobj);
380 int class_interface_register(struct class_interface *class_intf)
382 struct class * parent;
383 struct class_device * class_dev;
384 struct list_head * entry;
386 if (!class_intf || !class_intf->class)
387 return -ENODEV;
389 parent = class_get(class_intf->class);
390 if (!parent)
391 return -EINVAL;
393 down_write(&parent->subsys.rwsem);
394 list_add_tail(&class_intf->node, &parent->interfaces);
396 if (class_intf->add) {
397 list_for_each(entry, &parent->children) {
398 class_dev = container_of(entry, struct class_device, node);
399 class_intf->add(class_dev);
402 up_write(&parent->subsys.rwsem);
404 return 0;
407 void class_interface_unregister(struct class_interface *class_intf)
409 struct class * parent = class_intf->class;
410 struct list_head * entry;
412 if (!parent)
413 return;
415 down_write(&parent->subsys.rwsem);
416 list_del_init(&class_intf->node);
418 if (class_intf->remove) {
419 list_for_each(entry, &parent->children) {
420 struct class_device *class_dev = container_of(entry, struct class_device, node);
421 class_intf->remove(class_dev);
424 up_write(&parent->subsys.rwsem);
426 class_put(parent);
431 int __init classes_init(void)
433 int retval;
435 retval = subsystem_register(&class_subsys);
436 if (retval)
437 return retval;
439 /* ick, this is ugly, the things we go through to keep from showing up
440 * in sysfs... */
441 subsystem_init(&class_obj_subsys);
442 if (!class_obj_subsys.kset.subsys)
443 class_obj_subsys.kset.subsys = &class_obj_subsys;
444 return 0;
447 EXPORT_SYMBOL(class_create_file);
448 EXPORT_SYMBOL(class_remove_file);
449 EXPORT_SYMBOL(class_register);
450 EXPORT_SYMBOL(class_unregister);
451 EXPORT_SYMBOL(class_get);
452 EXPORT_SYMBOL(class_put);
454 EXPORT_SYMBOL(class_device_register);
455 EXPORT_SYMBOL(class_device_unregister);
456 EXPORT_SYMBOL(class_device_initialize);
457 EXPORT_SYMBOL(class_device_add);
458 EXPORT_SYMBOL(class_device_del);
459 EXPORT_SYMBOL(class_device_get);
460 EXPORT_SYMBOL(class_device_put);
461 EXPORT_SYMBOL(class_device_create_file);
462 EXPORT_SYMBOL(class_device_remove_file);
464 EXPORT_SYMBOL(class_interface_register);
465 EXPORT_SYMBOL(class_interface_unregister);