aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r--drivers/base/class.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 0154a1623b21..d207296b18dc 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -452,10 +452,29 @@ void class_device_initialize(struct class_device *class_dev)
452 INIT_LIST_HEAD(&class_dev->node); 452 INIT_LIST_HEAD(&class_dev->node);
453} 453}
454 454
455static char *make_class_name(struct class_device *class_dev)
456{
457 char *name;
458 int size;
459
460 size = strlen(class_dev->class->name) +
461 strlen(kobject_name(&class_dev->kobj)) + 2;
462
463 name = kmalloc(size, GFP_KERNEL);
464 if (!name)
465 return ERR_PTR(-ENOMEM);
466
467 strcpy(name, class_dev->class->name);
468 strcat(name, ":");
469 strcat(name, kobject_name(&class_dev->kobj));
470 return name;
471}
472
455int class_device_add(struct class_device *class_dev) 473int class_device_add(struct class_device *class_dev)
456{ 474{
457 struct class * parent = NULL; 475 struct class * parent = NULL;
458 struct class_interface * class_intf; 476 struct class_interface * class_intf;
477 char *class_name = NULL;
459 int error; 478 int error;
460 479
461 class_dev = class_device_get(class_dev); 480 class_dev = class_device_get(class_dev);
@@ -500,9 +519,13 @@ int class_device_add(struct class_device *class_dev)
500 } 519 }
501 520
502 class_device_add_attrs(class_dev); 521 class_device_add_attrs(class_dev);
503 if (class_dev->dev) 522 if (class_dev->dev) {
523 class_name = make_class_name(class_dev);
504 sysfs_create_link(&class_dev->kobj, 524 sysfs_create_link(&class_dev->kobj,
505 &class_dev->dev->kobj, "device"); 525 &class_dev->dev->kobj, "device");
526 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
527 class_name);
528 }
506 529
507 /* notify any interfaces this device is now here */ 530 /* notify any interfaces this device is now here */
508 if (parent) { 531 if (parent) {
@@ -519,6 +542,7 @@ int class_device_add(struct class_device *class_dev)
519 if (error && parent) 542 if (error && parent)
520 class_put(parent); 543 class_put(parent);
521 class_device_put(class_dev); 544 class_device_put(class_dev);
545 kfree(class_name);
522 return error; 546 return error;
523} 547}
524 548
@@ -584,6 +608,7 @@ void class_device_del(struct class_device *class_dev)
584{ 608{
585 struct class * parent = class_dev->class; 609 struct class * parent = class_dev->class;
586 struct class_interface * class_intf; 610 struct class_interface * class_intf;
611 char *class_name = NULL;
587 612
588 if (parent) { 613 if (parent) {
589 down(&parent->sem); 614 down(&parent->sem);
@@ -594,8 +619,11 @@ void class_device_del(struct class_device *class_dev)
594 up(&parent->sem); 619 up(&parent->sem);
595 } 620 }
596 621
597 if (class_dev->dev) 622 if (class_dev->dev) {
623 class_name = make_class_name(class_dev);
598 sysfs_remove_link(&class_dev->kobj, "device"); 624 sysfs_remove_link(&class_dev->kobj, "device");
625 sysfs_remove_link(&class_dev->dev->kobj, class_name);
626 }
599 if (class_dev->devt_attr) 627 if (class_dev->devt_attr)
600 class_device_remove_file(class_dev, class_dev->devt_attr); 628 class_device_remove_file(class_dev, class_dev->devt_attr);
601 class_device_remove_attrs(class_dev); 629 class_device_remove_attrs(class_dev);
@@ -605,6 +633,7 @@ void class_device_del(struct class_device *class_dev)
605 633
606 if (parent) 634 if (parent)
607 class_put(parent); 635 class_put(parent);
636 kfree(class_name);
608} 637}
609 638
610void class_device_unregister(struct class_device *class_dev) 639void class_device_unregister(struct class_device *class_dev)