aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-04-12 13:50:03 -0400
committerPaul Mackerras <paulus@samba.org>2007-04-12 13:50:03 -0400
commite049d1ca3094f3d1d94617f456a9961202f96e3a (patch)
treea30397ad22f2fbea268bd28fa69c60aad9dfa62a /drivers/base
parentedfac96a92b88d3b0b53e3f8231b74beee9ecd1d (diff)
parent80584ff3b99c36ead7e130e453b3a48b18072d18 (diff)
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c73
-rw-r--r--drivers/base/driver.c9
-rw-r--r--drivers/base/power/main.c6
3 files changed, 62 insertions, 26 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
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1214cbd17d86..082bfded3854 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -183,7 +183,14 @@ int driver_register(struct device_driver * drv)
183void driver_unregister(struct device_driver * drv) 183void driver_unregister(struct device_driver * drv)
184{ 184{
185 bus_remove_driver(drv); 185 bus_remove_driver(drv);
186 wait_for_completion(&drv->unloaded); 186 /*
187 * If the driver is a module, we are probably in
188 * the module unload path, and we want to wait
189 * for everything to unload before we can actually
190 * finish the unload.
191 */
192 if (drv->owner)
193 wait_for_completion(&drv->unloaded);
187} 194}
188 195
189/** 196/**
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index fdfa3d0cf6af..bbbb973a9d3c 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -54,7 +54,8 @@ int device_pm_add(struct device * dev)
54 int error; 54 int error;
55 55
56 pr_debug("PM: Adding info for %s:%s\n", 56 pr_debug("PM: Adding info for %s:%s\n",
57 dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); 57 dev->bus ? dev->bus->name : "No Bus",
58 kobject_name(&dev->kobj));
58 down(&dpm_list_sem); 59 down(&dpm_list_sem);
59 list_add_tail(&dev->power.entry, &dpm_active); 60 list_add_tail(&dev->power.entry, &dpm_active);
60 device_pm_set_parent(dev, dev->parent); 61 device_pm_set_parent(dev, dev->parent);
@@ -67,7 +68,8 @@ int device_pm_add(struct device * dev)
67void device_pm_remove(struct device * dev) 68void device_pm_remove(struct device * dev)
68{ 69{
69 pr_debug("PM: Removing info for %s:%s\n", 70 pr_debug("PM: Removing info for %s:%s\n",
70 dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); 71 dev->bus ? dev->bus->name : "No Bus",
72 kobject_name(&dev->kobj));
71 down(&dpm_list_sem); 73 down(&dpm_list_sem);
72 dpm_sysfs_remove(dev); 74 dpm_sysfs_remove(dev);
73 put_device(dev->power.pm_parent); 75 put_device(dev->power.pm_parent);