More meth updates.
[linux-2.6/linux-mips.git] / drivers / base / class.c
blobea551b8dc28b6f5700fdbecd455e43ef6e3b17ab
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 *
7 * This file is released under the GPLv2
9 */
11 #undef DEBUG
13 #include <linux/device.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/string.h>
17 #include "base.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)
22 static ssize_t
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);
27 ssize_t ret = 0;
29 if (class_attr->show)
30 ret = class_attr->show(dc,buf);
31 return ret;
34 static ssize_t
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);
40 ssize_t ret = 0;
42 if (class_attr->store)
43 ret = class_attr->store(dc,buf,count);
44 return ret;
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)
62 int error;
63 if (cls) {
64 error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
65 } else
66 error = -EINVAL;
67 return error;
70 void class_remove_file(struct class * cls, struct class_attribute * attr)
72 if (cls)
73 sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
76 struct class * class_get(struct class * cls)
78 if (cls)
79 return container_of(subsys_get(&cls->subsys),struct class,subsys);
80 return NULL;
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);
99 return 0;
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)
113 int error = -EINVAL;
114 if (class_dev)
115 error = sysfs_create_file(&class_dev->kobj, &attr->attr);
116 return error;
119 void class_device_remove_file(struct class_device * class_dev,
120 struct class_device_attribute * attr)
122 if (class_dev)
123 sysfs_remove_file(&class_dev->kobj, &attr->attr);
126 static int class_device_dev_link(struct class_device * class_dev)
128 if (class_dev->dev)
129 return sysfs_create_link(&class_dev->kobj,
130 &class_dev->dev->kobj, "device");
131 return 0;
134 static void class_device_dev_unlink(struct class_device * class_dev)
136 if (class_dev->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");
145 return 0;
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");
155 static ssize_t
156 class_device_attr_show(struct kobject * kobj, struct attribute * attr,
157 char * buf)
159 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
160 struct class_device * cd = to_class_dev(kobj);
161 ssize_t ret = 0;
163 if (class_dev_attr->show)
164 ret = class_dev_attr->show(cd,buf);
165 return ret;
168 static ssize_t
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);
174 ssize_t ret = 0;
176 if (class_dev_attr->store)
177 ret = class_dev_attr->store(cd,buf,count);
178 return ret;
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);
193 if (cls->release)
194 cls->release(cd);
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)
209 return 1;
211 return 0;
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);
225 int retval = 0;
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);
232 if (retval) {
233 pr_debug ("%s - hotplug() returned %d\n",
234 __FUNCTION__, retval);
238 return 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;
260 int error;
262 class_dev = class_device_get(class_dev);
263 if (!class_dev || !strlen(class_dev->class_id))
264 return -EINVAL;
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);
274 if (parent)
275 class_dev->kobj.parent = &parent->subsys.kset.kobj;
277 if ((error = kobject_add(&class_dev->kobj)))
278 goto register_done;
280 /* now take care of our own registration */
281 if (parent) {
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);
286 if (class_intf->add)
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);
295 register_done:
296 if (error && parent)
297 class_put(parent);
298 class_device_put(class_dev);
299 return error;
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;
314 if (parent) {
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);
330 if (parent)
331 class_put(parent);
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)
344 if (class_dev)
345 return to_class_dev(kobject_get(&class_dev->kobj));
346 return NULL;
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)
362 return -ENODEV;
364 parent = class_get(class_intf->class);
365 if (!parent)
366 return -EINVAL;
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);
379 return 0;
382 void class_interface_unregister(struct class_interface *class_intf)
384 struct class * parent = class_intf->class;
385 struct list_head * entry;
387 if (!parent)
388 return;
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);
401 class_put(parent);
406 int __init classes_init(void)
408 int retval;
410 retval = subsystem_register(&class_subsys);
411 if (retval)
412 return retval;
414 /* ick, this is ugly, the things we go through to keep from showing up
415 * in sysfs... */
416 subsystem_init(&class_obj_subsys);
417 if (!class_obj_subsys.kset.subsys)
418 class_obj_subsys.kset.subsys = &class_obj_subsys;
419 return 0;
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);