]> err.no Git - linux-2.6/blob - drivers/base/class.c
Driver core: convert block from raw kobjects to core devices
[linux-2.6] / 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         .kobj = { .k_name = "class_obj", },
470         .uevent_ops = &class_uevent_ops,
471 };
472
473 static int class_device_add_attrs(struct class_device * cd)
474 {
475         int i;
476         int error = 0;
477         struct class * cls = cd->class;
478
479         if (cls->class_dev_attrs) {
480                 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
481                         error = class_device_create_file(cd,
482                                                          &cls->class_dev_attrs[i]);
483                         if (error)
484                                 goto Err;
485                 }
486         }
487  Done:
488         return error;
489  Err:
490         while (--i >= 0)
491                 class_device_remove_file(cd,&cls->class_dev_attrs[i]);
492         goto Done;
493 }
494
495 static void class_device_remove_attrs(struct class_device * cd)
496 {
497         int i;
498         struct class * cls = cd->class;
499
500         if (cls->class_dev_attrs) {
501                 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
502                         class_device_remove_file(cd,&cls->class_dev_attrs[i]);
503         }
504 }
505
506 static int class_device_add_groups(struct class_device * cd)
507 {
508         int i;
509         int error = 0;
510
511         if (cd->groups) {
512                 for (i = 0; cd->groups[i]; i++) {
513                         error = sysfs_create_group(&cd->kobj, cd->groups[i]);
514                         if (error) {
515                                 while (--i >= 0)
516                                         sysfs_remove_group(&cd->kobj, cd->groups[i]);
517                                 goto out;
518                         }
519                 }
520         }
521 out:
522         return error;
523 }
524
525 static void class_device_remove_groups(struct class_device * cd)
526 {
527         int i;
528         if (cd->groups) {
529                 for (i = 0; cd->groups[i]; i++) {
530                         sysfs_remove_group(&cd->kobj, cd->groups[i]);
531                 }
532         }
533 }
534
535 static ssize_t show_dev(struct class_device *class_dev, char *buf)
536 {
537         return print_dev_t(buf, class_dev->devt);
538 }
539
540 static struct class_device_attribute class_devt_attr =
541         __ATTR(dev, S_IRUGO, show_dev, NULL);
542
543 static ssize_t store_uevent(struct class_device *class_dev,
544                             const char *buf, size_t count)
545 {
546         kobject_uevent(&class_dev->kobj, KOBJ_ADD);
547         return count;
548 }
549
550 static struct class_device_attribute class_uevent_attr =
551         __ATTR(uevent, S_IWUSR, NULL, store_uevent);
552
553 void class_device_initialize(struct class_device *class_dev)
554 {
555         class_dev->kobj.kset = &class_obj_subsys;
556         kobject_init_ng(&class_dev->kobj, &class_device_ktype);
557         INIT_LIST_HEAD(&class_dev->node);
558 }
559
560 int class_device_add(struct class_device *class_dev)
561 {
562         struct class *parent_class = NULL;
563         struct class_device *parent_class_dev = NULL;
564         struct class_interface *class_intf;
565         int error = -EINVAL;
566
567         class_dev = class_device_get(class_dev);
568         if (!class_dev)
569                 return -EINVAL;
570
571         if (!strlen(class_dev->class_id))
572                 goto out1;
573
574         parent_class = class_get(class_dev->class);
575         if (!parent_class)
576                 goto out1;
577
578         parent_class_dev = class_device_get(class_dev->parent);
579
580         pr_debug("CLASS: registering class device: ID = '%s'\n",
581                  class_dev->class_id);
582
583         /* first, register with generic layer. */
584         if (parent_class_dev)
585                 class_dev->kobj.parent = &parent_class_dev->kobj;
586         else
587                 class_dev->kobj.parent = &parent_class->subsys.kobj;
588
589         error = kobject_add_ng(&class_dev->kobj, class_dev->kobj.parent,
590                                "%s", class_dev->class_id);
591         if (error)
592                 goto out2;
593
594         /* add the needed attributes to this device */
595         error = sysfs_create_link(&class_dev->kobj,
596                                   &parent_class->subsys.kobj, "subsystem");
597         if (error)
598                 goto out3;
599
600         error = class_device_create_file(class_dev, &class_uevent_attr);
601         if (error)
602                 goto out3;
603
604         if (MAJOR(class_dev->devt)) {
605                 error = class_device_create_file(class_dev, &class_devt_attr);
606                 if (error)
607                         goto out4;
608         }
609
610         error = class_device_add_attrs(class_dev);
611         if (error)
612                 goto out5;
613
614         if (class_dev->dev) {
615                 error = sysfs_create_link(&class_dev->kobj,
616                                           &class_dev->dev->kobj, "device");
617                 if (error)
618                         goto out6;
619         }
620
621         error = class_device_add_groups(class_dev);
622         if (error)
623                 goto out7;
624
625         error = make_deprecated_class_device_links(class_dev);
626         if (error)
627                 goto out8;
628
629         kobject_uevent(&class_dev->kobj, KOBJ_ADD);
630
631         /* notify any interfaces this device is now here */
632         down(&parent_class->sem);
633         list_add_tail(&class_dev->node, &parent_class->children);
634         list_for_each_entry(class_intf, &parent_class->interfaces, node) {
635                 if (class_intf->add)
636                         class_intf->add(class_dev, class_intf);
637         }
638         up(&parent_class->sem);
639
640         goto out1;
641
642  out8:
643         class_device_remove_groups(class_dev);
644  out7:
645         if (class_dev->dev)
646                 sysfs_remove_link(&class_dev->kobj, "device");
647  out6:
648         class_device_remove_attrs(class_dev);
649  out5:
650         if (MAJOR(class_dev->devt))
651                 class_device_remove_file(class_dev, &class_devt_attr);
652  out4:
653         class_device_remove_file(class_dev, &class_uevent_attr);
654  out3:
655         kobject_del(&class_dev->kobj);
656  out2:
657         if(parent_class_dev)
658                 class_device_put(parent_class_dev);
659         class_put(parent_class);
660  out1:
661         class_device_put(class_dev);
662         return error;
663 }
664
665 int class_device_register(struct class_device *class_dev)
666 {
667         class_device_initialize(class_dev);
668         return class_device_add(class_dev);
669 }
670
671 /**
672  * class_device_create - creates a class device and registers it with sysfs
673  * @cls: pointer to the struct class that this device should be registered to.
674  * @parent: pointer to the parent struct class_device of this new device, if any.
675  * @devt: the dev_t for the char device to be added.
676  * @device: a pointer to a struct device that is assiociated with this class device.
677  * @fmt: string for the class device's name
678  *
679  * This function can be used by char device classes.  A struct
680  * class_device will be created in sysfs, registered to the specified
681  * class.
682  * A "dev" file will be created, showing the dev_t for the device, if
683  * the dev_t is not 0,0.
684  * If a pointer to a parent struct class_device is passed in, the newly
685  * created struct class_device will be a child of that device in sysfs.
686  * The pointer to the struct class_device will be returned from the
687  * call.  Any further sysfs files that might be required can be created
688  * using this pointer.
689  *
690  * Note: the struct class passed to this function must have previously
691  * been created with a call to class_create().
692  */
693 struct class_device *class_device_create(struct class *cls,
694                                          struct class_device *parent,
695                                          dev_t devt,
696                                          struct device *device,
697                                          const char *fmt, ...)
698 {
699         va_list args;
700         struct class_device *class_dev = NULL;
701         int retval = -ENODEV;
702
703         if (cls == NULL || IS_ERR(cls))
704                 goto error;
705
706         class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
707         if (!class_dev) {
708                 retval = -ENOMEM;
709                 goto error;
710         }
711
712         class_dev->devt = devt;
713         class_dev->dev = device;
714         class_dev->class = cls;
715         class_dev->parent = parent;
716         class_dev->release = class_device_create_release;
717         class_dev->uevent = class_device_create_uevent;
718
719         va_start(args, fmt);
720         vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
721         va_end(args);
722         retval = class_device_register(class_dev);
723         if (retval)
724                 goto error;
725
726         return class_dev;
727
728 error:
729         kfree(class_dev);
730         return ERR_PTR(retval);
731 }
732
733 void class_device_del(struct class_device *class_dev)
734 {
735         struct class *parent_class = class_dev->class;
736         struct class_device *parent_device = class_dev->parent;
737         struct class_interface *class_intf;
738
739         if (parent_class) {
740                 down(&parent_class->sem);
741                 list_del_init(&class_dev->node);
742                 list_for_each_entry(class_intf, &parent_class->interfaces, node)
743                         if (class_intf->remove)
744                                 class_intf->remove(class_dev, class_intf);
745                 up(&parent_class->sem);
746         }
747
748         if (class_dev->dev) {
749                 remove_deprecated_class_device_links(class_dev);
750                 sysfs_remove_link(&class_dev->kobj, "device");
751         }
752         sysfs_remove_link(&class_dev->kobj, "subsystem");
753         class_device_remove_file(class_dev, &class_uevent_attr);
754         if (MAJOR(class_dev->devt))
755                 class_device_remove_file(class_dev, &class_devt_attr);
756         class_device_remove_attrs(class_dev);
757         class_device_remove_groups(class_dev);
758
759         kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
760         kobject_del(&class_dev->kobj);
761
762         class_device_put(parent_device);
763         class_put(parent_class);
764 }
765
766 void class_device_unregister(struct class_device *class_dev)
767 {
768         pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
769                  class_dev->class_id);
770         class_device_del(class_dev);
771         class_device_put(class_dev);
772 }
773
774 /**
775  * class_device_destroy - removes a class device that was created with class_device_create()
776  * @cls: the pointer to the struct class that this device was registered * with.
777  * @devt: the dev_t of the device that was previously registered.
778  *
779  * This call unregisters and cleans up a class device that was created with a
780  * call to class_device_create()
781  */
782 void class_device_destroy(struct class *cls, dev_t devt)
783 {
784         struct class_device *class_dev = NULL;
785         struct class_device *class_dev_tmp;
786
787         down(&cls->sem);
788         list_for_each_entry(class_dev_tmp, &cls->children, node) {
789                 if (class_dev_tmp->devt == devt) {
790                         class_dev = class_dev_tmp;
791                         break;
792                 }
793         }
794         up(&cls->sem);
795
796         if (class_dev)
797                 class_device_unregister(class_dev);
798 }
799
800 struct class_device * class_device_get(struct class_device *class_dev)
801 {
802         if (class_dev)
803                 return to_class_dev(kobject_get(&class_dev->kobj));
804         return NULL;
805 }
806
807 void class_device_put(struct class_device *class_dev)
808 {
809         if (class_dev)
810                 kobject_put(&class_dev->kobj);
811 }
812
813
814 int class_interface_register(struct class_interface *class_intf)
815 {
816         struct class *parent;
817         struct class_device *class_dev;
818         struct device *dev;
819
820         if (!class_intf || !class_intf->class)
821                 return -ENODEV;
822
823         parent = class_get(class_intf->class);
824         if (!parent)
825                 return -EINVAL;
826
827         down(&parent->sem);
828         list_add_tail(&class_intf->node, &parent->interfaces);
829         if (class_intf->add) {
830                 list_for_each_entry(class_dev, &parent->children, node)
831                         class_intf->add(class_dev, class_intf);
832         }
833         if (class_intf->add_dev) {
834                 list_for_each_entry(dev, &parent->devices, node)
835                         class_intf->add_dev(dev, class_intf);
836         }
837         up(&parent->sem);
838
839         return 0;
840 }
841
842 void class_interface_unregister(struct class_interface *class_intf)
843 {
844         struct class * parent = class_intf->class;
845         struct class_device *class_dev;
846         struct device *dev;
847
848         if (!parent)
849                 return;
850
851         down(&parent->sem);
852         list_del_init(&class_intf->node);
853         if (class_intf->remove) {
854                 list_for_each_entry(class_dev, &parent->children, node)
855                         class_intf->remove(class_dev, class_intf);
856         }
857         if (class_intf->remove_dev) {
858                 list_for_each_entry(dev, &parent->devices, node)
859                         class_intf->remove_dev(dev, class_intf);
860         }
861         up(&parent->sem);
862
863         class_put(parent);
864 }
865
866 int __init classes_init(void)
867 {
868         class_kset = kset_create_and_add("class", NULL, NULL);
869         if (!class_kset)
870                 return -ENOMEM;
871
872         /* ick, this is ugly, the things we go through to keep from showing up
873          * in sysfs... */
874         kset_init(&class_obj_subsys);
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);