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>
18 #include <linux/kdev_t.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)
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
);
32 ret
= class_attr
->show(dc
, buf
);
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
);
44 if (class_attr
->store
)
45 ret
= class_attr
->store(dc
, buf
, count
);
49 static void class_release(struct kobject
* kobj
)
51 struct class *class = to_class(kobj
);
53 pr_debug("class '%s': release.\n", class->name
);
55 if (class->class_release
)
56 class->class_release(class);
58 pr_debug("class '%s' does not have a release() function, "
59 "be careful\n", class->name
);
62 static struct sysfs_ops class_sysfs_ops
= {
63 .show
= class_attr_show
,
64 .store
= class_attr_store
,
67 static struct kobj_type ktype_class
= {
68 .sysfs_ops
= &class_sysfs_ops
,
69 .release
= class_release
,
72 /* Hotplug events for classes go to the class_obj subsys */
73 static decl_subsys(class, &ktype_class
, NULL
);
76 int class_create_file(struct class * cls
, const struct class_attribute
* attr
)
80 error
= sysfs_create_file(&cls
->subsys
.kset
.kobj
, &attr
->attr
);
86 void class_remove_file(struct class * cls
, const struct class_attribute
* attr
)
89 sysfs_remove_file(&cls
->subsys
.kset
.kobj
, &attr
->attr
);
92 struct class * class_get(struct class * cls
)
95 return container_of(subsys_get(&cls
->subsys
), struct class, subsys
);
99 void class_put(struct class * cls
)
101 subsys_put(&cls
->subsys
);
105 static int add_class_attrs(struct class * cls
)
110 if (cls
->class_attrs
) {
111 for (i
= 0; attr_name(cls
->class_attrs
[i
]); i
++) {
112 error
= class_create_file(cls
,&cls
->class_attrs
[i
]);
121 class_remove_file(cls
,&cls
->class_attrs
[i
]);
125 static void remove_class_attrs(struct class * cls
)
129 if (cls
->class_attrs
) {
130 for (i
= 0; attr_name(cls
->class_attrs
[i
]); i
++)
131 class_remove_file(cls
,&cls
->class_attrs
[i
]);
135 int class_register(struct class * cls
)
139 pr_debug("device class '%s': registering\n", cls
->name
);
141 INIT_LIST_HEAD(&cls
->children
);
142 INIT_LIST_HEAD(&cls
->interfaces
);
143 init_MUTEX(&cls
->sem
);
144 error
= kobject_set_name(&cls
->subsys
.kset
.kobj
, "%s", cls
->name
);
148 subsys_set_kset(cls
, class_subsys
);
150 error
= subsystem_register(&cls
->subsys
);
152 error
= add_class_attrs(class_get(cls
));
158 void class_unregister(struct class * cls
)
160 pr_debug("device class '%s': unregistering\n", cls
->name
);
161 remove_class_attrs(cls
);
162 subsystem_unregister(&cls
->subsys
);
166 /* Class Device Stuff */
168 int class_device_create_file(struct class_device
* class_dev
,
169 const struct class_device_attribute
* attr
)
173 error
= sysfs_create_file(&class_dev
->kobj
, &attr
->attr
);
177 void class_device_remove_file(struct class_device
* class_dev
,
178 const struct class_device_attribute
* attr
)
181 sysfs_remove_file(&class_dev
->kobj
, &attr
->attr
);
184 int class_device_create_bin_file(struct class_device
*class_dev
,
185 struct bin_attribute
*attr
)
189 error
= sysfs_create_bin_file(&class_dev
->kobj
, attr
);
193 void class_device_remove_bin_file(struct class_device
*class_dev
,
194 struct bin_attribute
*attr
)
197 sysfs_remove_bin_file(&class_dev
->kobj
, attr
);
201 class_device_attr_show(struct kobject
* kobj
, struct attribute
* attr
,
204 struct class_device_attribute
* class_dev_attr
= to_class_dev_attr(attr
);
205 struct class_device
* cd
= to_class_dev(kobj
);
208 if (class_dev_attr
->show
)
209 ret
= class_dev_attr
->show(cd
, buf
);
214 class_device_attr_store(struct kobject
* kobj
, struct attribute
* attr
,
215 const char * buf
, size_t count
)
217 struct class_device_attribute
* class_dev_attr
= to_class_dev_attr(attr
);
218 struct class_device
* cd
= to_class_dev(kobj
);
221 if (class_dev_attr
->store
)
222 ret
= class_dev_attr
->store(cd
, buf
, count
);
226 static struct sysfs_ops class_dev_sysfs_ops
= {
227 .show
= class_device_attr_show
,
228 .store
= class_device_attr_store
,
231 static void class_dev_release(struct kobject
* kobj
)
233 struct class_device
*cd
= to_class_dev(kobj
);
234 struct class * cls
= cd
->class;
236 pr_debug("device class '%s': release.\n", cd
->class_id
);
241 printk(KERN_ERR
"Device class '%s' does not have a release() function, "
242 "it is broken and must be fixed.\n",
248 static struct kobj_type ktype_class_device
= {
249 .sysfs_ops
= &class_dev_sysfs_ops
,
250 .release
= class_dev_release
,
253 static int class_hotplug_filter(struct kset
*kset
, struct kobject
*kobj
)
255 struct kobj_type
*ktype
= get_ktype(kobj
);
257 if (ktype
== &ktype_class_device
) {
258 struct class_device
*class_dev
= to_class_dev(kobj
);
259 if (class_dev
->class)
265 static char *class_hotplug_name(struct kset
*kset
, struct kobject
*kobj
)
267 struct class_device
*class_dev
= to_class_dev(kobj
);
269 return class_dev
->class->name
;
272 static int class_hotplug(struct kset
*kset
, struct kobject
*kobj
, char **envp
,
273 int num_envp
, char *buffer
, int buffer_size
)
275 struct class_device
*class_dev
= to_class_dev(kobj
);
280 pr_debug("%s - name = %s\n", __FUNCTION__
, class_dev
->class_id
);
282 if (class_dev
->dev
) {
283 /* add physical device, backing this device */
284 struct device
*dev
= class_dev
->dev
;
285 char *path
= kobject_get_path(&dev
->kobj
, GFP_KERNEL
);
287 add_hotplug_env_var(envp
, num_envp
, &i
, buffer
, buffer_size
,
288 &length
, "PHYSDEVPATH=%s", path
);
292 add_hotplug_env_var(envp
, num_envp
, &i
,
293 buffer
, buffer_size
, &length
,
294 "PHYSDEVBUS=%s", dev
->bus
->name
);
297 add_hotplug_env_var(envp
, num_envp
, &i
,
298 buffer
, buffer_size
, &length
,
299 "PHYSDEVDRIVER=%s", dev
->driver
->name
);
302 if (MAJOR(class_dev
->devt
)) {
303 add_hotplug_env_var(envp
, num_envp
, &i
,
304 buffer
, buffer_size
, &length
,
305 "MAJOR=%u", MAJOR(class_dev
->devt
));
307 add_hotplug_env_var(envp
, num_envp
, &i
,
308 buffer
, buffer_size
, &length
,
309 "MINOR=%u", MINOR(class_dev
->devt
));
312 /* terminate, set to next free slot, shrink available space */
316 buffer
= &buffer
[length
];
317 buffer_size
-= length
;
319 if (class_dev
->class->hotplug
) {
320 /* have the bus specific function add its stuff */
321 retval
= class_dev
->class->hotplug (class_dev
, envp
, num_envp
,
322 buffer
, buffer_size
);
324 pr_debug ("%s - hotplug() returned %d\n",
325 __FUNCTION__
, retval
);
332 static struct kset_hotplug_ops class_hotplug_ops
= {
333 .filter
= class_hotplug_filter
,
334 .name
= class_hotplug_name
,
335 .hotplug
= class_hotplug
,
338 static decl_subsys(class_obj
, &ktype_class_device
, &class_hotplug_ops
);
341 static int class_device_add_attrs(struct class_device
* cd
)
345 struct class * cls
= cd
->class;
347 if (cls
->class_dev_attrs
) {
348 for (i
= 0; attr_name(cls
->class_dev_attrs
[i
]); i
++) {
349 error
= class_device_create_file(cd
,
350 &cls
->class_dev_attrs
[i
]);
359 class_device_remove_file(cd
,&cls
->class_dev_attrs
[i
]);
363 static void class_device_remove_attrs(struct class_device
* cd
)
366 struct class * cls
= cd
->class;
368 if (cls
->class_dev_attrs
) {
369 for (i
= 0; attr_name(cls
->class_dev_attrs
[i
]); i
++)
370 class_device_remove_file(cd
,&cls
->class_dev_attrs
[i
]);
374 static ssize_t
show_dev(struct class_device
*class_dev
, char *buf
)
376 return print_dev_t(buf
, class_dev
->devt
);
378 static CLASS_DEVICE_ATTR(dev
, S_IRUGO
, show_dev
, NULL
);
380 void class_device_initialize(struct class_device
*class_dev
)
382 kobj_set_kset_s(class_dev
, class_obj_subsys
);
383 kobject_init(&class_dev
->kobj
);
384 INIT_LIST_HEAD(&class_dev
->node
);
387 int class_device_add(struct class_device
*class_dev
)
389 struct class * parent
= NULL
;
390 struct class_interface
* class_intf
;
393 class_dev
= class_device_get(class_dev
);
397 if (!strlen(class_dev
->class_id
)) {
402 parent
= class_get(class_dev
->class);
404 pr_debug("CLASS: registering class device: ID = '%s'\n",
405 class_dev
->class_id
);
407 /* first, register with generic layer. */
408 kobject_set_name(&class_dev
->kobj
, "%s", class_dev
->class_id
);
410 class_dev
->kobj
.parent
= &parent
->subsys
.kset
.kobj
;
412 if ((error
= kobject_add(&class_dev
->kobj
)))
415 /* now take care of our own registration */
418 list_add_tail(&class_dev
->node
, &parent
->children
);
419 list_for_each_entry(class_intf
, &parent
->interfaces
, node
)
421 class_intf
->add(class_dev
);
425 if (MAJOR(class_dev
->devt
))
426 class_device_create_file(class_dev
, &class_device_attr_dev
);
428 class_device_add_attrs(class_dev
);
430 sysfs_create_link(&class_dev
->kobj
,
431 &class_dev
->dev
->kobj
, "device");
433 kobject_hotplug(&class_dev
->kobj
, KOBJ_ADD
);
437 class_device_put(class_dev
);
441 int class_device_register(struct class_device
*class_dev
)
443 class_device_initialize(class_dev
);
444 return class_device_add(class_dev
);
447 void class_device_del(struct class_device
*class_dev
)
449 struct class * parent
= class_dev
->class;
450 struct class_interface
* class_intf
;
454 list_del_init(&class_dev
->node
);
455 list_for_each_entry(class_intf
, &parent
->interfaces
, node
)
456 if (class_intf
->remove
)
457 class_intf
->remove(class_dev
);
462 sysfs_remove_link(&class_dev
->kobj
, "device");
463 class_device_remove_attrs(class_dev
);
465 kobject_hotplug(&class_dev
->kobj
, KOBJ_REMOVE
);
466 kobject_del(&class_dev
->kobj
);
472 void class_device_unregister(struct class_device
*class_dev
)
474 pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
475 class_dev
->class_id
);
476 class_device_del(class_dev
);
477 class_device_put(class_dev
);
480 int class_device_rename(struct class_device
*class_dev
, char *new_name
)
484 class_dev
= class_device_get(class_dev
);
488 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev
->class_id
,
491 strlcpy(class_dev
->class_id
, new_name
, KOBJ_NAME_LEN
);
493 error
= kobject_rename(&class_dev
->kobj
, new_name
);
495 class_device_put(class_dev
);
500 struct class_device
* class_device_get(struct class_device
*class_dev
)
503 return to_class_dev(kobject_get(&class_dev
->kobj
));
507 void class_device_put(struct class_device
*class_dev
)
509 kobject_put(&class_dev
->kobj
);
513 int class_interface_register(struct class_interface
*class_intf
)
515 struct class *parent
;
516 struct class_device
*class_dev
;
518 if (!class_intf
|| !class_intf
->class)
521 parent
= class_get(class_intf
->class);
526 list_add_tail(&class_intf
->node
, &parent
->interfaces
);
527 if (class_intf
->add
) {
528 list_for_each_entry(class_dev
, &parent
->children
, node
)
529 class_intf
->add(class_dev
);
536 void class_interface_unregister(struct class_interface
*class_intf
)
538 struct class * parent
= class_intf
->class;
539 struct class_device
*class_dev
;
545 list_del_init(&class_intf
->node
);
546 if (class_intf
->remove
) {
547 list_for_each_entry(class_dev
, &parent
->children
, node
)
548 class_intf
->remove(class_dev
);
557 int __init
classes_init(void)
561 retval
= subsystem_register(&class_subsys
);
565 /* ick, this is ugly, the things we go through to keep from showing up
567 subsystem_init(&class_obj_subsys
);
568 if (!class_obj_subsys
.kset
.subsys
)
569 class_obj_subsys
.kset
.subsys
= &class_obj_subsys
;
573 EXPORT_SYMBOL_GPL(class_create_file
);
574 EXPORT_SYMBOL_GPL(class_remove_file
);
575 EXPORT_SYMBOL_GPL(class_register
);
576 EXPORT_SYMBOL_GPL(class_unregister
);
577 EXPORT_SYMBOL_GPL(class_get
);
578 EXPORT_SYMBOL_GPL(class_put
);
580 EXPORT_SYMBOL_GPL(class_device_register
);
581 EXPORT_SYMBOL_GPL(class_device_unregister
);
582 EXPORT_SYMBOL_GPL(class_device_initialize
);
583 EXPORT_SYMBOL_GPL(class_device_add
);
584 EXPORT_SYMBOL_GPL(class_device_del
);
585 EXPORT_SYMBOL_GPL(class_device_get
);
586 EXPORT_SYMBOL_GPL(class_device_put
);
587 EXPORT_SYMBOL_GPL(class_device_create_file
);
588 EXPORT_SYMBOL_GPL(class_device_remove_file
);
589 EXPORT_SYMBOL_GPL(class_device_create_bin_file
);
590 EXPORT_SYMBOL_GPL(class_device_remove_bin_file
);
592 EXPORT_SYMBOL_GPL(class_interface_register
);
593 EXPORT_SYMBOL_GPL(class_interface_unregister
);