aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index cf2a398aaaa1..d7fcf823a42a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -28,20 +28,6 @@ int (*platform_notify)(struct device * dev) = NULL;
28int (*platform_notify_remove)(struct device * dev) = NULL; 28int (*platform_notify_remove)(struct device * dev) = NULL;
29 29
30/* 30/*
31 * Detect the LANANA-assigned LOCAL/EXPERIMENTAL majors
32 */
33bool is_lanana_major(unsigned int major)
34{
35 if (major >= 60 && major <= 63)
36 return 1;
37 if (major >= 120 && major <= 127)
38 return 1;
39 if (major >= 240 && major <= 254)
40 return 1;
41 return 0;
42}
43
44/*
45 * sysfs bindings for devices. 31 * sysfs bindings for devices.
46 */ 32 */
47 33
@@ -407,6 +393,35 @@ void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
407} 393}
408EXPORT_SYMBOL_GPL(device_remove_bin_file); 394EXPORT_SYMBOL_GPL(device_remove_bin_file);
409 395
396/**
397 * device_schedule_callback - helper to schedule a callback for a device
398 * @dev: device.
399 * @func: callback function to invoke later.
400 *
401 * Attribute methods must not unregister themselves or their parent device
402 * (which would amount to the same thing). Attempts to do so will deadlock,
403 * since unregistration is mutually exclusive with driver callbacks.
404 *
405 * Instead methods can call this routine, which will attempt to allocate
406 * and schedule a workqueue request to call back @func with @dev as its
407 * argument in the workqueue's process context. @dev will be pinned until
408 * @func returns.
409 *
410 * Returns 0 if the request was submitted, -ENOMEM if storage could not
411 * be allocated.
412 *
413 * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an
414 * underlying sysfs routine (since it is intended for use by attribute
415 * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
416 */
417int device_schedule_callback(struct device *dev,
418 void (*func)(struct device *))
419{
420 return sysfs_schedule_callback(&dev->kobj,
421 (void (*)(void *)) func, dev);
422}
423EXPORT_SYMBOL_GPL(device_schedule_callback);
424
410static void klist_children_get(struct klist_node *n) 425static void klist_children_get(struct klist_node *n)
411{ 426{
412 struct device *dev = container_of(n, struct device, knode_parent); 427 struct device *dev = container_of(n, struct device, knode_parent);
@@ -584,17 +599,17 @@ int device_add(struct device *dev)
584 if (dev->kobj.parent != &dev->class->subsys.kset.kobj) 599 if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
585 sysfs_create_link(&dev->class->subsys.kset.kobj, 600 sysfs_create_link(&dev->class->subsys.kset.kobj,
586 &dev->kobj, dev->bus_id); 601 &dev->kobj, dev->bus_id);
587#ifdef CONFIG_SYSFS_DEPRECATED
588 if (parent) { 602 if (parent) {
589 sysfs_create_link(&dev->kobj, &dev->parent->kobj, 603 sysfs_create_link(&dev->kobj, &dev->parent->kobj,
590 "device"); 604 "device");
605#ifdef CONFIG_SYSFS_DEPRECATED
591 class_name = make_class_name(dev->class->name, 606 class_name = make_class_name(dev->class->name,
592 &dev->kobj); 607 &dev->kobj);
593 if (class_name) 608 if (class_name)
594 sysfs_create_link(&dev->parent->kobj, 609 sysfs_create_link(&dev->parent->kobj,
595 &dev->kobj, class_name); 610 &dev->kobj, class_name);
596 }
597#endif 611#endif
612 }
598 } 613 }
599 614
600 if ((error = device_add_attrs(dev))) 615 if ((error = device_add_attrs(dev)))
@@ -651,17 +666,17 @@ int device_add(struct device *dev)
651 if (dev->kobj.parent != &dev->class->subsys.kset.kobj) 666 if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
652 sysfs_remove_link(&dev->class->subsys.kset.kobj, 667 sysfs_remove_link(&dev->class->subsys.kset.kobj,
653 dev->bus_id); 668 dev->bus_id);
654#ifdef CONFIG_SYSFS_DEPRECATED
655 if (parent) { 669 if (parent) {
670#ifdef CONFIG_SYSFS_DEPRECATED
656 char *class_name = make_class_name(dev->class->name, 671 char *class_name = make_class_name(dev->class->name,
657 &dev->kobj); 672 &dev->kobj);
658 if (class_name) 673 if (class_name)
659 sysfs_remove_link(&dev->parent->kobj, 674 sysfs_remove_link(&dev->parent->kobj,
660 class_name); 675 class_name);
661 kfree(class_name); 676 kfree(class_name);
677#endif
662 sysfs_remove_link(&dev->kobj, "device"); 678 sysfs_remove_link(&dev->kobj, "device");
663 } 679 }
664#endif
665 680
666 down(&dev->class->sem); 681 down(&dev->class->sem);
667 /* notify any interfaces that the device is now gone */ 682 /* notify any interfaces that the device is now gone */
@@ -761,17 +776,17 @@ void device_del(struct device * dev)
761 if (dev->kobj.parent != &dev->class->subsys.kset.kobj) 776 if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
762 sysfs_remove_link(&dev->class->subsys.kset.kobj, 777 sysfs_remove_link(&dev->class->subsys.kset.kobj,
763 dev->bus_id); 778 dev->bus_id);
764#ifdef CONFIG_SYSFS_DEPRECATED
765 if (parent) { 779 if (parent) {
780#ifdef CONFIG_SYSFS_DEPRECATED
766 char *class_name = make_class_name(dev->class->name, 781 char *class_name = make_class_name(dev->class->name,
767 &dev->kobj); 782 &dev->kobj);
768 if (class_name) 783 if (class_name)
769 sysfs_remove_link(&dev->parent->kobj, 784 sysfs_remove_link(&dev->parent->kobj,
770 class_name); 785 class_name);
771 kfree(class_name); 786 kfree(class_name);
787#endif
772 sysfs_remove_link(&dev->kobj, "device"); 788 sysfs_remove_link(&dev->kobj, "device");
773 } 789 }
774#endif
775 790
776 down(&dev->class->sem); 791 down(&dev->class->sem);
777 /* notify any interfaces that the device is now gone */ 792 /* notify any interfaces that the device is now gone */
@@ -787,6 +802,13 @@ void device_del(struct device * dev)
787 device_remove_attrs(dev); 802 device_remove_attrs(dev);
788 bus_remove_device(dev); 803 bus_remove_device(dev);
789 804
805 /*
806 * Some platform devices are driven without driver attached
807 * and managed resources may have been acquired. Make sure
808 * all resources are released.
809 */
810 devres_release_all(dev);
811
790 /* Notify the platform of the removal, in case they 812 /* Notify the platform of the removal, in case they
791 * need to do anything... 813 * need to do anything...
792 */ 814 */
@@ -1058,14 +1080,14 @@ int device_rename(struct device *dev, char *new_name)
1058 1080
1059 return error; 1081 return error;
1060} 1082}
1061 1083EXPORT_SYMBOL_GPL(device_rename);
1062 1084
1063static int device_move_class_links(struct device *dev, 1085static int device_move_class_links(struct device *dev,
1064 struct device *old_parent, 1086 struct device *old_parent,
1065 struct device *new_parent) 1087 struct device *new_parent)
1066{ 1088{
1089 int error = 0;
1067#ifdef CONFIG_SYSFS_DEPRECATED 1090#ifdef CONFIG_SYSFS_DEPRECATED
1068 int error;
1069 char *class_name; 1091 char *class_name;
1070 1092
1071 class_name = make_class_name(dev->class->name, &dev->kobj); 1093 class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -1093,7 +1115,12 @@ out:
1093 kfree(class_name); 1115 kfree(class_name);
1094 return error; 1116 return error;
1095#else 1117#else
1096 return 0; 1118 if (old_parent)
1119 sysfs_remove_link(&dev->kobj, "device");
1120 if (new_parent)
1121 error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
1122 "device");
1123 return error;
1097#endif 1124#endif
1098} 1125}
1099 1126