aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/class.c125
-rw-r--r--include/linux/device.h13
2 files changed, 91 insertions, 47 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 3cf6eb36f3d8..c3e569730afe 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -99,7 +99,8 @@ struct class * class_get(struct class * cls)
99 99
100void class_put(struct class * cls) 100void class_put(struct class * cls)
101{ 101{
102 subsys_put(&cls->subsys); 102 if (cls)
103 subsys_put(&cls->subsys);
103} 104}
104 105
105 106
@@ -165,14 +166,25 @@ void class_unregister(struct class * cls)
165 166
166static void class_create_release(struct class *cls) 167static void class_create_release(struct class *cls)
167{ 168{
169 pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
168 kfree(cls); 170 kfree(cls);
169} 171}
170 172
171static void class_device_create_release(struct class_device *class_dev) 173static void class_device_create_release(struct class_device *class_dev)
172{ 174{
175 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
173 kfree(class_dev); 176 kfree(class_dev);
174} 177}
175 178
179/* needed to allow these devices to have parent class devices */
180static int class_device_create_hotplug(struct class_device *class_dev,
181 char **envp, int num_envp,
182 char *buffer, int buffer_size)
183{
184 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
185 return 0;
186}
187
176/** 188/**
177 * class_create - create a struct class structure 189 * class_create - create a struct class structure
178 * @owner: pointer to the module that is to "own" this struct class 190 * @owner: pointer to the module that is to "own" this struct class
@@ -301,10 +313,12 @@ static void class_dev_release(struct kobject * kobj)
301 kfree(cd->devt_attr); 313 kfree(cd->devt_attr);
302 cd->devt_attr = NULL; 314 cd->devt_attr = NULL;
303 315
304 if (cls->release) 316 if (cd->release)
317 cd->release(cd);
318 else if (cls->release)
305 cls->release(cd); 319 cls->release(cd);
306 else { 320 else {
307 printk(KERN_ERR "Device class '%s' does not have a release() function, " 321 printk(KERN_ERR "Class Device '%s' does not have a release() function, "
308 "it is broken and must be fixed.\n", 322 "it is broken and must be fixed.\n",
309 cd->class_id); 323 cd->class_id);
310 WARN_ON(1); 324 WARN_ON(1);
@@ -382,14 +396,18 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
382 buffer = &buffer[length]; 396 buffer = &buffer[length];
383 buffer_size -= length; 397 buffer_size -= length;
384 398
385 if (class_dev->class->hotplug) { 399 if (class_dev->hotplug) {
386 /* have the bus specific function add its stuff */ 400 /* have the class device specific function add its stuff */
387 retval = class_dev->class->hotplug (class_dev, envp, num_envp, 401 retval = class_dev->hotplug(class_dev, envp, num_envp,
388 buffer, buffer_size); 402 buffer, buffer_size);
389 if (retval) { 403 if (retval)
390 pr_debug ("%s - hotplug() returned %d\n", 404 pr_debug("class_dev->hotplug() returned %d\n", retval);
391 __FUNCTION__, retval); 405 } else if (class_dev->class->hotplug) {
392 } 406 /* have the class specific function add its stuff */
407 retval = class_dev->class->hotplug(class_dev, envp, num_envp,
408 buffer, buffer_size);
409 if (retval)
410 pr_debug("class->hotplug() returned %d\n", retval);
393 } 411 }
394 412
395 return retval; 413 return retval;
@@ -476,37 +494,42 @@ static char *make_class_name(struct class_device *class_dev)
476 494
477int class_device_add(struct class_device *class_dev) 495int class_device_add(struct class_device *class_dev)
478{ 496{
479 struct class * parent = NULL; 497 struct class *parent_class = NULL;
480 struct class_interface * class_intf; 498 struct class_device *parent_class_dev = NULL;
499 struct class_interface *class_intf;
481 char *class_name = NULL; 500 char *class_name = NULL;
482 int error; 501 int error = -EINVAL;
483 502
484 class_dev = class_device_get(class_dev); 503 class_dev = class_device_get(class_dev);
485 if (!class_dev) 504 if (!class_dev)
486 return -EINVAL; 505 return -EINVAL;
487 506
488 if (!strlen(class_dev->class_id)) { 507 if (!strlen(class_dev->class_id))
489 error = -EINVAL;
490 goto register_done; 508 goto register_done;
491 }
492 509
493 parent = class_get(class_dev->class); 510 parent_class = class_get(class_dev->class);
511 if (!parent_class)
512 goto register_done;
513 parent_class_dev = class_device_get(class_dev->parent);
494 514
495 pr_debug("CLASS: registering class device: ID = '%s'\n", 515 pr_debug("CLASS: registering class device: ID = '%s'\n",
496 class_dev->class_id); 516 class_dev->class_id);
497 517
498 /* first, register with generic layer. */ 518 /* first, register with generic layer. */
499 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 519 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
500 if (parent) 520 if (parent_class_dev)
501 class_dev->kobj.parent = &parent->subsys.kset.kobj; 521 class_dev->kobj.parent = &parent_class_dev->kobj;
522 else
523 class_dev->kobj.parent = &parent_class->subsys.kset.kobj;
502 524
503 if ((error = kobject_add(&class_dev->kobj))) 525 error = kobject_add(&class_dev->kobj);
526 if (error)
504 goto register_done; 527 goto register_done;
505 528
506 /* add the needed attributes to this device */ 529 /* add the needed attributes to this device */
507 class_dev->uevent_attr.attr.name = "uevent"; 530 class_dev->uevent_attr.attr.name = "uevent";
508 class_dev->uevent_attr.attr.mode = S_IWUSR; 531 class_dev->uevent_attr.attr.mode = S_IWUSR;
509 class_dev->uevent_attr.attr.owner = parent->owner; 532 class_dev->uevent_attr.attr.owner = parent_class->owner;
510 class_dev->uevent_attr.store = store_uevent; 533 class_dev->uevent_attr.store = store_uevent;
511 class_device_create_file(class_dev, &class_dev->uevent_attr); 534 class_device_create_file(class_dev, &class_dev->uevent_attr);
512 535
@@ -520,7 +543,7 @@ int class_device_add(struct class_device *class_dev)
520 } 543 }
521 attr->attr.name = "dev"; 544 attr->attr.name = "dev";
522 attr->attr.mode = S_IRUGO; 545 attr->attr.mode = S_IRUGO;
523 attr->attr.owner = parent->owner; 546 attr->attr.owner = parent_class->owner;
524 attr->show = show_dev; 547 attr->show = show_dev;
525 class_device_create_file(class_dev, attr); 548 class_device_create_file(class_dev, attr);
526 class_dev->devt_attr = attr; 549 class_dev->devt_attr = attr;
@@ -538,18 +561,20 @@ int class_device_add(struct class_device *class_dev)
538 kobject_hotplug(&class_dev->kobj, KOBJ_ADD); 561 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
539 562
540 /* notify any interfaces this device is now here */ 563 /* notify any interfaces this device is now here */
541 if (parent) { 564 if (parent_class) {
542 down(&parent->sem); 565 down(&parent_class->sem);
543 list_add_tail(&class_dev->node, &parent->children); 566 list_add_tail(&class_dev->node, &parent_class->children);
544 list_for_each_entry(class_intf, &parent->interfaces, node) 567 list_for_each_entry(class_intf, &parent_class->interfaces, node)
545 if (class_intf->add) 568 if (class_intf->add)
546 class_intf->add(class_dev, class_intf); 569 class_intf->add(class_dev, class_intf);
547 up(&parent->sem); 570 up(&parent_class->sem);
548 } 571 }
549 572
550 register_done: 573 register_done:
551 if (error && parent) 574 if (error) {
552 class_put(parent); 575 class_put(parent_class);
576 class_device_put(parent_class_dev);
577 }
553 class_device_put(class_dev); 578 class_device_put(class_dev);
554 kfree(class_name); 579 kfree(class_name);
555 return error; 580 return error;
@@ -564,21 +589,28 @@ int class_device_register(struct class_device *class_dev)
564/** 589/**
565 * class_device_create - creates a class device and registers it with sysfs 590 * class_device_create - creates a class device and registers it with sysfs
566 * @cs: pointer to the struct class that this device should be registered to. 591 * @cs: pointer to the struct class that this device should be registered to.
592 * @parent: pointer to the parent struct class_device of this new device, if any.
567 * @dev: the dev_t for the char device to be added. 593 * @dev: the dev_t for the char device to be added.
568 * @device: a pointer to a struct device that is assiociated with this class device. 594 * @device: a pointer to a struct device that is assiociated with this class device.
569 * @fmt: string for the class device's name 595 * @fmt: string for the class device's name
570 * 596 *
571 * This function can be used by char device classes. A struct 597 * This function can be used by char device classes. A struct
572 * class_device will be created in sysfs, registered to the specified 598 * class_device will be created in sysfs, registered to the specified
573 * class. A "dev" file will be created, showing the dev_t for the 599 * class.
574 * device. The pointer to the struct class_device will be returned from 600 * A "dev" file will be created, showing the dev_t for the device, if
575 * the call. Any further sysfs files that might be required can be 601 * the dev_t is not 0,0.
576 * created using this pointer. 602 * If a pointer to a parent struct class_device is passed in, the newly
603 * created struct class_device will be a child of that device in sysfs.
604 * The pointer to the struct class_device will be returned from the
605 * call. Any further sysfs files that might be required can be created
606 * using this pointer.
577 * 607 *
578 * Note: the struct class passed to this function must have previously 608 * Note: the struct class passed to this function must have previously
579 * been created with a call to class_create(). 609 * been created with a call to class_create().
580 */ 610 */
581struct class_device *class_device_create(struct class *cls, dev_t devt, 611struct class_device *class_device_create(struct class *cls,
612 struct class_device *parent,
613 dev_t devt,
582 struct device *device, char *fmt, ...) 614 struct device *device, char *fmt, ...)
583{ 615{
584 va_list args; 616 va_list args;
@@ -597,6 +629,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
597 class_dev->devt = devt; 629 class_dev->devt = devt;
598 class_dev->dev = device; 630 class_dev->dev = device;
599 class_dev->class = cls; 631 class_dev->class = cls;
632 class_dev->parent = parent;
633 class_dev->release = class_device_create_release;
634 class_dev->hotplug = class_device_create_hotplug;
600 635
601 va_start(args, fmt); 636 va_start(args, fmt);
602 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); 637 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -614,17 +649,18 @@ error:
614 649
615void class_device_del(struct class_device *class_dev) 650void class_device_del(struct class_device *class_dev)
616{ 651{
617 struct class * parent = class_dev->class; 652 struct class *parent_class = class_dev->class;
618 struct class_interface * class_intf; 653 struct class_device *parent_device = class_dev->parent;
654 struct class_interface *class_intf;
619 char *class_name = NULL; 655 char *class_name = NULL;
620 656
621 if (parent) { 657 if (parent_class) {
622 down(&parent->sem); 658 down(&parent_class->sem);
623 list_del_init(&class_dev->node); 659 list_del_init(&class_dev->node);
624 list_for_each_entry(class_intf, &parent->interfaces, node) 660 list_for_each_entry(class_intf, &parent_class->interfaces, node)
625 if (class_intf->remove) 661 if (class_intf->remove)
626 class_intf->remove(class_dev, class_intf); 662 class_intf->remove(class_dev, class_intf);
627 up(&parent->sem); 663 up(&parent_class->sem);
628 } 664 }
629 665
630 if (class_dev->dev) { 666 if (class_dev->dev) {
@@ -640,8 +676,8 @@ void class_device_del(struct class_device *class_dev)
640 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); 676 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
641 kobject_del(&class_dev->kobj); 677 kobject_del(&class_dev->kobj);
642 678
643 if (parent) 679 class_device_put(parent_device);
644 class_put(parent); 680 class_put(parent_class);
645 kfree(class_name); 681 kfree(class_name);
646} 682}
647 683
@@ -721,7 +757,8 @@ struct class_device * class_device_get(struct class_device *class_dev)
721 757
722void class_device_put(struct class_device *class_dev) 758void class_device_put(struct class_device *class_dev)
723{ 759{
724 kobject_put(&class_dev->kobj); 760 if (class_dev)
761 kobject_put(&class_dev->kobj);
725} 762}
726 763
727 764
diff --git a/include/linux/device.h b/include/linux/device.h
index e86a580b72e1..226e550ae2ea 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -213,7 +213,11 @@ struct class_device {
213 struct class_device_attribute uevent_attr; 213 struct class_device_attribute uevent_attr;
214 struct device * dev; /* not necessary, but nice to have */ 214 struct device * dev; /* not necessary, but nice to have */
215 void * class_data; /* class-specific data */ 215 void * class_data; /* class-specific data */
216 struct class_device *parent; /* parent of this child device, if there is one */
216 217
218 void (*release)(struct class_device *dev);
219 int (*hotplug)(struct class_device *dev, char **envp,
220 int num_envp, char *buffer, int buffer_size);
217 char class_id[BUS_ID_SIZE]; /* unique to this class */ 221 char class_id[BUS_ID_SIZE]; /* unique to this class */
218}; 222};
219 223
@@ -261,9 +265,12 @@ extern void class_interface_unregister(struct class_interface *);
261 265
262extern struct class *class_create(struct module *owner, char *name); 266extern struct class *class_create(struct module *owner, char *name);
263extern void class_destroy(struct class *cls); 267extern void class_destroy(struct class *cls);
264extern struct class_device *class_device_create(struct class *cls, dev_t devt, 268extern struct class_device *class_device_create(struct class *cls,
265 struct device *device, char *fmt, ...) 269 struct class_device *parent,
266 __attribute__((format(printf,4,5))); 270 dev_t devt,
271 struct device *device,
272 char *fmt, ...)
273 __attribute__((format(printf,5,6)));
267extern void class_device_destroy(struct class *cls, dev_t devt); 274extern void class_device_destroy(struct class *cls, dev_t devt);
268 275
269 276