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-2004 Greg Kroah-Hartman
7 * Copyright (c) 2003-2004 IBM Corp.
9 * This file is released under the GPLv2
13 #include <linux/config.h>
14 #include <linux/device.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/string.h>
20 #define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr)
21 #define to_class(obj) container_of(obj,struct class,subsys.kset.kobj)
24 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
26 struct class_attribute * class_attr = to_class_attr(attr);
27 struct class * dc = to_class(kobj);
31 ret = class_attr->show(dc,buf);
36 class_attr_store(struct kobject * kobj, struct attribute * attr,
37 const char * buf, size_t count)
39 struct class_attribute * class_attr = to_class_attr(attr);
40 struct class * dc = to_class(kobj);
43 if (class_attr->store)
44 ret = class_attr->store(dc,buf,count);
48 static void class_release(struct kobject * kobj)
50 struct class *class = to_class(kobj);
52 pr_debug("class '%s': release.\n", class->name);
54 if (class->class_release)
55 class->class_release(class);
57 pr_debug("class '%s' does not have a release() function, "
58 "be careful\n", class->name);
61 static struct sysfs_ops class_sysfs_ops = {
62 .show = class_attr_show,
63 .store = class_attr_store,
66 static struct kobj_type ktype_class = {
67 .sysfs_ops = &class_sysfs_ops,
68 .release = class_release,
71 /* Hotplug events for classes go to the class_obj subsys */
72 static decl_subsys(class,&ktype_class,NULL);
75 int class_create_file(struct class * cls, const struct class_attribute * attr)
79 error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
85 void class_remove_file(struct class * cls, const struct class_attribute * attr)
88 sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
91 struct class * class_get(struct class * cls)
94 return container_of(subsys_get(&cls->subsys),struct class,subsys);
98 void class_put(struct class * cls)
100 subsys_put(&cls->subsys);
103 int class_register(struct class * cls)
107 pr_debug("device class '%s': registering\n",cls->name);
109 INIT_LIST_HEAD(&cls->children);
110 INIT_LIST_HEAD(&cls->interfaces);
111 error = kobject_set_name(&cls->subsys.kset.kobj,cls->name);
115 subsys_set_kset(cls,class_subsys);
117 error = subsystem_register(&cls->subsys);
124 void class_unregister(struct class * cls)
126 pr_debug("device class '%s': unregistering\n",cls->name);
127 subsystem_unregister(&cls->subsys);
130 /* Class Device Stuff */
132 int class_device_create_file(struct class_device * class_dev,
133 const struct class_device_attribute * attr)
137 error = sysfs_create_file(&class_dev->kobj, &attr->attr);
141 void class_device_remove_file(struct class_device * class_dev,
142 const struct class_device_attribute * attr)
145 sysfs_remove_file(&class_dev->kobj, &attr->attr);
148 static int class_device_dev_link(struct class_device * class_dev)
151 return sysfs_create_link(&class_dev->kobj,
152 &class_dev->dev->kobj, "device");
156 static void class_device_dev_unlink(struct class_device * class_dev)
158 sysfs_remove_link(&class_dev->kobj, "device");
161 static int class_device_driver_link(struct class_device * class_dev)
163 if ((class_dev->dev) && (class_dev->dev->driver))
164 return sysfs_create_link(&class_dev->kobj,
165 &class_dev->dev->driver->kobj, "driver");
169 static void class_device_driver_unlink(struct class_device * class_dev)
171 sysfs_remove_link(&class_dev->kobj, "driver");
176 class_device_attr_show(struct kobject * kobj, struct attribute * attr,
179 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
180 struct class_device * cd = to_class_dev(kobj);
183 if (class_dev_attr->show)
184 ret = class_dev_attr->show(cd,buf);
189 class_device_attr_store(struct kobject * kobj, struct attribute * attr,
190 const char * buf, size_t count)
192 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
193 struct class_device * cd = to_class_dev(kobj);
196 if (class_dev_attr->store)
197 ret = class_dev_attr->store(cd,buf,count);
201 static struct sysfs_ops class_dev_sysfs_ops = {
202 .show = class_device_attr_show,
203 .store = class_device_attr_store,
206 static void class_dev_release(struct kobject * kobj)
208 struct class_device *cd = to_class_dev(kobj);
209 struct class * cls = cd->class;
211 pr_debug("device class '%s': release.\n",cd->class_id);
216 printk(KERN_ERR "Device class '%s' does not have a release() function, "
217 "it is broken and must be fixed.\n",
223 static struct kobj_type ktype_class_device = {
224 .sysfs_ops = &class_dev_sysfs_ops,
225 .release = class_dev_release,
228 static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
230 struct kobj_type *ktype = get_ktype(kobj);
232 if (ktype == &ktype_class_device) {
233 struct class_device *class_dev = to_class_dev(kobj);
234 if (class_dev->class)
240 static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
242 struct class_device *class_dev = to_class_dev(kobj);
244 return class_dev->class->name;
247 static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
248 int num_envp, char *buffer, int buffer_size)
250 struct class_device *class_dev = to_class_dev(kobj);
253 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
254 if (class_dev->class->hotplug) {
255 /* have the bus specific function add its stuff */
256 retval = class_dev->class->hotplug (class_dev, envp, num_envp,
257 buffer, buffer_size);
259 pr_debug ("%s - hotplug() returned %d\n",
260 __FUNCTION__, retval);
267 static struct kset_hotplug_ops class_hotplug_ops = {
268 .filter = class_hotplug_filter,
269 .name = class_hotplug_name,
270 .hotplug = class_hotplug,
273 static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
275 void class_device_initialize(struct class_device *class_dev)
277 kobj_set_kset_s(class_dev, class_obj_subsys);
278 kobject_init(&class_dev->kobj);
279 INIT_LIST_HEAD(&class_dev->node);
282 int class_device_add(struct class_device *class_dev)
284 struct class * parent;
285 struct class_interface * class_intf;
288 class_dev = class_device_get(class_dev);
289 if (!class_dev || !strlen(class_dev->class_id))
292 parent = class_get(class_dev->class);
294 pr_debug("CLASS: registering class device: ID = '%s'\n",
295 class_dev->class_id);
297 /* first, register with generic layer. */
298 kobject_set_name(&class_dev->kobj, class_dev->class_id);
300 class_dev->kobj.parent = &parent->subsys.kset.kobj;
302 if ((error = kobject_add(&class_dev->kobj)))
305 /* now take care of our own registration */
307 down_write(&parent->subsys.rwsem);
308 list_add_tail(&class_dev->node, &parent->children);
309 list_for_each_entry(class_intf, &parent->interfaces, node)
311 class_intf->add(class_dev);
312 up_write(&parent->subsys.rwsem);
315 class_device_dev_link(class_dev);
316 class_device_driver_link(class_dev);
321 class_device_put(class_dev);
325 int class_device_register(struct class_device *class_dev)
327 class_device_initialize(class_dev);
328 return class_device_add(class_dev);
331 void class_device_del(struct class_device *class_dev)
333 struct class * parent = class_dev->class;
334 struct class_interface * class_intf;
337 down_write(&parent->subsys.rwsem);
338 list_del_init(&class_dev->node);
339 list_for_each_entry(class_intf, &parent->interfaces, node)
340 if (class_intf->remove)
341 class_intf->remove(class_dev);
342 up_write(&parent->subsys.rwsem);
345 class_device_dev_unlink(class_dev);
346 class_device_driver_unlink(class_dev);
348 kobject_del(&class_dev->kobj);
354 void class_device_unregister(struct class_device *class_dev)
356 pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
357 class_dev->class_id);
358 class_device_del(class_dev);
359 class_device_put(class_dev);
362 int class_device_rename(struct class_device *class_dev, char *new_name)
364 class_dev = class_device_get(class_dev);
368 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
371 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
373 kobject_rename(&class_dev->kobj, new_name);
375 class_device_put(class_dev);
380 struct class_device * class_device_get(struct class_device *class_dev)
383 return to_class_dev(kobject_get(&class_dev->kobj));
387 void class_device_put(struct class_device *class_dev)
389 kobject_put(&class_dev->kobj);
393 int class_interface_register(struct class_interface *class_intf)
395 struct class * parent;
396 struct class_device * class_dev;
398 if (!class_intf || !class_intf->class)
401 parent = class_get(class_intf->class);
405 down_write(&parent->subsys.rwsem);
406 list_add_tail(&class_intf->node, &parent->interfaces);
408 if (class_intf->add) {
409 list_for_each_entry(class_dev, &parent->children, node)
410 class_intf->add(class_dev);
412 up_write(&parent->subsys.rwsem);
417 void class_interface_unregister(struct class_interface *class_intf)
419 struct class * parent = class_intf->class;
420 struct class_device *class_dev;
425 down_write(&parent->subsys.rwsem);
426 list_del_init(&class_intf->node);
428 if (class_intf->remove) {
429 list_for_each_entry(class_dev, &parent->children, node)
430 class_intf->remove(class_dev);
432 up_write(&parent->subsys.rwsem);
439 int __init classes_init(void)
443 retval = subsystem_register(&class_subsys);
447 /* ick, this is ugly, the things we go through to keep from showing up
449 subsystem_init(&class_obj_subsys);
450 if (!class_obj_subsys.kset.subsys)
451 class_obj_subsys.kset.subsys = &class_obj_subsys;
455 EXPORT_SYMBOL(class_create_file);
456 EXPORT_SYMBOL(class_remove_file);
457 EXPORT_SYMBOL(class_register);
458 EXPORT_SYMBOL(class_unregister);
459 EXPORT_SYMBOL(class_get);
460 EXPORT_SYMBOL(class_put);
462 EXPORT_SYMBOL(class_device_register);
463 EXPORT_SYMBOL(class_device_unregister);
464 EXPORT_SYMBOL(class_device_initialize);
465 EXPORT_SYMBOL(class_device_add);
466 EXPORT_SYMBOL(class_device_del);
467 EXPORT_SYMBOL(class_device_get);
468 EXPORT_SYMBOL(class_device_put);
469 EXPORT_SYMBOL(class_device_create_file);
470 EXPORT_SYMBOL(class_device_remove_file);
472 EXPORT_SYMBOL(class_interface_register);
473 EXPORT_SYMBOL(class_interface_unregister);