aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/class.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 16:09:47 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 16:09:47 -0400
commit84860bf0644d7c45afe7ddbd30731c3e3c371fae (patch)
treed6c4b98a9c3fd9981e7fcc5d7729c9e01e327767 /drivers/base/class.c
parent8caf89157d64f1eedba37113afb4b303b2b3e301 (diff)
parent6fbfddcb52d8d9fa2cd209f5ac2a1c87497d55b5 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r--drivers/base/class.c150
1 files changed, 100 insertions, 50 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ce23dc8c18c5..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;
@@ -442,6 +460,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
442 return print_dev_t(buf, class_dev->devt); 460 return print_dev_t(buf, class_dev->devt);
443} 461}
444 462
463static ssize_t store_uevent(struct class_device *class_dev,
464 const char *buf, size_t count)
465{
466 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
467 return count;
468}
469
445void class_device_initialize(struct class_device *class_dev) 470void class_device_initialize(struct class_device *class_dev)
446{ 471{
447 kobj_set_kset_s(class_dev, class_obj_subsys); 472 kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -469,34 +494,45 @@ static char *make_class_name(struct class_device *class_dev)
469 494
470int class_device_add(struct class_device *class_dev) 495int class_device_add(struct class_device *class_dev)
471{ 496{
472 struct class * parent = NULL; 497 struct class *parent_class = NULL;
473 struct class_interface * class_intf; 498 struct class_device *parent_class_dev = NULL;
499 struct class_interface *class_intf;
474 char *class_name = NULL; 500 char *class_name = NULL;
475 int error; 501 int error = -EINVAL;
476 502
477 class_dev = class_device_get(class_dev); 503 class_dev = class_device_get(class_dev);
478 if (!class_dev) 504 if (!class_dev)
479 return -EINVAL; 505 return -EINVAL;
480 506
481 if (!strlen(class_dev->class_id)) { 507 if (!strlen(class_dev->class_id))
482 error = -EINVAL;
483 goto register_done; 508 goto register_done;
484 }
485 509
486 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);
487 514
488 pr_debug("CLASS: registering class device: ID = '%s'\n", 515 pr_debug("CLASS: registering class device: ID = '%s'\n",
489 class_dev->class_id); 516 class_dev->class_id);
490 517
491 /* first, register with generic layer. */ 518 /* first, register with generic layer. */
492 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 519 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
493 if (parent) 520 if (parent_class_dev)
494 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;
495 524
496 if ((error = kobject_add(&class_dev->kobj))) 525 error = kobject_add(&class_dev->kobj);
526 if (error)
497 goto register_done; 527 goto register_done;
498 528
499 /* add the needed attributes to this device */ 529 /* add the needed attributes to this device */
530 class_dev->uevent_attr.attr.name = "uevent";
531 class_dev->uevent_attr.attr.mode = S_IWUSR;
532 class_dev->uevent_attr.attr.owner = parent_class->owner;
533 class_dev->uevent_attr.store = store_uevent;
534 class_device_create_file(class_dev, &class_dev->uevent_attr);
535
500 if (MAJOR(class_dev->devt)) { 536 if (MAJOR(class_dev->devt)) {
501 struct class_device_attribute *attr; 537 struct class_device_attribute *attr;
502 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 538 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
@@ -505,12 +541,10 @@ int class_device_add(struct class_device *class_dev)
505 kobject_del(&class_dev->kobj); 541 kobject_del(&class_dev->kobj);
506 goto register_done; 542 goto register_done;
507 } 543 }
508
509 attr->attr.name = "dev"; 544 attr->attr.name = "dev";
510 attr->attr.mode = S_IRUGO; 545 attr->attr.mode = S_IRUGO;
511 attr->attr.owner = parent->owner; 546 attr->attr.owner = parent_class->owner;
512 attr->show = show_dev; 547 attr->show = show_dev;
513 attr->store = NULL;
514 class_device_create_file(class_dev, attr); 548 class_device_create_file(class_dev, attr);
515 class_dev->devt_attr = attr; 549 class_dev->devt_attr = attr;
516 } 550 }
@@ -524,20 +558,23 @@ int class_device_add(struct class_device *class_dev)
524 class_name); 558 class_name);
525 } 559 }
526 560
561 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
562
527 /* notify any interfaces this device is now here */ 563 /* notify any interfaces this device is now here */
528 if (parent) { 564 if (parent_class) {
529 down(&parent->sem); 565 down(&parent_class->sem);
530 list_add_tail(&class_dev->node, &parent->children); 566 list_add_tail(&class_dev->node, &parent_class->children);
531 list_for_each_entry(class_intf, &parent->interfaces, node) 567 list_for_each_entry(class_intf, &parent_class->interfaces, node)
532 if (class_intf->add) 568 if (class_intf->add)
533 class_intf->add(class_dev); 569 class_intf->add(class_dev, class_intf);
534 up(&parent->sem); 570 up(&parent_class->sem);
535 } 571 }
536 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
537 572
538 register_done: 573 register_done:
539 if (error && parent) 574 if (error) {
540 class_put(parent); 575 class_put(parent_class);
576 class_device_put(parent_class_dev);
577 }
541 class_device_put(class_dev); 578 class_device_put(class_dev);
542 kfree(class_name); 579 kfree(class_name);
543 return error; 580 return error;
@@ -552,21 +589,28 @@ int class_device_register(struct class_device *class_dev)
552/** 589/**
553 * 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
554 * @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.
555 * @dev: the dev_t for the char device to be added. 593 * @dev: the dev_t for the char device to be added.
556 * @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.
557 * @fmt: string for the class device's name 595 * @fmt: string for the class device's name
558 * 596 *
559 * This function can be used by char device classes. A struct 597 * This function can be used by char device classes. A struct
560 * class_device will be created in sysfs, registered to the specified 598 * class_device will be created in sysfs, registered to the specified
561 * class. A "dev" file will be created, showing the dev_t for the 599 * class.
562 * 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
563 * the call. Any further sysfs files that might be required can be 601 * the dev_t is not 0,0.
564 * 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.
565 * 607 *
566 * Note: the struct class passed to this function must have previously 608 * Note: the struct class passed to this function must have previously
567 * been created with a call to class_create(). 609 * been created with a call to class_create().
568 */ 610 */
569struct 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,
570 struct device *device, char *fmt, ...) 614 struct device *device, char *fmt, ...)
571{ 615{
572 va_list args; 616 va_list args;
@@ -585,6 +629,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
585 class_dev->devt = devt; 629 class_dev->devt = devt;
586 class_dev->dev = device; 630 class_dev->dev = device;
587 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;
588 635
589 va_start(args, fmt); 636 va_start(args, fmt);
590 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); 637 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -602,17 +649,18 @@ error:
602 649
603void class_device_del(struct class_device *class_dev) 650void class_device_del(struct class_device *class_dev)
604{ 651{
605 struct class * parent = class_dev->class; 652 struct class *parent_class = class_dev->class;
606 struct class_interface * class_intf; 653 struct class_device *parent_device = class_dev->parent;
654 struct class_interface *class_intf;
607 char *class_name = NULL; 655 char *class_name = NULL;
608 656
609 if (parent) { 657 if (parent_class) {
610 down(&parent->sem); 658 down(&parent_class->sem);
611 list_del_init(&class_dev->node); 659 list_del_init(&class_dev->node);
612 list_for_each_entry(class_intf, &parent->interfaces, node) 660 list_for_each_entry(class_intf, &parent_class->interfaces, node)
613 if (class_intf->remove) 661 if (class_intf->remove)
614 class_intf->remove(class_dev); 662 class_intf->remove(class_dev, class_intf);
615 up(&parent->sem); 663 up(&parent_class->sem);
616 } 664 }
617 665
618 if (class_dev->dev) { 666 if (class_dev->dev) {
@@ -620,6 +668,7 @@ void class_device_del(struct class_device *class_dev)
620 sysfs_remove_link(&class_dev->kobj, "device"); 668 sysfs_remove_link(&class_dev->kobj, "device");
621 sysfs_remove_link(&class_dev->dev->kobj, class_name); 669 sysfs_remove_link(&class_dev->dev->kobj, class_name);
622 } 670 }
671 class_device_remove_file(class_dev, &class_dev->uevent_attr);
623 if (class_dev->devt_attr) 672 if (class_dev->devt_attr)
624 class_device_remove_file(class_dev, class_dev->devt_attr); 673 class_device_remove_file(class_dev, class_dev->devt_attr);
625 class_device_remove_attrs(class_dev); 674 class_device_remove_attrs(class_dev);
@@ -627,8 +676,8 @@ void class_device_del(struct class_device *class_dev)
627 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); 676 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
628 kobject_del(&class_dev->kobj); 677 kobject_del(&class_dev->kobj);
629 678
630 if (parent) 679 class_device_put(parent_device);
631 class_put(parent); 680 class_put(parent_class);
632 kfree(class_name); 681 kfree(class_name);
633} 682}
634 683
@@ -708,7 +757,8 @@ struct class_device * class_device_get(struct class_device *class_dev)
708 757
709void class_device_put(struct class_device *class_dev) 758void class_device_put(struct class_device *class_dev)
710{ 759{
711 kobject_put(&class_dev->kobj); 760 if (class_dev)
761 kobject_put(&class_dev->kobj);
712} 762}
713 763
714 764
@@ -728,7 +778,7 @@ int class_interface_register(struct class_interface *class_intf)
728 list_add_tail(&class_intf->node, &parent->interfaces); 778 list_add_tail(&class_intf->node, &parent->interfaces);
729 if (class_intf->add) { 779 if (class_intf->add) {
730 list_for_each_entry(class_dev, &parent->children, node) 780 list_for_each_entry(class_dev, &parent->children, node)
731 class_intf->add(class_dev); 781 class_intf->add(class_dev, class_intf);
732 } 782 }
733 up(&parent->sem); 783 up(&parent->sem);
734 784
@@ -747,7 +797,7 @@ void class_interface_unregister(struct class_interface *class_intf)
747 list_del_init(&class_intf->node); 797 list_del_init(&class_intf->node);
748 if (class_intf->remove) { 798 if (class_intf->remove) {
749 list_for_each_entry(class_dev, &parent->children, node) 799 list_for_each_entry(class_dev, &parent->children, node)
750 class_intf->remove(class_dev); 800 class_intf->remove(class_dev, class_intf);
751 } 801 }
752 up(&parent->sem); 802 up(&parent->sem);
753 803