]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/base/class.c
Driver core: change sysdev classes to use dynamic kobject names
[linux-2.6-omap-h63xx.git] / drivers / base / class.c
1 /*
2  * class.c - basic device class management
3  *
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.
8  *
9  * This file is released under the GPLv2
10  *
11  */
12
13 #include <linux/device.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/string.h>
17 #include <linux/kdev_t.h>
18 #include <linux/err.h>
19 #include <linux/slab.h>
20 #include <linux/genhd.h>
21 #include "base.h"
22
23 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
24 #define to_class(obj) container_of(obj, struct class, subsys.kobj)
25
26 static ssize_t
27 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
28 {
29         struct class_attribute * class_attr = to_class_attr(attr);
30         struct class * dc = to_class(kobj);
31         ssize_t ret = -EIO;
32
33         if (class_attr->show)
34                 ret = class_attr->show(dc, buf);
35         return ret;
36 }
37
38 static ssize_t
39 class_attr_store(struct kobject * kobj, struct attribute * attr,
40                  const char * buf, size_t count)
41 {
42         struct class_attribute * class_attr = to_class_attr(attr);
43         struct class * dc = to_class(kobj);
44         ssize_t ret = -EIO;
45
46         if (class_attr->store)
47                 ret = class_attr->store(dc, buf, count);
48         return ret;
49 }
50
51 static void class_release(struct kobject * kobj)
52 {
53         struct class *class = to_class(kobj);
54
55         pr_debug("class '%s': release.\n", class->name);
56
57         if (class->class_release)
58                 class->class_release(class);
59         else
60                 pr_debug("class '%s' does not have a release() function, "
61                          "be careful\n", class->name);
62 }
63
64 static struct sysfs_ops class_sysfs_ops = {
65         .show   = class_attr_show,
66         .store  = class_attr_store,
67 };
68
69 static struct kobj_type class_ktype = {
70         .sysfs_ops      = &class_sysfs_ops,
71         .release        = class_release,
72 };
73
74 /* Hotplug events for classes go to the class_obj subsys */
75 static struct kset *class_kset;
76
77
78 int class_create_file(struct class * cls, const struct class_attribute * attr)
79 {
80         int error;
81         if (cls) {
82                 error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
83         } else
84                 error = -EINVAL;
85         return error;
86 }
87
88 void class_remove_file(struct class * cls, const struct class_attribute * attr)
89 {
90         if (cls)
91                 sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
92 }
93
94 static struct class *class_get(struct class *cls)
95 {
96         if (cls)
97                 return container_of(kset_get(&cls->subsys), struct class, subsys);
98         return NULL;
99 }
100
101 static void class_put(struct class * cls)
102 {
103         if (cls)
104                 kset_put(&cls->subsys);
105 }
106
107
108 static int add_class_attrs(struct class * cls)
109 {
110         int i;
111         int error = 0;
112
113         if (cls->class_attrs) {
114                 for (i = 0; attr_name(cls->class_attrs[i]); i++) {
115                         error = class_create_file(cls,&cls->class_attrs[i]);
116                         if (error)
117                                 goto Err;
118                 }
119         }
120  Done:
121         return error;
122  Err:
123         while (--i >= 0)
124                 class_remove_file(cls,&cls->class_attrs[i]);
125         goto Done;
126 }
127
128 static void remove_class_attrs(struct class * cls)
129 {
130         int i;
131
132         if (cls->class_attrs) {
133                 for (i = 0; attr_name(cls->class_attrs[i]); i++)
134                         class_remove_file(cls,&cls->class_attrs[i]);
135         }
136 }
137
138 int class_register(struct class * cls)
139 {
140         int error;
141
142         pr_debug("device class '%s': registering\n", cls->name);
143
144         INIT_LIST_HEAD(&cls->children);
145         INIT_LIST_HEAD(&cls->devices);
146         INIT_LIST_HEAD(&cls->interfaces);
147         kset_init(&cls->class_dirs);
148         init_MUTEX(&cls->sem);
149         error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
150         if (error)
151                 return error;
152
153 #ifdef CONFIG_SYSFS_DEPRECATED
154         /* let the block class directory show up in the root of sysfs */
155         if (cls != &block_class)
156                 cls->subsys.kobj.kset = class_kset;
157 #else
158         cls->subsys.kobj.kset = class_kset;
159 #endif
160         cls->subsys.kobj.ktype = &class_ktype;
161
162         error = kset_register(&cls->subsys);
163         if (!error) {
164                 error = add_class_attrs(class_get(cls));
165                 class_put(cls);
166         }
167         return error;
168 }
169
170 void class_unregister(struct class * cls)
171 {
172         pr_debug("device class '%s': unregistering\n", cls->name);
173         remove_class_attrs(cls);
174         kset_unregister(&cls->subsys);
175 }
176
177 static void class_create_release(struct class *cls)
178 {
179         pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
180         kfree(cls);
181 }
182
183 static void class_device_create_release(struct class_device *class_dev)
184 {
185         pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
186         kfree(class_dev);
187 }
188
189 /* needed to allow these devices to have parent class devices */
190 static int class_device_create_uevent(struct class_device *class_dev,
191                                       struct kobj_uevent_env *env)
192 {
193         pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
194         return 0;
195 }
196
197 /**
198  * class_create - create a struct class structure
199  * @owner: pointer to the module that is to "own" this struct class
200  * @name: pointer to a string for the name of this class.
201  *
202  * This is used to create a struct class pointer that can then be used
203  * in calls to class_device_create().
204  *
205  * Note, the pointer created here is to be destroyed when finished by
206  * making a call to class_destroy().
207  */
208 struct class *class_create(struct module *owner, const char *name)
209 {
210         struct class *cls;
211         int retval;
212
213         cls = kzalloc(sizeof(*cls), GFP_KERNEL);
214         if (!cls) {
215                 retval = -ENOMEM;
216                 goto error;
217         }
218
219         cls->name = name;
220         cls->owner = owner;
221         cls->class_release = class_create_release;
222         cls->release = class_device_create_release;
223
224         retval = class_register(cls);
225         if (retval)
226                 goto error;
227
228         return cls;
229
230 error:
231         kfree(cls);
232         return ERR_PTR(retval);
233 }
234
235 /**
236  * class_destroy - destroys a struct class structure
237  * @cls: pointer to the struct class that is to be destroyed
238  *
239  * Note, the pointer to be destroyed must have been created with a call
240  * to class_create().
241  */
242 void class_destroy(struct class *cls)
243 {
244         if ((cls == NULL) || (IS_ERR(cls)))
245                 return;
246
247         class_unregister(cls);
248 }
249
250 /* Class Device Stuff */
251
252 int class_device_create_file(struct class_device * class_dev,
253                              const struct class_device_attribute * attr)
254 {
255         int error = -EINVAL;
256         if (class_dev)
257                 error = sysfs_create_file(&class_dev->kobj, &attr->attr);
258         return error;
259 }
260
261 void class_device_remove_file(struct class_device * class_dev,
262                               const struct class_device_attribute * attr)
263 {
264         if (class_dev)
265                 sysfs_remove_file(&class_dev->kobj, &attr->attr);
266 }
267
268 int class_device_create_bin_file(struct class_device *class_dev,
269                                  struct bin_attribute *attr)
270 {
271         int error = -EINVAL;
272         if (class_dev)
273                 error = sysfs_create_bin_file(&class_dev->kobj, attr);
274         return error;
275 }
276
277 void class_device_remove_bin_file(struct class_device *class_dev,
278                                   struct bin_attribute *attr)
279 {
280         if (class_dev)
281                 sysfs_remove_bin_file(&class_dev->kobj, attr);
282 }
283
284 static ssize_t
285 class_device_attr_show(struct kobject * kobj, struct attribute * attr,
286                        char * buf)
287 {
288         struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
289         struct class_device * cd = to_class_dev(kobj);
290         ssize_t ret = 0;
291
292         if (class_dev_attr->show)
293                 ret = class_dev_attr->show(cd, buf);
294         return ret;
295 }
296
297 static ssize_t
298 class_device_attr_store(struct kobject * kobj, struct attribute * attr,
299                         const char * buf, size_t count)
300 {
301         struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
302         struct class_device * cd = to_class_dev(kobj);
303         ssize_t ret = 0;
304
305         if (class_dev_attr->store)
306                 ret = class_dev_attr->store(cd, buf, count);
307         return ret;
308 }
309
310 static struct sysfs_ops class_dev_sysfs_ops = {
311         .show   = class_device_attr_show,
312         .store  = class_device_attr_store,
313 };
314
315 static void class_dev_release(struct kobject * kobj)
316 {
317         struct class_device *cd = to_class_dev(kobj);
318         struct class * cls = cd->class;
319
320         pr_debug("device class '%s': release.\n", cd->class_id);
321
322         if (cd->release)
323                 cd->release(cd);
324         else if (cls->release)
325                 cls->release(cd);
326         else {
327                 printk(KERN_ERR "Class Device '%s' does not have a release() function, "
328                         "it is broken and must be fixed.\n",
329                         cd->class_id);
330                 WARN_ON(1);
331         }
332 }
333
334 static struct kobj_type class_device_ktype = {
335         .sysfs_ops      = &class_dev_sysfs_ops,
336         .release        = class_dev_release,
337 };
338
339 static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
340 {
341         struct kobj_type *ktype = get_ktype(kobj);
342
343         if (ktype == &class_device_ktype) {
344                 struct class_device *class_dev = to_class_dev(kobj);
345                 if (class_dev->class)
346                         return 1;
347         }
348         return 0;
349 }
350
351 static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
352 {
353         struct class_device *class_dev = to_class_dev(kobj);
354
355         return class_dev->class->name;
356 }
357
358 #ifdef CONFIG_SYSFS_DEPRECATED
359 char *make_class_name(const char *name, struct kobject *kobj)
360 {
361         char *class_name;
362         int size;
363
364         size = strlen(name) + strlen(kobject_name(kobj)) + 2;
365
366         class_name = kmalloc(size, GFP_KERNEL);
367         if (!class_name)
368                 return NULL;
369
370         strcpy(class_name, name);
371         strcat(class_name, ":");
372         strcat(class_name, kobject_name(kobj));
373         return class_name;
374 }
375
376 static int make_deprecated_class_device_links(struct class_device *class_dev)
377 {
378         char *class_name;
379         int error;
380
381         if (!class_dev->dev)
382                 return 0;
383
384         class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
385         if (class_name)
386                 error = sysfs_create_link(&class_dev->dev->kobj,
387                                           &class_dev->kobj, class_name);
388         else
389                 error = -ENOMEM;
390         kfree(class_name);
391         return error;
392 }
393
394 static void remove_deprecated_class_device_links(struct class_device *class_dev)
395 {
396         char *class_name;
397
398         if (!class_dev->dev)
399                 return;
400
401         class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
402         if (class_name)
403                 sysfs_remove_link(&class_dev->dev->kobj, class_name);
404         kfree(class_name);
405 }
406 #else
407 static inline int make_deprecated_class_device_links(struct class_device *cd)
408 { return 0; }
409 static void remove_deprecated_class_device_links(struct class_device *cd)
410 { }
411 #endif
412
413 static int class_uevent(struct kset *kset, struct kobject *kobj,
414                         struct kobj_uevent_env *env)
415 {
416         struct class_device *class_dev = to_class_dev(kobj);
417         struct device *dev = class_dev->dev;
418         int retval = 0;
419
420         pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
421
422         if (MAJOR(class_dev->devt)) {
423                 add_uevent_var(env, "MAJOR=%u", MAJOR(class_dev->devt));
424
425                 add_uevent_var(env, "MINOR=%u", MINOR(class_dev->devt));
426         }
427
428         if (dev) {
429                 const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
430                 if (path) {
431                         add_uevent_var(env, "PHYSDEVPATH=%s", path);
432                         kfree(path);
433                 }
434
435                 if (dev->bus)
436                         add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
437
438                 if (dev->driver)
439                         add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
440         }
441
442         if (class_dev->uevent) {
443                 /* have the class device specific function add its stuff */
444                 retval = class_dev->uevent(class_dev, env);
445                 if (retval)
446                         pr_debug("class_dev->uevent() returned %d\n", retval);
447         } else if (class_dev->class->uevent) {
448                 /* have the class specific function add its stuff */
449                 retval = class_dev->class->uevent(class_dev, env);
450                 if (retval)
451                         pr_debug("class->uevent() returned %d\n", retval);
452         }
453
454         return retval;
455 }
456
457 static struct kset_uevent_ops class_uevent_ops = {
458         .filter =       class_uevent_filter,
459         .name =         class_uevent_name,
460         .uevent =       class_uevent,
461 };
462
463 /*
464  * DO NOT copy how this is created, kset_create_and_add() should be
465  * called, but this is a hold-over from the old-way and will be deleted
466  * entirely soon.
467  */
468 static struct kset class_obj_subsys = {
469         .uevent_ops = &class_uevent_ops,
470 };
471
472 static int class_device_add_attrs(struct class_device * cd)
473 {
474         int i;
475         int error = 0;
476         struct class * cls = cd->class;
477
478         if (cls->class_dev_attrs) {
479                 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
480                         error = class_device_create_file(cd,
481                                                          &cls->class_dev_attrs[i]);
482                         if (error)
483                                 goto Err;
484                 }
485         }
486  Done:
487         return error;
488  Err:
489         while (--i >= 0)
490                 class_device_remove_file(cd,&cls->class_dev_attrs[i]);
491         goto Done;
492 }
493
494 static void class_device_remove_attrs(struct class_device * cd)
495 {
496         int i;
497         struct class * cls = cd->class;
498
499         if (cls->class_dev_attrs) {
500                 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
501                         class_device_remove_file(cd,&cls->class_dev_attrs[i]);
502         }
503 }
504
505 static int class_device_add_groups(struct class_device * cd)
506 {
507         int i;
508         int error = 0;
509
510         if (cd->groups) {
511                 for (i = 0; cd->groups[i]; i++) {
512                         error = sysfs_create_group(&cd->kobj, cd->groups[i]);
513                         if (error) {
514                                 while (--i >= 0)
515                                         sysfs_remove_group(&cd->kobj, cd->groups[i]);
516                                 goto out;
517                         }
518                 }
519         }
520 out:
521         return error;
522 }
523
524 static void class_device_remove_groups(struct class_device * cd)
525 {
526         int i;
527         if (cd->groups) {
528                 for (i = 0; cd->groups[i]; i++) {
529                         sysfs_remove_group(&cd->kobj, cd->groups[i]);
530                 }
531         }
532 }
533
534 static ssize_t show_dev(struct class_device *class_dev, char *buf)
535 {
536         return print_dev_t(buf, class_dev->devt);
537 }
538
539 static struct class_device_attribute class_devt_attr =
540         __ATTR(dev, S_IRUGO, show_dev, NULL);
541
542 static ssize_t store_uevent(struct class_device *class_dev,
543                             const char *buf, size_t count)
544 {
545         kobject_uevent(&class_dev->kobj, KOBJ_ADD);
546         return count;
547 }
548
549 static struct class_device_attribute class_uevent_attr =
550         __ATTR(uevent, S_IWUSR, NULL, store_uevent);
551
552 void class_device_initialize(struct class_device *class_dev)
553 {
554         class_dev->kobj.kset = &class_obj_subsys;
555         kobject_init(&class_dev->kobj, &class_device_ktype);
556         INIT_LIST_HEAD(&class_dev->node);
557 }
558
559 int class_device_add(struct class_device *class_dev)
560 {
561         struct class *parent_class = NULL;
562         struct class_device *parent_class_dev = NULL;
563         struct class_interface *class_intf;
564         int error = -EINVAL;
565
566         class_dev = class_device_get(class_dev);
567         if (!class_dev)
568                 return -EINVAL;
569
570         if (!strlen(class_dev->class_id))
571                 goto out1;
572
573         parent_class = class_get(class_dev->class);
574         if (!parent_class)
575                 goto out1;
576
577         parent_class_dev = class_device_get(class_dev->parent);
578
579         pr_debug("CLASS: registering class device: ID = '%s'\n",
580                  class_dev->class_id);
581
582         /* first, register with generic layer. */
583         if (parent_class_dev)
584                 class_dev->kobj.parent = &parent_class_dev->kobj;
585         else
586                 class_dev->kobj.parent = &parent_class->subsys.kobj;
587
588         error = kobject_add(&class_dev->kobj, class_dev->kobj.parent,
589                             "%s", class_dev->class_id);
590         if (error)
591                 goto out2;
592
593         /* add the needed attributes to this device */
594         error = sysfs_create_link(&class_dev->kobj,
595                                   &parent_class->subsys.kobj, "subsystem");
596         if (error)
597                 goto out3;
598
599         error = class_device_create_file(class_dev, &class_uevent_attr);
600         if (error)
601                 goto out3;
602
603         if (MAJOR(class_dev->devt)) {
604                 error = class_device_create_file(class_dev, &class_devt_attr);
605                 if (error)
606                         goto out4;
607         }
608
609         error = class_device_add_attrs(class_dev);
610         if (error)
611                 goto out5;
612
613         if (class_dev->dev) {
614                 error = sysfs_create_link(&class_dev->kobj,
615                                           &class_dev->dev->kobj, "device");
616                 if (error)
617                         goto out6;
618         }
619
620         error = class_device_add_groups(class_dev);
621         if (error)
622                 goto out7;
623
624         error = make_deprecated_class_device_links(class_dev);
625         if (error)
626                 goto out8;
627
628         kobject_uevent(&class_dev->kobj, KOBJ_ADD);
629
630         /* notify any interfaces this device is now here */
631         down(&parent_class->sem);
632         list_add_tail(&class_dev->node, &parent_class->children);
633         list_for_each_entry(class_intf, &parent_class->interfaces, node) {
634                 if (class_intf->add)
635                         class_intf->add(class_dev, class_intf);
636         }
637         up(&parent_class->sem);
638
639         goto out1;
640
641  out8:
642         class_device_remove_groups(class_dev);
643  out7:
644         if (class_dev->dev)
645                 sysfs_remove_link(&class_dev->kobj, "device");
646  out6:
647         class_device_remove_attrs(class_dev);
648  out5:
649         if (MAJOR(class_dev->devt))
650                 class_device_remove_file(class_dev, &class_devt_attr);
651  out4:
652         class_device_remove_file(class_dev, &class_uevent_attr);
653  out3:
654         kobject_del(&class_dev->kobj);
655  out2:
656         if(parent_class_dev)
657                 class_device_put(parent_class_dev);
658         class_put(parent_class);
659  out1:
660         class_device_put(class_dev);
661         return error;
662 }
663
664 int class_device_register(struct class_device *class_dev)
665 {
666         class_device_initialize(class_dev);
667         return class_device_add(class_dev);
668 }
669
670 /**
671  * class_device_create - creates a class device and registers it with sysfs
672  * @cls: pointer to the struct class that this device should be registered to.
673  * @parent: pointer to the parent struct class_device of this new device, if any.
674  * @devt: the dev_t for the char device to be added.
675  * @device: a pointer to a struct device that is assiociated with this class device.
676  * @fmt: string for the class device's name
677  *
678  * This function can be used by char device classes.  A struct
679  * class_device will be created in sysfs, registered to the specified
680  * class.
681  * A "dev" file will be created, showing the dev_t for the device, if
682  * the dev_t is not 0,0.
683  * If a pointer to a parent struct class_device is passed in, the newly
684  * created struct class_device will be a child of that device in sysfs.
685  * The pointer to the struct class_device will be returned from the
686  * call.  Any further sysfs files that might be required can be created
687  * using this pointer.
688  *
689  * Note: the struct class passed to this function must have previously
690  * been created with a call to class_create().
691  */
692 struct class_device *class_device_create(struct class *cls,
693                                          struct class_device *parent,
694                                          dev_t devt,
695                                          struct device *device,
696                                          const char *fmt, ...)
697 {
698         va_list args;
699         struct class_device *class_dev = NULL;
700         int retval = -ENODEV;
701
702         if (cls == NULL || IS_ERR(cls))
703                 goto error;
704
705         class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
706         if (!class_dev) {
707                 retval = -ENOMEM;
708                 goto error;
709         }
710
711         class_dev->devt = devt;
712         class_dev->dev = device;
713         class_dev->class = cls;
714         class_dev->parent = parent;
715         class_dev->release = class_device_create_release;
716         class_dev->uevent = class_device_create_uevent;
717
718         va_start(args, fmt);
719         vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
720         va_end(args);
721         retval = class_device_register(class_dev);
722         if (retval)
723                 goto error;
724
725         return class_dev;
726
727 error:
728         kfree(class_dev);
729         return ERR_PTR(retval);
730 }
731
732 void class_device_del(struct class_device *class_dev)
733 {
734         struct class *parent_class = class_dev->class;
735         struct class_device *parent_device = class_dev->parent;
736         struct class_interface *class_intf;
737
738         if (parent_class) {
739                 down(&parent_class->sem);
740                 list_del_init(&class_dev->node);
741                 list_for_each_entry(class_intf, &parent_class->interfaces, node)
742                         if (class_intf->remove)
743                                 class_intf->remove(class_dev, class_intf);
744                 up(&parent_class->sem);
745         }
746
747         if (class_dev->dev) {
748                 remove_deprecated_class_device_links(class_dev);
749                 sysfs_remove_link(&class_dev->kobj, "device");
750         }
751         sysfs_remove_link(&class_dev->kobj, "subsystem");
752         class_device_remove_file(class_dev, &class_uevent_attr);
753         if (MAJOR(class_dev->devt))
754                 class_device_remove_file(class_dev, &class_devt_attr);
755         class_device_remove_attrs(class_dev);
756         class_device_remove_groups(class_dev);
757
758         kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
759         kobject_del(&class_dev->kobj);
760
761         class_device_put(parent_device);
762         class_put(parent_class);
763 }
764
765 void class_device_unregister(struct class_device *class_dev)
766 {
767         pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
768                  class_dev->class_id);
769         class_device_del(class_dev);
770         class_device_put(class_dev);
771 }
772
773 /**
774  * class_device_destroy - removes a class device that was created with class_device_create()
775  * @cls: the pointer to the struct class that this device was registered * with.
776  * @devt: the dev_t of the device that was previously registered.
777  *
778  * This call unregisters and cleans up a class device that was created with a
779  * call to class_device_create()
780  */
781 void class_device_destroy(struct class *cls, dev_t devt)
782 {
783         struct class_device *class_dev = NULL;
784         struct class_device *class_dev_tmp;
785
786         down(&cls->sem);
787         list_for_each_entry(class_dev_tmp, &cls->children, node) {
788                 if (class_dev_tmp->devt == devt) {
789                         class_dev = class_dev_tmp;
790                         break;
791                 }
792         }
793         up(&cls->sem);
794
795         if (class_dev)
796                 class_device_unregister(class_dev);
797 }
798
799 struct class_device * class_device_get(struct class_device *class_dev)
800 {
801         if (class_dev)
802                 return to_class_dev(kobject_get(&class_dev->kobj));
803         return NULL;
804 }
805
806 void class_device_put(struct class_device *class_dev)
807 {
808         if (class_dev)
809                 kobject_put(&class_dev->kobj);
810 }
811
812
813 int class_interface_register(struct class_interface *class_intf)
814 {
815         struct class *parent;
816         struct class_device *class_dev;
817         struct device *dev;
818
819         if (!class_intf || !class_intf->class)
820                 return -ENODEV;
821
822         parent = class_get(class_intf->class);
823         if (!parent)
824                 return -EINVAL;
825
826         down(&parent->sem);
827         list_add_tail(&class_intf->node, &parent->interfaces);
828         if (class_intf->add) {
829                 list_for_each_entry(class_dev, &parent->children, node)
830                         class_intf->add(class_dev, class_intf);
831         }
832         if (class_intf->add_dev) {
833                 list_for_each_entry(dev, &parent->devices, node)
834                         class_intf->add_dev(dev, class_intf);
835         }
836         up(&parent->sem);
837
838         return 0;
839 }
840
841 void class_interface_unregister(struct class_interface *class_intf)
842 {
843         struct class * parent = class_intf->class;
844         struct class_device *class_dev;
845         struct device *dev;
846
847         if (!parent)
848                 return;
849
850         down(&parent->sem);
851         list_del_init(&class_intf->node);
852         if (class_intf->remove) {
853                 list_for_each_entry(class_dev, &parent->children, node)
854                         class_intf->remove(class_dev, class_intf);
855         }
856         if (class_intf->remove_dev) {
857                 list_for_each_entry(dev, &parent->devices, node)
858                         class_intf->remove_dev(dev, class_intf);
859         }
860         up(&parent->sem);
861
862         class_put(parent);
863 }
864
865 int __init classes_init(void)
866 {
867         class_kset = kset_create_and_add("class", NULL, NULL);
868         if (!class_kset)
869                 return -ENOMEM;
870
871         /* ick, this is ugly, the things we go through to keep from showing up
872          * in sysfs... */
873         kset_init(&class_obj_subsys);
874         kobject_set_name(&class_obj_subsys.kobj, "class_obj");
875         if (!class_obj_subsys.kobj.parent)
876                 class_obj_subsys.kobj.parent = &class_obj_subsys.kobj;
877         return 0;
878 }
879
880 EXPORT_SYMBOL_GPL(class_create_file);
881 EXPORT_SYMBOL_GPL(class_remove_file);
882 EXPORT_SYMBOL_GPL(class_register);
883 EXPORT_SYMBOL_GPL(class_unregister);
884 EXPORT_SYMBOL_GPL(class_create);
885 EXPORT_SYMBOL_GPL(class_destroy);
886
887 EXPORT_SYMBOL_GPL(class_device_register);
888 EXPORT_SYMBOL_GPL(class_device_unregister);
889 EXPORT_SYMBOL_GPL(class_device_initialize);
890 EXPORT_SYMBOL_GPL(class_device_add);
891 EXPORT_SYMBOL_GPL(class_device_del);
892 EXPORT_SYMBOL_GPL(class_device_get);
893 EXPORT_SYMBOL_GPL(class_device_put);
894 EXPORT_SYMBOL_GPL(class_device_create);
895 EXPORT_SYMBOL_GPL(class_device_destroy);
896 EXPORT_SYMBOL_GPL(class_device_create_file);
897 EXPORT_SYMBOL_GPL(class_device_remove_file);
898 EXPORT_SYMBOL_GPL(class_device_create_bin_file);
899 EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
900
901 EXPORT_SYMBOL_GPL(class_interface_register);
902 EXPORT_SYMBOL_GPL(class_interface_unregister);