2 * class.c - basic device class management
4 * Copyright (c) 2002-3 Patrick Mochel
5 * Copyright (c) 2002-3 Open Source Development Labs
7 * This file is released under the GPLv2
13 #include <linux/device.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/string.h>
19 #define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr)
20 #define to_class(obj) container_of(obj,struct class,subsys.kset.kobj)
23 class_attr_show(struct kobject
* kobj
, struct attribute
* attr
, char * buf
)
25 struct class_attribute
* class_attr
= to_class_attr(attr
);
26 struct class * dc
= to_class(kobj
);
30 ret
= class_attr
->show(dc
,buf
);
35 class_attr_store(struct kobject
* kobj
, struct attribute
* attr
,
36 const char * buf
, size_t count
)
38 struct class_attribute
* class_attr
= to_class_attr(attr
);
39 struct class * dc
= to_class(kobj
);
42 if (class_attr
->store
)
43 ret
= class_attr
->store(dc
,buf
,count
);
47 static struct sysfs_ops class_sysfs_ops
= {
48 .show
= class_attr_show
,
49 .store
= class_attr_store
,
52 static struct kobj_type ktype_class
= {
53 .sysfs_ops
= &class_sysfs_ops
,
56 /* Hotplug events for classes go to the class_obj subsys */
57 static decl_subsys(class,&ktype_class
,NULL
);
60 int class_create_file(struct class * cls
, struct class_attribute
* attr
)
64 error
= sysfs_create_file(&cls
->subsys
.kset
.kobj
,&attr
->attr
);
70 void class_remove_file(struct class * cls
, struct class_attribute
* attr
)
73 sysfs_remove_file(&cls
->subsys
.kset
.kobj
,&attr
->attr
);
76 struct class * class_get(struct class * cls
)
79 return container_of(subsys_get(&cls
->subsys
),struct class,subsys
);
83 void class_put(struct class * cls
)
85 subsys_put(&cls
->subsys
);
88 int class_register(struct class * cls
)
90 pr_debug("device class '%s': registering\n",cls
->name
);
92 INIT_LIST_HEAD(&cls
->children
);
93 INIT_LIST_HEAD(&cls
->interfaces
);
95 strlcpy(cls
->subsys
.kset
.kobj
.name
,cls
->name
,KOBJ_NAME_LEN
);
96 subsys_set_kset(cls
,class_subsys
);
97 subsystem_register(&cls
->subsys
);
102 void class_unregister(struct class * cls
)
104 pr_debug("device class '%s': unregistering\n",cls
->name
);
105 subsystem_unregister(&cls
->subsys
);
108 /* Class Device Stuff */
110 int class_device_create_file(struct class_device
* class_dev
,
111 struct class_device_attribute
* attr
)
115 error
= sysfs_create_file(&class_dev
->kobj
, &attr
->attr
);
119 void class_device_remove_file(struct class_device
* class_dev
,
120 struct class_device_attribute
* attr
)
123 sysfs_remove_file(&class_dev
->kobj
, &attr
->attr
);
126 static int class_device_dev_link(struct class_device
* class_dev
)
129 return sysfs_create_link(&class_dev
->kobj
,
130 &class_dev
->dev
->kobj
, "device");
134 static void class_device_dev_unlink(struct class_device
* class_dev
)
137 sysfs_remove_link(&class_dev
->kobj
, "device");
140 static int class_device_driver_link(struct class_device
* class_dev
)
142 if ((class_dev
->dev
) && (class_dev
->dev
->driver
))
143 return sysfs_create_link(&class_dev
->kobj
,
144 &class_dev
->dev
->driver
->kobj
, "driver");
148 static void class_device_driver_unlink(struct class_device
* class_dev
)
150 if ((class_dev
->dev
) && (class_dev
->dev
->driver
))
151 sysfs_remove_link(&class_dev
->kobj
, "driver");
156 class_device_attr_show(struct kobject
* kobj
, struct attribute
* attr
,
159 struct class_device_attribute
* class_dev_attr
= to_class_dev_attr(attr
);
160 struct class_device
* cd
= to_class_dev(kobj
);
163 if (class_dev_attr
->show
)
164 ret
= class_dev_attr
->show(cd
,buf
);
169 class_device_attr_store(struct kobject
* kobj
, struct attribute
* attr
,
170 const char * buf
, size_t count
)
172 struct class_device_attribute
* class_dev_attr
= to_class_dev_attr(attr
);
173 struct class_device
* cd
= to_class_dev(kobj
);
176 if (class_dev_attr
->store
)
177 ret
= class_dev_attr
->store(cd
,buf
,count
);
181 static struct sysfs_ops class_dev_sysfs_ops
= {
182 .show
= class_device_attr_show
,
183 .store
= class_device_attr_store
,
186 static void class_dev_release(struct kobject
* kobj
)
188 struct class_device
*cd
= to_class_dev(kobj
);
189 struct class * cls
= cd
->class;
191 pr_debug("device class '%s': release.\n",cd
->class_id
);
197 static struct kobj_type ktype_class_device
= {
198 .sysfs_ops
= &class_dev_sysfs_ops
,
199 .release
= class_dev_release
,
202 static int class_hotplug_filter(struct kset
*kset
, struct kobject
*kobj
)
204 struct kobj_type
*ktype
= get_ktype(kobj
);
206 if (ktype
== &ktype_class_device
) {
207 struct class_device
*class_dev
= to_class_dev(kobj
);
208 if (class_dev
->class)
214 static char *class_hotplug_name(struct kset
*kset
, struct kobject
*kobj
)
216 struct class_device
*class_dev
= to_class_dev(kobj
);
218 return class_dev
->class->name
;
221 static int class_hotplug(struct kset
*kset
, struct kobject
*kobj
, char **envp
,
222 int num_envp
, char *buffer
, int buffer_size
)
224 struct class_device
*class_dev
= to_class_dev(kobj
);
227 pr_debug("%s - name = %s\n", __FUNCTION__
, class_dev
->class_id
);
228 if (class_dev
->class->hotplug
) {
229 /* have the bus specific function add its stuff */
230 retval
= class_dev
->class->hotplug (class_dev
, envp
, num_envp
,
231 buffer
, buffer_size
);
233 pr_debug ("%s - hotplug() returned %d\n",
234 __FUNCTION__
, retval
);
241 static struct kset_hotplug_ops class_hotplug_ops
= {
242 .filter
= class_hotplug_filter
,
243 .name
= class_hotplug_name
,
244 .hotplug
= class_hotplug
,
247 static decl_subsys(class_obj
, &ktype_class_device
, &class_hotplug_ops
);
249 void class_device_initialize(struct class_device
*class_dev
)
251 kobject_init(&class_dev
->kobj
);
252 INIT_LIST_HEAD(&class_dev
->node
);
255 int class_device_add(struct class_device
*class_dev
)
257 struct class * parent
;
258 struct class_interface
* class_intf
;
259 struct list_head
* entry
;
262 class_dev
= class_device_get(class_dev
);
263 if (!class_dev
|| !strlen(class_dev
->class_id
))
266 parent
= class_get(class_dev
->class);
268 pr_debug("CLASS: registering class device: ID = '%s'\n",
269 class_dev
->class_id
);
271 /* first, register with generic layer. */
272 strlcpy(class_dev
->kobj
.name
, class_dev
->class_id
, KOBJ_NAME_LEN
);
273 kobj_set_kset_s(class_dev
, class_obj_subsys
);
275 class_dev
->kobj
.parent
= &parent
->subsys
.kset
.kobj
;
277 if ((error
= kobject_add(&class_dev
->kobj
)))
280 /* now take care of our own registration */
282 down_write(&parent
->subsys
.rwsem
);
283 list_add_tail(&class_dev
->node
, &parent
->children
);
284 list_for_each(entry
, &parent
->interfaces
) {
285 class_intf
= container_of(entry
, struct class_interface
, node
);
287 class_intf
->add(class_dev
);
289 up_write(&parent
->subsys
.rwsem
);
292 class_device_dev_link(class_dev
);
293 class_device_driver_link(class_dev
);
298 class_device_put(class_dev
);
302 int class_device_register(struct class_device
*class_dev
)
304 class_device_initialize(class_dev
);
305 return class_device_add(class_dev
);
308 void class_device_del(struct class_device
*class_dev
)
310 struct class * parent
= class_dev
->class;
311 struct class_interface
* class_intf
;
312 struct list_head
* entry
;
315 down_write(&parent
->subsys
.rwsem
);
316 list_del_init(&class_dev
->node
);
317 list_for_each(entry
, &parent
->interfaces
) {
318 class_intf
= container_of(entry
, struct class_interface
, node
);
319 if (class_intf
->remove
)
320 class_intf
->remove(class_dev
);
322 up_write(&parent
->subsys
.rwsem
);
325 class_device_dev_unlink(class_dev
);
326 class_device_driver_unlink(class_dev
);
328 kobject_del(&class_dev
->kobj
);
334 void class_device_unregister(struct class_device
*class_dev
)
336 pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
337 class_dev
->class_id
);
338 class_device_del(class_dev
);
339 class_device_put(class_dev
);
342 struct class_device
* class_device_get(struct class_device
*class_dev
)
345 return to_class_dev(kobject_get(&class_dev
->kobj
));
349 void class_device_put(struct class_device
*class_dev
)
351 kobject_put(&class_dev
->kobj
);
355 int class_interface_register(struct class_interface
*class_intf
)
357 struct class * parent
;
358 struct class_device
* class_dev
;
359 struct list_head
* entry
;
361 if (!class_intf
|| !class_intf
->class)
364 parent
= class_get(class_intf
->class);
368 down_write(&parent
->subsys
.rwsem
);
369 list_add_tail(&class_intf
->node
, &parent
->interfaces
);
371 if (class_intf
->add
) {
372 list_for_each(entry
, &parent
->children
) {
373 class_dev
= container_of(entry
, struct class_device
, node
);
374 class_intf
->add(class_dev
);
377 up_write(&parent
->subsys
.rwsem
);
382 void class_interface_unregister(struct class_interface
*class_intf
)
384 struct class * parent
= class_intf
->class;
385 struct list_head
* entry
;
390 down_write(&parent
->subsys
.rwsem
);
391 list_del_init(&class_intf
->node
);
393 if (class_intf
->remove
) {
394 list_for_each(entry
, &parent
->children
) {
395 struct class_device
*class_dev
= container_of(entry
, struct class_device
, node
);
396 class_intf
->remove(class_dev
);
399 up_write(&parent
->subsys
.rwsem
);
406 int __init
classes_init(void)
410 retval
= subsystem_register(&class_subsys
);
414 /* ick, this is ugly, the things we go through to keep from showing up
416 subsystem_init(&class_obj_subsys
);
417 if (!class_obj_subsys
.kset
.subsys
)
418 class_obj_subsys
.kset
.subsys
= &class_obj_subsys
;
422 EXPORT_SYMBOL(class_create_file
);
423 EXPORT_SYMBOL(class_remove_file
);
424 EXPORT_SYMBOL(class_register
);
425 EXPORT_SYMBOL(class_unregister
);
426 EXPORT_SYMBOL(class_get
);
427 EXPORT_SYMBOL(class_put
);
429 EXPORT_SYMBOL(class_device_register
);
430 EXPORT_SYMBOL(class_device_unregister
);
431 EXPORT_SYMBOL(class_device_initialize
);
432 EXPORT_SYMBOL(class_device_add
);
433 EXPORT_SYMBOL(class_device_del
);
434 EXPORT_SYMBOL(class_device_get
);
435 EXPORT_SYMBOL(class_device_put
);
436 EXPORT_SYMBOL(class_device_create_file
);
437 EXPORT_SYMBOL(class_device_remove_file
);
439 EXPORT_SYMBOL(class_interface_register
);
440 EXPORT_SYMBOL(class_interface_unregister
);