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.c171
1 files changed, 102 insertions, 69 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index b32b77ff2dcd..f098881f45b2 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -352,6 +352,92 @@ static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
352 return class_dev->class->name; 352 return class_dev->class->name;
353} 353}
354 354
355#ifdef CONFIG_SYSFS_DEPRECATED
356char *make_class_name(const char *name, struct kobject *kobj)
357{
358 char *class_name;
359 int size;
360
361 size = strlen(name) + strlen(kobject_name(kobj)) + 2;
362
363 class_name = kmalloc(size, GFP_KERNEL);
364 if (!class_name)
365 return ERR_PTR(-ENOMEM);
366
367 strcpy(class_name, name);
368 strcat(class_name, ":");
369 strcat(class_name, kobject_name(kobj));
370 return class_name;
371}
372
373static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index,
374 char *buffer, int buffer_size,
375 int *cur_len,
376 struct class_device *class_dev)
377{
378 struct device *dev = class_dev->dev;
379 char *path;
380
381 if (!dev)
382 return 0;
383
384 /* add device, backing this class device (deprecated) */
385 path = kobject_get_path(&dev->kobj, GFP_KERNEL);
386
387 add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size,
388 cur_len, "PHYSDEVPATH=%s", path);
389 kfree(path);
390
391 if (dev->bus)
392 add_uevent_var(envp, num_envp, cur_index,
393 buffer, buffer_size, cur_len,
394 "PHYSDEVBUS=%s", dev->bus->name);
395
396 if (dev->driver)
397 add_uevent_var(envp, num_envp, cur_index,
398 buffer, buffer_size, cur_len,
399 "PHYSDEVDRIVER=%s", dev->driver->name);
400 return 0;
401}
402
403static int make_deprecated_class_device_links(struct class_device *class_dev)
404{
405 char *class_name;
406 int error;
407
408 if (!class_dev->dev)
409 return 0;
410
411 class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
412 error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
413 class_name);
414 kfree(class_name);
415 return error;
416}
417
418static void remove_deprecated_class_device_links(struct class_device *class_dev)
419{
420 char *class_name;
421
422 if (!class_dev->dev)
423 return;
424
425 class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
426 sysfs_remove_link(&class_dev->dev->kobj, class_name);
427 kfree(class_name);
428}
429#else
430static inline int deprecated_class_uevent(char **envp, int num_envp,
431 int *cur_index, char *buffer,
432 int buffer_size, int *cur_len,
433 struct class_device *class_dev)
434{ return 0; }
435static inline int make_deprecated_class_device_links(struct class_device *cd)
436{ return 0; }
437static void remove_deprecated_class_device_links(struct class_device *cd)
438{ }
439#endif
440
355static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, 441static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
356 int num_envp, char *buffer, int buffer_size) 442 int num_envp, char *buffer, int buffer_size)
357{ 443{
@@ -362,25 +448,8 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
362 448
363 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); 449 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
364 450
365 if (class_dev->dev) { 451 deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size,
366 /* add device, backing this class device (deprecated) */ 452 &length, class_dev);
367 struct device *dev = class_dev->dev;
368 char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
369
370 add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
371 &length, "PHYSDEVPATH=%s", path);
372 kfree(path);
373
374 if (dev->bus)
375 add_uevent_var(envp, num_envp, &i,
376 buffer, buffer_size, &length,
377 "PHYSDEVBUS=%s", dev->bus->name);
378
379 if (dev->driver)
380 add_uevent_var(envp, num_envp, &i,
381 buffer, buffer_size, &length,
382 "PHYSDEVDRIVER=%s", dev->driver->name);
383 }
384 453
385 if (MAJOR(class_dev->devt)) { 454 if (MAJOR(class_dev->devt)) {
386 add_uevent_var(envp, num_envp, &i, 455 add_uevent_var(envp, num_envp, &i,
@@ -506,29 +575,11 @@ void class_device_initialize(struct class_device *class_dev)
506 INIT_LIST_HEAD(&class_dev->node); 575 INIT_LIST_HEAD(&class_dev->node);
507} 576}
508 577
509char *make_class_name(const char *name, struct kobject *kobj)
510{
511 char *class_name;
512 int size;
513
514 size = strlen(name) + strlen(kobject_name(kobj)) + 2;
515
516 class_name = kmalloc(size, GFP_KERNEL);
517 if (!class_name)
518 return ERR_PTR(-ENOMEM);
519
520 strcpy(class_name, name);
521 strcat(class_name, ":");
522 strcat(class_name, kobject_name(kobj));
523 return class_name;
524}
525
526int class_device_add(struct class_device *class_dev) 578int class_device_add(struct class_device *class_dev)
527{ 579{
528 struct class *parent_class = NULL; 580 struct class *parent_class = NULL;
529 struct class_device *parent_class_dev = NULL; 581 struct class_device *parent_class_dev = NULL;
530 struct class_interface *class_intf; 582 struct class_interface *class_intf;
531 char *class_name = NULL;
532 int error = -EINVAL; 583 int error = -EINVAL;
533 584
534 class_dev = class_device_get(class_dev); 585 class_dev = class_device_get(class_dev);
@@ -562,7 +613,10 @@ int class_device_add(struct class_device *class_dev)
562 goto out2; 613 goto out2;
563 614
564 /* add the needed attributes to this device */ 615 /* add the needed attributes to this device */
565 sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem"); 616 error = sysfs_create_link(&class_dev->kobj,
617 &parent_class->subsys.kset.kobj, "subsystem");
618 if (error)
619 goto out3;
566 class_dev->uevent_attr.attr.name = "uevent"; 620 class_dev->uevent_attr.attr.name = "uevent";
567 class_dev->uevent_attr.attr.mode = S_IWUSR; 621 class_dev->uevent_attr.attr.mode = S_IWUSR;
568 class_dev->uevent_attr.attr.owner = parent_class->owner; 622 class_dev->uevent_attr.attr.owner = parent_class->owner;
@@ -596,20 +650,18 @@ int class_device_add(struct class_device *class_dev)
596 goto out5; 650 goto out5;
597 651
598 if (class_dev->dev) { 652 if (class_dev->dev) {
599 class_name = make_class_name(class_dev->class->name,
600 &class_dev->kobj);
601 error = sysfs_create_link(&class_dev->kobj, 653 error = sysfs_create_link(&class_dev->kobj,
602 &class_dev->dev->kobj, "device"); 654 &class_dev->dev->kobj, "device");
603 if (error) 655 if (error)
604 goto out6; 656 goto out6;
605 error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
606 class_name);
607 if (error)
608 goto out7;
609 } 657 }
610 658
611 error = class_device_add_groups(class_dev); 659 error = class_device_add_groups(class_dev);
612 if (error) 660 if (error)
661 goto out7;
662
663 error = make_deprecated_class_device_links(class_dev);
664 if (error)
613 goto out8; 665 goto out8;
614 666
615 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 667 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
@@ -626,8 +678,7 @@ int class_device_add(struct class_device *class_dev)
626 goto out1; 678 goto out1;
627 679
628 out8: 680 out8:
629 if (class_dev->dev) 681 class_device_remove_groups(class_dev);
630 sysfs_remove_link(&class_dev->kobj, class_name);
631 out7: 682 out7:
632 if (class_dev->dev) 683 if (class_dev->dev)
633 sysfs_remove_link(&class_dev->kobj, "device"); 684 sysfs_remove_link(&class_dev->kobj, "device");
@@ -646,7 +697,6 @@ int class_device_add(struct class_device *class_dev)
646 class_put(parent_class); 697 class_put(parent_class);
647 out1: 698 out1:
648 class_device_put(class_dev); 699 class_device_put(class_dev);
649 kfree(class_name);
650 return error; 700 return error;
651} 701}
652 702
@@ -723,7 +773,6 @@ void class_device_del(struct class_device *class_dev)
723 struct class *parent_class = class_dev->class; 773 struct class *parent_class = class_dev->class;
724 struct class_device *parent_device = class_dev->parent; 774 struct class_device *parent_device = class_dev->parent;
725 struct class_interface *class_intf; 775 struct class_interface *class_intf;
726 char *class_name = NULL;
727 776
728 if (parent_class) { 777 if (parent_class) {
729 down(&parent_class->sem); 778 down(&parent_class->sem);
@@ -735,10 +784,8 @@ void class_device_del(struct class_device *class_dev)
735 } 784 }
736 785
737 if (class_dev->dev) { 786 if (class_dev->dev) {
738 class_name = make_class_name(class_dev->class->name, 787 remove_deprecated_class_device_links(class_dev);
739 &class_dev->kobj);
740 sysfs_remove_link(&class_dev->kobj, "device"); 788 sysfs_remove_link(&class_dev->kobj, "device");
741 sysfs_remove_link(&class_dev->dev->kobj, class_name);
742 } 789 }
743 sysfs_remove_link(&class_dev->kobj, "subsystem"); 790 sysfs_remove_link(&class_dev->kobj, "subsystem");
744 class_device_remove_file(class_dev, &class_dev->uevent_attr); 791 class_device_remove_file(class_dev, &class_dev->uevent_attr);
@@ -752,7 +799,6 @@ void class_device_del(struct class_device *class_dev)
752 799
753 class_device_put(parent_device); 800 class_device_put(parent_device);
754 class_put(parent_class); 801 class_put(parent_class);
755 kfree(class_name);
756} 802}
757 803
758void class_device_unregister(struct class_device *class_dev) 804void class_device_unregister(struct class_device *class_dev)
@@ -801,14 +847,17 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
801 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id, 847 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
802 new_name); 848 new_name);
803 849
850#ifdef CONFIG_SYSFS_DEPRECATED
804 if (class_dev->dev) 851 if (class_dev->dev)
805 old_class_name = make_class_name(class_dev->class->name, 852 old_class_name = make_class_name(class_dev->class->name,
806 &class_dev->kobj); 853 &class_dev->kobj);
854#endif
807 855
808 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); 856 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
809 857
810 error = kobject_rename(&class_dev->kobj, new_name); 858 error = kobject_rename(&class_dev->kobj, new_name);
811 859
860#ifdef CONFIG_SYSFS_DEPRECATED
812 if (class_dev->dev) { 861 if (class_dev->dev) {
813 new_class_name = make_class_name(class_dev->class->name, 862 new_class_name = make_class_name(class_dev->class->name,
814 &class_dev->kobj); 863 &class_dev->kobj);
@@ -816,6 +865,7 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
816 new_class_name); 865 new_class_name);
817 sysfs_remove_link(&class_dev->dev->kobj, old_class_name); 866 sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
818 } 867 }
868#endif
819 class_device_put(class_dev); 869 class_device_put(class_dev);
820 870
821 kfree(old_class_name); 871 kfree(old_class_name);
@@ -890,23 +940,6 @@ void class_interface_unregister(struct class_interface *class_intf)
890 class_put(parent); 940 class_put(parent);
891} 941}
892 942
893int virtual_device_parent(struct device *dev)
894{
895 if (!dev->class)
896 return -ENODEV;
897
898 if (!dev->class->virtual_dir) {
899 static struct kobject *virtual_dir = NULL;
900
901 if (!virtual_dir)
902 virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual");
903 dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
904 }
905
906 dev->kobj.parent = dev->class->virtual_dir;
907 return 0;
908}
909
910int __init classes_init(void) 943int __init classes_init(void)
911{ 944{
912 int retval; 945 int retval;