Merge with 2.5.75.
[linux-2.6/linux-mips.git] / drivers / base / class.c
blob2a9c349bd7c9a16337974e9ae10861cbb9bca3da
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, 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, 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);
97 strlcpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
98 subsys_set_kset(cls,class_subsys);
99 subsystem_register(&cls->subsys);
101 return 0;
104 void class_unregister(struct class * cls)
106 pr_debug("device class '%s': unregistering\n",cls->name);
107 subsystem_unregister(&cls->subsys);
110 /* Class Device Stuff */
112 int class_device_create_file(struct class_device * class_dev,
113 struct class_device_attribute * attr)
115 int error = -EINVAL;
116 if (class_dev)
117 error = sysfs_create_file(&class_dev->kobj, &attr->attr);
118 return error;
121 void class_device_remove_file(struct class_device * class_dev,
122 struct class_device_attribute * attr)
124 if (class_dev)
125 sysfs_remove_file(&class_dev->kobj, &attr->attr);
128 static int class_device_dev_link(struct class_device * class_dev)
130 if (class_dev->dev)
131 return sysfs_create_link(&class_dev->kobj,
132 &class_dev->dev->kobj, "device");
133 return 0;
136 static void class_device_dev_unlink(struct class_device * class_dev)
138 if (class_dev->dev)
139 sysfs_remove_link(&class_dev->kobj, "device");
142 static int class_device_driver_link(struct class_device * class_dev)
144 if ((class_dev->dev) && (class_dev->dev->driver))
145 return sysfs_create_link(&class_dev->kobj,
146 &class_dev->dev->driver->kobj, "driver");
147 return 0;
150 static void class_device_driver_unlink(struct class_device * class_dev)
152 if ((class_dev->dev) && (class_dev->dev->driver))
153 sysfs_remove_link(&class_dev->kobj, "driver");
157 static ssize_t
158 class_device_attr_show(struct kobject * kobj, struct attribute * attr,
159 char * buf)
161 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
162 struct class_device * cd = to_class_dev(kobj);
163 ssize_t ret = 0;
165 if (class_dev_attr->show)
166 ret = class_dev_attr->show(cd,buf);
167 return ret;
170 static ssize_t
171 class_device_attr_store(struct kobject * kobj, struct attribute * attr,
172 const char * buf, size_t count)
174 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
175 struct class_device * cd = to_class_dev(kobj);
176 ssize_t ret = 0;
178 if (class_dev_attr->store)
179 ret = class_dev_attr->store(cd,buf,count);
180 return ret;
183 static struct sysfs_ops class_dev_sysfs_ops = {
184 .show = class_device_attr_show,
185 .store = class_device_attr_store,
188 static void class_dev_release(struct kobject * kobj)
190 struct class_device *cd = to_class_dev(kobj);
191 struct class * cls = cd->class;
193 pr_debug("device class '%s': release.\n",cd->class_id);
195 if (cls->release)
196 cls->release(cd);
199 static struct kobj_type ktype_class_device = {
200 .sysfs_ops = &class_dev_sysfs_ops,
201 .release = class_dev_release,
204 static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
206 struct kobj_type *ktype = get_ktype(kobj);
208 if (ktype == &ktype_class_device) {
209 struct class_device *class_dev = to_class_dev(kobj);
210 if (class_dev->class)
211 return 1;
213 return 0;
216 static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
218 struct class_device *class_dev = to_class_dev(kobj);
220 return class_dev->class->name;
223 static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
224 int num_envp, char *buffer, int buffer_size)
226 struct class_device *class_dev = to_class_dev(kobj);
227 int retval = 0;
229 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
230 if (class_dev->class->hotplug) {
231 /* have the bus specific function add its stuff */
232 retval = class_dev->class->hotplug (class_dev, envp, num_envp,
233 buffer, buffer_size);
234 if (retval) {
235 pr_debug ("%s - hotplug() returned %d\n",
236 __FUNCTION__, retval);
240 return retval;
243 static struct kset_hotplug_ops class_hotplug_ops = {
244 .filter = class_hotplug_filter,
245 .name = class_hotplug_name,
246 .hotplug = class_hotplug,
249 static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
251 void class_device_initialize(struct class_device *class_dev)
253 kobject_init(&class_dev->kobj);
254 INIT_LIST_HEAD(&class_dev->node);
257 int class_device_add(struct class_device *class_dev)
259 struct class * parent;
260 struct class_interface * class_intf;
261 struct list_head * entry;
262 int error;
264 class_dev = class_device_get(class_dev);
265 if (!class_dev || !strlen(class_dev->class_id))
266 return -EINVAL;
268 parent = class_get(class_dev->class);
270 pr_debug("CLASS: registering class device: ID = '%s'\n",
271 class_dev->class_id);
273 /* first, register with generic layer. */
274 strlcpy(class_dev->kobj.name, class_dev->class_id, KOBJ_NAME_LEN);
275 kobj_set_kset_s(class_dev, class_obj_subsys);
276 if (parent)
277 class_dev->kobj.parent = &parent->subsys.kset.kobj;
279 if ((error = kobject_add(&class_dev->kobj)))
280 goto register_done;
282 /* now take care of our own registration */
283 if (parent) {
284 down_write(&parent->subsys.rwsem);
285 list_add_tail(&class_dev->node, &parent->children);
286 list_for_each(entry, &parent->interfaces) {
287 class_intf = container_of(entry, struct class_interface, node);
288 if (class_intf->add)
289 class_intf->add(class_dev);
291 up_write(&parent->subsys.rwsem);
294 class_device_dev_link(class_dev);
295 class_device_driver_link(class_dev);
297 register_done:
298 if (error && parent)
299 class_put(parent);
300 class_device_put(class_dev);
301 return error;
304 int class_device_register(struct class_device *class_dev)
306 class_device_initialize(class_dev);
307 return class_device_add(class_dev);
310 void class_device_del(struct class_device *class_dev)
312 struct class * parent = class_dev->class;
313 struct class_interface * class_intf;
314 struct list_head * entry;
316 if (parent) {
317 down_write(&parent->subsys.rwsem);
318 list_del_init(&class_dev->node);
319 list_for_each(entry, &parent->interfaces) {
320 class_intf = container_of(entry, struct class_interface, node);
321 if (class_intf->remove)
322 class_intf->remove(class_dev);
324 up_write(&parent->subsys.rwsem);
327 class_device_dev_unlink(class_dev);
328 class_device_driver_unlink(class_dev);
330 kobject_del(&class_dev->kobj);
332 if (parent)
333 class_put(parent);
336 void class_device_unregister(struct class_device *class_dev)
338 pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
339 class_dev->class_id);
340 class_device_del(class_dev);
341 class_device_put(class_dev);
344 int class_device_rename(struct class_device *class_dev, char *new_name)
346 class_dev = class_device_get(class_dev);
347 if (!class_dev)
348 return -EINVAL;
350 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
351 new_name);
353 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
355 kobject_rename(&class_dev->kobj, new_name);
357 class_device_put(class_dev);
359 return 0;
362 struct class_device * class_device_get(struct class_device *class_dev)
364 if (class_dev)
365 return to_class_dev(kobject_get(&class_dev->kobj));
366 return NULL;
369 void class_device_put(struct class_device *class_dev)
371 kobject_put(&class_dev->kobj);
375 int class_interface_register(struct class_interface *class_intf)
377 struct class * parent;
378 struct class_device * class_dev;
379 struct list_head * entry;
381 if (!class_intf || !class_intf->class)
382 return -ENODEV;
384 parent = class_get(class_intf->class);
385 if (!parent)
386 return -EINVAL;
388 down_write(&parent->subsys.rwsem);
389 list_add_tail(&class_intf->node, &parent->interfaces);
391 if (class_intf->add) {
392 list_for_each(entry, &parent->children) {
393 class_dev = container_of(entry, struct class_device, node);
394 class_intf->add(class_dev);
397 up_write(&parent->subsys.rwsem);
399 return 0;
402 void class_interface_unregister(struct class_interface *class_intf)
404 struct class * parent = class_intf->class;
405 struct list_head * entry;
407 if (!parent)
408 return;
410 down_write(&parent->subsys.rwsem);
411 list_del_init(&class_intf->node);
413 if (class_intf->remove) {
414 list_for_each(entry, &parent->children) {
415 struct class_device *class_dev = container_of(entry, struct class_device, node);
416 class_intf->remove(class_dev);
419 up_write(&parent->subsys.rwsem);
421 class_put(parent);
426 int __init classes_init(void)
428 int retval;
430 retval = subsystem_register(&class_subsys);
431 if (retval)
432 return retval;
434 /* ick, this is ugly, the things we go through to keep from showing up
435 * in sysfs... */
436 subsystem_init(&class_obj_subsys);
437 if (!class_obj_subsys.kset.subsys)
438 class_obj_subsys.kset.subsys = &class_obj_subsys;
439 return 0;
442 EXPORT_SYMBOL(class_create_file);
443 EXPORT_SYMBOL(class_remove_file);
444 EXPORT_SYMBOL(class_register);
445 EXPORT_SYMBOL(class_unregister);
446 EXPORT_SYMBOL(class_get);
447 EXPORT_SYMBOL(class_put);
449 EXPORT_SYMBOL(class_device_register);
450 EXPORT_SYMBOL(class_device_unregister);
451 EXPORT_SYMBOL(class_device_initialize);
452 EXPORT_SYMBOL(class_device_add);
453 EXPORT_SYMBOL(class_device_del);
454 EXPORT_SYMBOL(class_device_get);
455 EXPORT_SYMBOL(class_device_put);
456 EXPORT_SYMBOL(class_device_create_file);
457 EXPORT_SYMBOL(class_device_remove_file);
459 EXPORT_SYMBOL(class_interface_register);
460 EXPORT_SYMBOL(class_interface_unregister);