diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-30 17:53:32 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-30 17:53:32 -0400 |
commit | 65fb0d23fcddd8697c871047b700c78817bdaa43 (patch) | |
tree | 119e6e5f276622c4c862f6c9b6d795264ba1603a /drivers/base | |
parent | 8c083f081d0014057901c68a0a3e0f8ca7ac8d23 (diff) | |
parent | dfbbe89e197a77f2c8046a51c74e33e35f878080 (diff) |
Merge branch 'linus' into cpumask-for-linus
Conflicts:
arch/x86/kernel/cpu/common.c
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/base.h | 31 | ||||
-rw-r--r-- | drivers/base/bus.c | 44 | ||||
-rw-r--r-- | drivers/base/core.c | 108 | ||||
-rw-r--r-- | drivers/base/dd.c | 40 | ||||
-rw-r--r-- | drivers/base/driver.c | 15 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 4 | ||||
-rw-r--r-- | drivers/base/iommu.c | 2 | ||||
-rw-r--r-- | drivers/base/platform.c | 60 | ||||
-rw-r--r-- | drivers/base/power/main.c | 44 | ||||
-rw-r--r-- | drivers/base/power/power.h | 8 | ||||
-rw-r--r-- | drivers/base/sys.c | 54 |
11 files changed, 290 insertions, 120 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index 9f50f1b545dc..ddc97496db4a 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -63,6 +63,32 @@ struct class_private { | |||
63 | #define to_class(obj) \ | 63 | #define to_class(obj) \ |
64 | container_of(obj, struct class_private, class_subsys.kobj) | 64 | container_of(obj, struct class_private, class_subsys.kobj) |
65 | 65 | ||
66 | /** | ||
67 | * struct device_private - structure to hold the private to the driver core portions of the device structure. | ||
68 | * | ||
69 | * @klist_children - klist containing all children of this device | ||
70 | * @knode_parent - node in sibling list | ||
71 | * @knode_driver - node in driver list | ||
72 | * @knode_bus - node in bus list | ||
73 | * @device - pointer back to the struct class that this structure is | ||
74 | * associated with. | ||
75 | * | ||
76 | * Nothing outside of the driver core should ever touch these fields. | ||
77 | */ | ||
78 | struct device_private { | ||
79 | struct klist klist_children; | ||
80 | struct klist_node knode_parent; | ||
81 | struct klist_node knode_driver; | ||
82 | struct klist_node knode_bus; | ||
83 | struct device *device; | ||
84 | }; | ||
85 | #define to_device_private_parent(obj) \ | ||
86 | container_of(obj, struct device_private, knode_parent) | ||
87 | #define to_device_private_driver(obj) \ | ||
88 | container_of(obj, struct device_private, knode_driver) | ||
89 | #define to_device_private_bus(obj) \ | ||
90 | container_of(obj, struct device_private, knode_bus) | ||
91 | |||
66 | /* initialisation functions */ | 92 | /* initialisation functions */ |
67 | extern int devices_init(void); | 93 | extern int devices_init(void); |
68 | extern int buses_init(void); | 94 | extern int buses_init(void); |
@@ -86,6 +112,11 @@ extern void bus_remove_driver(struct device_driver *drv); | |||
86 | 112 | ||
87 | extern void driver_detach(struct device_driver *drv); | 113 | extern void driver_detach(struct device_driver *drv); |
88 | extern int driver_probe_device(struct device_driver *drv, struct device *dev); | 114 | extern int driver_probe_device(struct device_driver *drv, struct device *dev); |
115 | static inline int driver_match_device(struct device_driver *drv, | ||
116 | struct device *dev) | ||
117 | { | ||
118 | return drv->bus->match && drv->bus->match(dev, drv); | ||
119 | } | ||
89 | 120 | ||
90 | extern void sysdev_shutdown(void); | 121 | extern void sysdev_shutdown(void); |
91 | 122 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 83f32b891fa9..dc030f1f00f1 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
198 | int err = -ENODEV; | 198 | int err = -ENODEV; |
199 | 199 | ||
200 | dev = bus_find_device_by_name(bus, NULL, buf); | 200 | dev = bus_find_device_by_name(bus, NULL, buf); |
201 | if (dev && dev->driver == NULL) { | 201 | if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { |
202 | if (dev->parent) /* Needed for USB */ | 202 | if (dev->parent) /* Needed for USB */ |
203 | down(&dev->parent->sem); | 203 | down(&dev->parent->sem); |
204 | down(&dev->sem); | 204 | down(&dev->sem); |
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus, | |||
253 | static struct device *next_device(struct klist_iter *i) | 253 | static struct device *next_device(struct klist_iter *i) |
254 | { | 254 | { |
255 | struct klist_node *n = klist_next(i); | 255 | struct klist_node *n = klist_next(i); |
256 | return n ? container_of(n, struct device, knode_bus) : NULL; | 256 | struct device *dev = NULL; |
257 | struct device_private *dev_prv; | ||
258 | |||
259 | if (n) { | ||
260 | dev_prv = to_device_private_bus(n); | ||
261 | dev = dev_prv->device; | ||
262 | } | ||
263 | return dev; | ||
257 | } | 264 | } |
258 | 265 | ||
259 | /** | 266 | /** |
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start, | |||
286 | return -EINVAL; | 293 | return -EINVAL; |
287 | 294 | ||
288 | klist_iter_init_node(&bus->p->klist_devices, &i, | 295 | klist_iter_init_node(&bus->p->klist_devices, &i, |
289 | (start ? &start->knode_bus : NULL)); | 296 | (start ? &start->p->knode_bus : NULL)); |
290 | while ((dev = next_device(&i)) && !error) | 297 | while ((dev = next_device(&i)) && !error) |
291 | error = fn(dev, data); | 298 | error = fn(dev, data); |
292 | klist_iter_exit(&i); | 299 | klist_iter_exit(&i); |
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus, | |||
320 | return NULL; | 327 | return NULL; |
321 | 328 | ||
322 | klist_iter_init_node(&bus->p->klist_devices, &i, | 329 | klist_iter_init_node(&bus->p->klist_devices, &i, |
323 | (start ? &start->knode_bus : NULL)); | 330 | (start ? &start->p->knode_bus : NULL)); |
324 | while ((dev = next_device(&i))) | 331 | while ((dev = next_device(&i))) |
325 | if (match(dev, data) && get_device(dev)) | 332 | if (match(dev, data) && get_device(dev)) |
326 | break; | 333 | break; |
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev) | |||
507 | ret = device_attach(dev); | 514 | ret = device_attach(dev); |
508 | WARN_ON(ret < 0); | 515 | WARN_ON(ret < 0); |
509 | if (ret >= 0) | 516 | if (ret >= 0) |
510 | klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); | 517 | klist_add_tail(&dev->p->knode_bus, |
518 | &bus->p->klist_devices); | ||
511 | } | 519 | } |
512 | } | 520 | } |
513 | 521 | ||
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev) | |||
528 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 536 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
529 | dev_name(dev)); | 537 | dev_name(dev)); |
530 | device_remove_attrs(dev->bus, dev); | 538 | device_remove_attrs(dev->bus, dev); |
531 | if (klist_node_attached(&dev->knode_bus)) | 539 | if (klist_node_attached(&dev->p->knode_bus)) |
532 | klist_del(&dev->knode_bus); | 540 | klist_del(&dev->p->knode_bus); |
533 | 541 | ||
534 | pr_debug("bus: '%s': remove device %s\n", | 542 | pr_debug("bus: '%s': remove device %s\n", |
535 | dev->bus->name, dev_name(dev)); | 543 | dev->bus->name, dev_name(dev)); |
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus) | |||
831 | 839 | ||
832 | static void klist_devices_get(struct klist_node *n) | 840 | static void klist_devices_get(struct klist_node *n) |
833 | { | 841 | { |
834 | struct device *dev = container_of(n, struct device, knode_bus); | 842 | struct device_private *dev_prv = to_device_private_bus(n); |
843 | struct device *dev = dev_prv->device; | ||
835 | 844 | ||
836 | get_device(dev); | 845 | get_device(dev); |
837 | } | 846 | } |
838 | 847 | ||
839 | static void klist_devices_put(struct klist_node *n) | 848 | static void klist_devices_put(struct klist_node *n) |
840 | { | 849 | { |
841 | struct device *dev = container_of(n, struct device, knode_bus); | 850 | struct device_private *dev_prv = to_device_private_bus(n); |
851 | struct device *dev = dev_prv->device; | ||
842 | 852 | ||
843 | put_device(dev); | 853 | put_device(dev); |
844 | } | 854 | } |
@@ -932,6 +942,7 @@ bus_uevent_fail: | |||
932 | kset_unregister(&bus->p->subsys); | 942 | kset_unregister(&bus->p->subsys); |
933 | kfree(bus->p); | 943 | kfree(bus->p); |
934 | out: | 944 | out: |
945 | bus->p = NULL; | ||
935 | return retval; | 946 | return retval; |
936 | } | 947 | } |
937 | EXPORT_SYMBOL_GPL(bus_register); | 948 | EXPORT_SYMBOL_GPL(bus_register); |
@@ -953,6 +964,7 @@ void bus_unregister(struct bus_type *bus) | |||
953 | bus_remove_file(bus, &bus_attr_uevent); | 964 | bus_remove_file(bus, &bus_attr_uevent); |
954 | kset_unregister(&bus->p->subsys); | 965 | kset_unregister(&bus->p->subsys); |
955 | kfree(bus->p); | 966 | kfree(bus->p); |
967 | bus->p = NULL; | ||
956 | } | 968 | } |
957 | EXPORT_SYMBOL_GPL(bus_unregister); | 969 | EXPORT_SYMBOL_GPL(bus_unregister); |
958 | 970 | ||
@@ -993,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list | |||
993 | { | 1005 | { |
994 | struct list_head *pos; | 1006 | struct list_head *pos; |
995 | struct klist_node *n; | 1007 | struct klist_node *n; |
1008 | struct device_private *dev_prv; | ||
996 | struct device *b; | 1009 | struct device *b; |
997 | 1010 | ||
998 | list_for_each(pos, list) { | 1011 | list_for_each(pos, list) { |
999 | n = container_of(pos, struct klist_node, n_node); | 1012 | n = container_of(pos, struct klist_node, n_node); |
1000 | b = container_of(n, struct device, knode_bus); | 1013 | dev_prv = to_device_private_bus(n); |
1014 | b = dev_prv->device; | ||
1001 | if (compare(a, b) <= 0) { | 1015 | if (compare(a, b) <= 0) { |
1002 | list_move_tail(&a->knode_bus.n_node, | 1016 | list_move_tail(&a->p->knode_bus.n_node, |
1003 | &b->knode_bus.n_node); | 1017 | &b->p->knode_bus.n_node); |
1004 | return; | 1018 | return; |
1005 | } | 1019 | } |
1006 | } | 1020 | } |
1007 | list_move_tail(&a->knode_bus.n_node, list); | 1021 | list_move_tail(&a->p->knode_bus.n_node, list); |
1008 | } | 1022 | } |
1009 | 1023 | ||
1010 | void bus_sort_breadthfirst(struct bus_type *bus, | 1024 | void bus_sort_breadthfirst(struct bus_type *bus, |
@@ -1014,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus, | |||
1014 | LIST_HEAD(sorted_devices); | 1028 | LIST_HEAD(sorted_devices); |
1015 | struct list_head *pos, *tmp; | 1029 | struct list_head *pos, *tmp; |
1016 | struct klist_node *n; | 1030 | struct klist_node *n; |
1031 | struct device_private *dev_prv; | ||
1017 | struct device *dev; | 1032 | struct device *dev; |
1018 | struct klist *device_klist; | 1033 | struct klist *device_klist; |
1019 | 1034 | ||
@@ -1022,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus, | |||
1022 | spin_lock(&device_klist->k_lock); | 1037 | spin_lock(&device_klist->k_lock); |
1023 | list_for_each_safe(pos, tmp, &device_klist->k_list) { | 1038 | list_for_each_safe(pos, tmp, &device_klist->k_list) { |
1024 | n = container_of(pos, struct klist_node, n_node); | 1039 | n = container_of(pos, struct klist_node, n_node); |
1025 | dev = container_of(n, struct device, knode_bus); | 1040 | dev_prv = to_device_private_bus(n); |
1041 | dev = dev_prv->device; | ||
1026 | device_insertion_sort_klist(dev, &sorted_devices, compare); | 1042 | device_insertion_sort_klist(dev, &sorted_devices, compare); |
1027 | } | 1043 | } |
1028 | list_splice(&sorted_devices, &device_klist->k_list); | 1044 | list_splice(&sorted_devices, &device_klist->k_list); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index f3eae630e589..e73c92d13a23 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = { | |||
109 | static void device_release(struct kobject *kobj) | 109 | static void device_release(struct kobject *kobj) |
110 | { | 110 | { |
111 | struct device *dev = to_dev(kobj); | 111 | struct device *dev = to_dev(kobj); |
112 | struct device_private *p = dev->p; | ||
112 | 113 | ||
113 | if (dev->release) | 114 | if (dev->release) |
114 | dev->release(dev); | 115 | dev->release(dev); |
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj) | |||
120 | WARN(1, KERN_ERR "Device '%s' does not have a release() " | 121 | WARN(1, KERN_ERR "Device '%s' does not have a release() " |
121 | "function, it is broken and must be fixed.\n", | 122 | "function, it is broken and must be fixed.\n", |
122 | dev_name(dev)); | 123 | dev_name(dev)); |
124 | kfree(p); | ||
123 | } | 125 | } |
124 | 126 | ||
125 | static struct kobj_type device_ktype = { | 127 | static struct kobj_type device_ktype = { |
@@ -134,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
134 | 136 | ||
135 | if (ktype == &device_ktype) { | 137 | if (ktype == &device_ktype) { |
136 | struct device *dev = to_dev(kobj); | 138 | struct device *dev = to_dev(kobj); |
137 | if (dev->uevent_suppress) | ||
138 | return 0; | ||
139 | if (dev->bus) | 139 | if (dev->bus) |
140 | return 1; | 140 | return 1; |
141 | if (dev->class) | 141 | if (dev->class) |
@@ -507,14 +507,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner); | |||
507 | 507 | ||
508 | static void klist_children_get(struct klist_node *n) | 508 | static void klist_children_get(struct klist_node *n) |
509 | { | 509 | { |
510 | struct device *dev = container_of(n, struct device, knode_parent); | 510 | struct device_private *p = to_device_private_parent(n); |
511 | struct device *dev = p->device; | ||
511 | 512 | ||
512 | get_device(dev); | 513 | get_device(dev); |
513 | } | 514 | } |
514 | 515 | ||
515 | static void klist_children_put(struct klist_node *n) | 516 | static void klist_children_put(struct klist_node *n) |
516 | { | 517 | { |
517 | struct device *dev = container_of(n, struct device, knode_parent); | 518 | struct device_private *p = to_device_private_parent(n); |
519 | struct device *dev = p->device; | ||
518 | 520 | ||
519 | put_device(dev); | 521 | put_device(dev); |
520 | } | 522 | } |
@@ -538,8 +540,6 @@ void device_initialize(struct device *dev) | |||
538 | { | 540 | { |
539 | dev->kobj.kset = devices_kset; | 541 | dev->kobj.kset = devices_kset; |
540 | kobject_init(&dev->kobj, &device_ktype); | 542 | kobject_init(&dev->kobj, &device_ktype); |
541 | klist_init(&dev->klist_children, klist_children_get, | ||
542 | klist_children_put); | ||
543 | INIT_LIST_HEAD(&dev->dma_pools); | 543 | INIT_LIST_HEAD(&dev->dma_pools); |
544 | init_MUTEX(&dev->sem); | 544 | init_MUTEX(&dev->sem); |
545 | spin_lock_init(&dev->devres_lock); | 545 | spin_lock_init(&dev->devres_lock); |
@@ -777,17 +777,12 @@ static void device_remove_class_symlinks(struct device *dev) | |||
777 | int dev_set_name(struct device *dev, const char *fmt, ...) | 777 | int dev_set_name(struct device *dev, const char *fmt, ...) |
778 | { | 778 | { |
779 | va_list vargs; | 779 | va_list vargs; |
780 | char *s; | 780 | int err; |
781 | 781 | ||
782 | va_start(vargs, fmt); | 782 | va_start(vargs, fmt); |
783 | vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs); | 783 | err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); |
784 | va_end(vargs); | 784 | va_end(vargs); |
785 | 785 | return err; | |
786 | /* ewww... some of these buggers have / in the name... */ | ||
787 | while ((s = strchr(dev->bus_id, '/'))) | ||
788 | *s = '!'; | ||
789 | |||
790 | return 0; | ||
791 | } | 786 | } |
792 | EXPORT_SYMBOL_GPL(dev_set_name); | 787 | EXPORT_SYMBOL_GPL(dev_set_name); |
793 | 788 | ||
@@ -864,12 +859,26 @@ int device_add(struct device *dev) | |||
864 | if (!dev) | 859 | if (!dev) |
865 | goto done; | 860 | goto done; |
866 | 861 | ||
867 | /* Temporarily support init_name if it is set. | 862 | dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); |
868 | * It will override bus_id for now */ | 863 | if (!dev->p) { |
869 | if (dev->init_name) | 864 | error = -ENOMEM; |
870 | dev_set_name(dev, "%s", dev->init_name); | 865 | goto done; |
866 | } | ||
867 | dev->p->device = dev; | ||
868 | klist_init(&dev->p->klist_children, klist_children_get, | ||
869 | klist_children_put); | ||
870 | |||
871 | /* | ||
872 | * for statically allocated devices, which should all be converted | ||
873 | * some day, we need to initialize the name. We prevent reading back | ||
874 | * the name, and force the use of dev_name() | ||
875 | */ | ||
876 | if (dev->init_name) { | ||
877 | dev_set_name(dev, dev->init_name); | ||
878 | dev->init_name = NULL; | ||
879 | } | ||
871 | 880 | ||
872 | if (!strlen(dev->bus_id)) | 881 | if (!dev_name(dev)) |
873 | goto done; | 882 | goto done; |
874 | 883 | ||
875 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 884 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
@@ -928,7 +937,8 @@ int device_add(struct device *dev) | |||
928 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 937 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
929 | bus_attach_device(dev); | 938 | bus_attach_device(dev); |
930 | if (parent) | 939 | if (parent) |
931 | klist_add_tail(&dev->knode_parent, &parent->klist_children); | 940 | klist_add_tail(&dev->p->knode_parent, |
941 | &parent->p->klist_children); | ||
932 | 942 | ||
933 | if (dev->class) { | 943 | if (dev->class) { |
934 | mutex_lock(&dev->class->p->class_mutex); | 944 | mutex_lock(&dev->class->p->class_mutex); |
@@ -1042,7 +1052,7 @@ void device_del(struct device *dev) | |||
1042 | device_pm_remove(dev); | 1052 | device_pm_remove(dev); |
1043 | dpm_sysfs_remove(dev); | 1053 | dpm_sysfs_remove(dev); |
1044 | if (parent) | 1054 | if (parent) |
1045 | klist_del(&dev->knode_parent); | 1055 | klist_del(&dev->p->knode_parent); |
1046 | if (MAJOR(dev->devt)) { | 1056 | if (MAJOR(dev->devt)) { |
1047 | device_remove_sys_dev_entry(dev); | 1057 | device_remove_sys_dev_entry(dev); |
1048 | device_remove_file(dev, &devt_attr); | 1058 | device_remove_file(dev, &devt_attr); |
@@ -1103,7 +1113,14 @@ void device_unregister(struct device *dev) | |||
1103 | static struct device *next_device(struct klist_iter *i) | 1113 | static struct device *next_device(struct klist_iter *i) |
1104 | { | 1114 | { |
1105 | struct klist_node *n = klist_next(i); | 1115 | struct klist_node *n = klist_next(i); |
1106 | return n ? container_of(n, struct device, knode_parent) : NULL; | 1116 | struct device *dev = NULL; |
1117 | struct device_private *p; | ||
1118 | |||
1119 | if (n) { | ||
1120 | p = to_device_private_parent(n); | ||
1121 | dev = p->device; | ||
1122 | } | ||
1123 | return dev; | ||
1107 | } | 1124 | } |
1108 | 1125 | ||
1109 | /** | 1126 | /** |
@@ -1125,7 +1142,7 @@ int device_for_each_child(struct device *parent, void *data, | |||
1125 | struct device *child; | 1142 | struct device *child; |
1126 | int error = 0; | 1143 | int error = 0; |
1127 | 1144 | ||
1128 | klist_iter_init(&parent->klist_children, &i); | 1145 | klist_iter_init(&parent->p->klist_children, &i); |
1129 | while ((child = next_device(&i)) && !error) | 1146 | while ((child = next_device(&i)) && !error) |
1130 | error = fn(child, data); | 1147 | error = fn(child, data); |
1131 | klist_iter_exit(&i); | 1148 | klist_iter_exit(&i); |
@@ -1156,7 +1173,7 @@ struct device *device_find_child(struct device *parent, void *data, | |||
1156 | if (!parent) | 1173 | if (!parent) |
1157 | return NULL; | 1174 | return NULL; |
1158 | 1175 | ||
1159 | klist_iter_init(&parent->klist_children, &i); | 1176 | klist_iter_init(&parent->p->klist_children, &i); |
1160 | while ((child = next_device(&i))) | 1177 | while ((child = next_device(&i))) |
1161 | if (match(child, data) && get_device(child)) | 1178 | if (match(child, data) && get_device(child)) |
1162 | break; | 1179 | break; |
@@ -1348,7 +1365,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent, | |||
1348 | dev->release = device_create_release; | 1365 | dev->release = device_create_release; |
1349 | dev_set_drvdata(dev, drvdata); | 1366 | dev_set_drvdata(dev, drvdata); |
1350 | 1367 | ||
1351 | vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args); | 1368 | retval = kobject_set_name_vargs(&dev->kobj, fmt, args); |
1369 | if (retval) | ||
1370 | goto error; | ||
1371 | |||
1352 | retval = device_register(dev); | 1372 | retval = device_register(dev); |
1353 | if (retval) | 1373 | if (retval) |
1354 | goto error; | 1374 | goto error; |
@@ -1452,19 +1472,15 @@ int device_rename(struct device *dev, char *new_name) | |||
1452 | old_class_name = make_class_name(dev->class->name, &dev->kobj); | 1472 | old_class_name = make_class_name(dev->class->name, &dev->kobj); |
1453 | #endif | 1473 | #endif |
1454 | 1474 | ||
1455 | old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); | 1475 | old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); |
1456 | if (!old_device_name) { | 1476 | if (!old_device_name) { |
1457 | error = -ENOMEM; | 1477 | error = -ENOMEM; |
1458 | goto out; | 1478 | goto out; |
1459 | } | 1479 | } |
1460 | strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE); | ||
1461 | strlcpy(dev->bus_id, new_name, BUS_ID_SIZE); | ||
1462 | 1480 | ||
1463 | error = kobject_rename(&dev->kobj, new_name); | 1481 | error = kobject_rename(&dev->kobj, new_name); |
1464 | if (error) { | 1482 | if (error) |
1465 | strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE); | ||
1466 | goto out; | 1483 | goto out; |
1467 | } | ||
1468 | 1484 | ||
1469 | #ifdef CONFIG_SYSFS_DEPRECATED | 1485 | #ifdef CONFIG_SYSFS_DEPRECATED |
1470 | if (old_class_name) { | 1486 | if (old_class_name) { |
@@ -1545,8 +1561,10 @@ out: | |||
1545 | * device_move - moves a device to a new parent | 1561 | * device_move - moves a device to a new parent |
1546 | * @dev: the pointer to the struct device to be moved | 1562 | * @dev: the pointer to the struct device to be moved |
1547 | * @new_parent: the new parent of the device (can by NULL) | 1563 | * @new_parent: the new parent of the device (can by NULL) |
1564 | * @dpm_order: how to reorder the dpm_list | ||
1548 | */ | 1565 | */ |
1549 | int device_move(struct device *dev, struct device *new_parent) | 1566 | int device_move(struct device *dev, struct device *new_parent, |
1567 | enum dpm_order dpm_order) | ||
1550 | { | 1568 | { |
1551 | int error; | 1569 | int error; |
1552 | struct device *old_parent; | 1570 | struct device *old_parent; |
@@ -1556,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1556 | if (!dev) | 1574 | if (!dev) |
1557 | return -EINVAL; | 1575 | return -EINVAL; |
1558 | 1576 | ||
1577 | device_pm_lock(); | ||
1559 | new_parent = get_device(new_parent); | 1578 | new_parent = get_device(new_parent); |
1560 | new_parent_kobj = get_device_parent(dev, new_parent); | 1579 | new_parent_kobj = get_device_parent(dev, new_parent); |
1561 | 1580 | ||
@@ -1570,9 +1589,10 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1570 | old_parent = dev->parent; | 1589 | old_parent = dev->parent; |
1571 | dev->parent = new_parent; | 1590 | dev->parent = new_parent; |
1572 | if (old_parent) | 1591 | if (old_parent) |
1573 | klist_remove(&dev->knode_parent); | 1592 | klist_remove(&dev->p->knode_parent); |
1574 | if (new_parent) { | 1593 | if (new_parent) { |
1575 | klist_add_tail(&dev->knode_parent, &new_parent->klist_children); | 1594 | klist_add_tail(&dev->p->knode_parent, |
1595 | &new_parent->p->klist_children); | ||
1576 | set_dev_node(dev, dev_to_node(new_parent)); | 1596 | set_dev_node(dev, dev_to_node(new_parent)); |
1577 | } | 1597 | } |
1578 | 1598 | ||
@@ -1584,11 +1604,11 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1584 | device_move_class_links(dev, new_parent, old_parent); | 1604 | device_move_class_links(dev, new_parent, old_parent); |
1585 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { | 1605 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { |
1586 | if (new_parent) | 1606 | if (new_parent) |
1587 | klist_remove(&dev->knode_parent); | 1607 | klist_remove(&dev->p->knode_parent); |
1588 | dev->parent = old_parent; | 1608 | dev->parent = old_parent; |
1589 | if (old_parent) { | 1609 | if (old_parent) { |
1590 | klist_add_tail(&dev->knode_parent, | 1610 | klist_add_tail(&dev->p->knode_parent, |
1591 | &old_parent->klist_children); | 1611 | &old_parent->p->klist_children); |
1592 | set_dev_node(dev, dev_to_node(old_parent)); | 1612 | set_dev_node(dev, dev_to_node(old_parent)); |
1593 | } | 1613 | } |
1594 | } | 1614 | } |
@@ -1596,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1596 | put_device(new_parent); | 1616 | put_device(new_parent); |
1597 | goto out; | 1617 | goto out; |
1598 | } | 1618 | } |
1619 | switch (dpm_order) { | ||
1620 | case DPM_ORDER_NONE: | ||
1621 | break; | ||
1622 | case DPM_ORDER_DEV_AFTER_PARENT: | ||
1623 | device_pm_move_after(dev, new_parent); | ||
1624 | break; | ||
1625 | case DPM_ORDER_PARENT_BEFORE_DEV: | ||
1626 | device_pm_move_before(new_parent, dev); | ||
1627 | break; | ||
1628 | case DPM_ORDER_DEV_LAST: | ||
1629 | device_pm_move_last(dev); | ||
1630 | break; | ||
1631 | } | ||
1599 | out_put: | 1632 | out_put: |
1600 | put_device(old_parent); | 1633 | put_device(old_parent); |
1601 | out: | 1634 | out: |
1635 | device_pm_unlock(); | ||
1602 | put_device(dev); | 1636 | put_device(dev); |
1603 | return error; | 1637 | return error; |
1604 | } | 1638 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 135231239103..f17c3266a0e0 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static void driver_bound(struct device *dev) | 31 | static void driver_bound(struct device *dev) |
32 | { | 32 | { |
33 | if (klist_node_attached(&dev->knode_driver)) { | 33 | if (klist_node_attached(&dev->p->knode_driver)) { |
34 | printk(KERN_WARNING "%s: device %s already bound\n", | 34 | printk(KERN_WARNING "%s: device %s already bound\n", |
35 | __func__, kobject_name(&dev->kobj)); | 35 | __func__, kobject_name(&dev->kobj)); |
36 | return; | 36 | return; |
@@ -43,7 +43,7 @@ static void driver_bound(struct device *dev) | |||
43 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 43 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
44 | BUS_NOTIFY_BOUND_DRIVER, dev); | 44 | BUS_NOTIFY_BOUND_DRIVER, dev); |
45 | 45 | ||
46 | klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); | 46 | klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); |
47 | } | 47 | } |
48 | 48 | ||
49 | static int driver_sysfs_add(struct device *dev) | 49 | static int driver_sysfs_add(struct device *dev) |
@@ -172,16 +172,12 @@ int driver_probe_done(void) | |||
172 | /** | 172 | /** |
173 | * wait_for_device_probe | 173 | * wait_for_device_probe |
174 | * Wait for device probing to be completed. | 174 | * Wait for device probing to be completed. |
175 | * | ||
176 | * Note: this function polls at 100 msec intervals. | ||
177 | */ | 175 | */ |
178 | int wait_for_device_probe(void) | 176 | void wait_for_device_probe(void) |
179 | { | 177 | { |
180 | /* wait for the known devices to complete their probing */ | 178 | /* wait for the known devices to complete their probing */ |
181 | while (driver_probe_done() != 0) | 179 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); |
182 | msleep(100); | ||
183 | async_synchronize_full(); | 180 | async_synchronize_full(); |
184 | return 0; | ||
185 | } | 181 | } |
186 | 182 | ||
187 | /** | 183 | /** |
@@ -189,14 +185,8 @@ int wait_for_device_probe(void) | |||
189 | * @drv: driver to bind a device to | 185 | * @drv: driver to bind a device to |
190 | * @dev: device to try to bind to the driver | 186 | * @dev: device to try to bind to the driver |
191 | * | 187 | * |
192 | * First, we call the bus's match function, if one present, which should | 188 | * This function returns -ENODEV if the device is not registered, |
193 | * compare the device IDs the driver supports with the device IDs of the | 189 | * 1 if the device is bound sucessfully and 0 otherwise. |
194 | * device. Note we don't do this ourselves because we don't know the | ||
195 | * format of the ID structures, nor what is to be considered a match and | ||
196 | * what is not. | ||
197 | * | ||
198 | * This function returns 1 if a match is found, -ENODEV if the device is | ||
199 | * not registered, and 0 otherwise. | ||
200 | * | 190 | * |
201 | * This function must be called with @dev->sem held. When called for a | 191 | * This function must be called with @dev->sem held. When called for a |
202 | * USB interface, @dev->parent->sem must be held as well. | 192 | * USB interface, @dev->parent->sem must be held as well. |
@@ -207,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
207 | 197 | ||
208 | if (!device_is_registered(dev)) | 198 | if (!device_is_registered(dev)) |
209 | return -ENODEV; | 199 | return -ENODEV; |
210 | if (drv->bus->match && !drv->bus->match(dev, drv)) | ||
211 | goto done; | ||
212 | 200 | ||
213 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", | 201 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", |
214 | drv->bus->name, __func__, dev_name(dev), drv->name); | 202 | drv->bus->name, __func__, dev_name(dev), drv->name); |
215 | 203 | ||
216 | ret = really_probe(dev, drv); | 204 | ret = really_probe(dev, drv); |
217 | 205 | ||
218 | done: | ||
219 | return ret; | 206 | return ret; |
220 | } | 207 | } |
221 | 208 | ||
222 | static int __device_attach(struct device_driver *drv, void *data) | 209 | static int __device_attach(struct device_driver *drv, void *data) |
223 | { | 210 | { |
224 | struct device *dev = data; | 211 | struct device *dev = data; |
212 | |||
213 | if (!driver_match_device(drv, dev)) | ||
214 | return 0; | ||
215 | |||
225 | return driver_probe_device(drv, dev); | 216 | return driver_probe_device(drv, dev); |
226 | } | 217 | } |
227 | 218 | ||
@@ -274,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data) | |||
274 | * is an error. | 265 | * is an error. |
275 | */ | 266 | */ |
276 | 267 | ||
277 | if (drv->bus->match && !drv->bus->match(dev, drv)) | 268 | if (!driver_match_device(drv, dev)) |
278 | return 0; | 269 | return 0; |
279 | 270 | ||
280 | if (dev->parent) /* Needed for USB */ | 271 | if (dev->parent) /* Needed for USB */ |
@@ -327,7 +318,7 @@ static void __device_release_driver(struct device *dev) | |||
327 | drv->remove(dev); | 318 | drv->remove(dev); |
328 | devres_release_all(dev); | 319 | devres_release_all(dev); |
329 | dev->driver = NULL; | 320 | dev->driver = NULL; |
330 | klist_remove(&dev->knode_driver); | 321 | klist_remove(&dev->p->knode_driver); |
331 | } | 322 | } |
332 | } | 323 | } |
333 | 324 | ||
@@ -357,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver); | |||
357 | */ | 348 | */ |
358 | void driver_detach(struct device_driver *drv) | 349 | void driver_detach(struct device_driver *drv) |
359 | { | 350 | { |
351 | struct device_private *dev_prv; | ||
360 | struct device *dev; | 352 | struct device *dev; |
361 | 353 | ||
362 | for (;;) { | 354 | for (;;) { |
@@ -365,8 +357,10 @@ void driver_detach(struct device_driver *drv) | |||
365 | spin_unlock(&drv->p->klist_devices.k_lock); | 357 | spin_unlock(&drv->p->klist_devices.k_lock); |
366 | break; | 358 | break; |
367 | } | 359 | } |
368 | dev = list_entry(drv->p->klist_devices.k_list.prev, | 360 | dev_prv = list_entry(drv->p->klist_devices.k_list.prev, |
369 | struct device, knode_driver.n_node); | 361 | struct device_private, |
362 | knode_driver.n_node); | ||
363 | dev = dev_prv->device; | ||
370 | get_device(dev); | 364 | get_device(dev); |
371 | spin_unlock(&drv->p->klist_devices.k_lock); | 365 | spin_unlock(&drv->p->klist_devices.k_lock); |
372 | 366 | ||
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 1e2bda780e48..c51f11bb29ae 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -19,7 +19,14 @@ | |||
19 | static struct device *next_device(struct klist_iter *i) | 19 | static struct device *next_device(struct klist_iter *i) |
20 | { | 20 | { |
21 | struct klist_node *n = klist_next(i); | 21 | struct klist_node *n = klist_next(i); |
22 | return n ? container_of(n, struct device, knode_driver) : NULL; | 22 | struct device *dev = NULL; |
23 | struct device_private *dev_prv; | ||
24 | |||
25 | if (n) { | ||
26 | dev_prv = to_device_private_driver(n); | ||
27 | dev = dev_prv->device; | ||
28 | } | ||
29 | return dev; | ||
23 | } | 30 | } |
24 | 31 | ||
25 | /** | 32 | /** |
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start, | |||
42 | return -EINVAL; | 49 | return -EINVAL; |
43 | 50 | ||
44 | klist_iter_init_node(&drv->p->klist_devices, &i, | 51 | klist_iter_init_node(&drv->p->klist_devices, &i, |
45 | start ? &start->knode_driver : NULL); | 52 | start ? &start->p->knode_driver : NULL); |
46 | while ((dev = next_device(&i)) && !error) | 53 | while ((dev = next_device(&i)) && !error) |
47 | error = fn(dev, data); | 54 | error = fn(dev, data); |
48 | klist_iter_exit(&i); | 55 | klist_iter_exit(&i); |
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv, | |||
76 | return NULL; | 83 | return NULL; |
77 | 84 | ||
78 | klist_iter_init_node(&drv->p->klist_devices, &i, | 85 | klist_iter_init_node(&drv->p->klist_devices, &i, |
79 | (start ? &start->knode_driver : NULL)); | 86 | (start ? &start->p->knode_driver : NULL)); |
80 | while ((dev = next_device(&i))) | 87 | while ((dev = next_device(&i))) |
81 | if (match(dev, data) && get_device(dev)) | 88 | if (match(dev, data) && get_device(dev)) |
82 | break; | 89 | break; |
@@ -216,6 +223,8 @@ int driver_register(struct device_driver *drv) | |||
216 | int ret; | 223 | int ret; |
217 | struct device_driver *other; | 224 | struct device_driver *other; |
218 | 225 | ||
226 | BUG_ON(!drv->bus->p); | ||
227 | |||
219 | if ((drv->bus->probe && drv->probe) || | 228 | if ((drv->bus->probe && drv->probe) || |
220 | (drv->bus->remove && drv->remove) || | 229 | (drv->bus->remove && drv->remove) || |
221 | (drv->bus->shutdown && drv->shutdown)) | 230 | (drv->bus->shutdown && drv->shutdown)) |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 44699d9dd85c..d3a59c688fe4 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, | |||
319 | f_dev->parent = device; | 319 | f_dev->parent = device; |
320 | f_dev->class = &firmware_class; | 320 | f_dev->class = &firmware_class; |
321 | dev_set_drvdata(f_dev, fw_priv); | 321 | dev_set_drvdata(f_dev, fw_priv); |
322 | f_dev->uevent_suppress = 1; | 322 | dev_set_uevent_suppress(f_dev, 1); |
323 | retval = device_register(f_dev); | 323 | retval = device_register(f_dev); |
324 | if (retval) { | 324 | if (retval) { |
325 | dev_err(device, "%s: device_register failed\n", __func__); | 325 | dev_err(device, "%s: device_register failed\n", __func__); |
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p, | |||
366 | } | 366 | } |
367 | 367 | ||
368 | if (uevent) | 368 | if (uevent) |
369 | f_dev->uevent_suppress = 0; | 369 | dev_set_uevent_suppress(f_dev, 0); |
370 | *dev_p = f_dev; | 370 | *dev_p = f_dev; |
371 | goto out; | 371 | goto out; |
372 | 372 | ||
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c index 5e039d4f877c..c2d1eed90376 100644 --- a/drivers/base/iommu.c +++ b/drivers/base/iommu.c | |||
@@ -31,7 +31,7 @@ void register_iommu(struct iommu_ops *ops) | |||
31 | iommu_ops = ops; | 31 | iommu_ops = ops; |
32 | } | 32 | } |
33 | 33 | ||
34 | bool iommu_found() | 34 | bool iommu_found(void) |
35 | { | 35 | { |
36 | return iommu_ops != NULL; | 36 | return iommu_ops != NULL; |
37 | } | 37 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 349a1013603f..d2198f64ad4e 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, | |||
217 | if (d) { | 217 | if (d) { |
218 | memcpy(d, data, size); | 218 | memcpy(d, data, size); |
219 | pdev->dev.platform_data = d; | 219 | pdev->dev.platform_data = d; |
220 | pdev->platform_data = d; | ||
220 | } | 221 | } |
221 | return d ? 0 : -ENOMEM; | 222 | return d ? 0 : -ENOMEM; |
222 | } | 223 | } |
@@ -246,6 +247,21 @@ int platform_device_add(struct platform_device *pdev) | |||
246 | else | 247 | else |
247 | dev_set_name(&pdev->dev, pdev->name); | 248 | dev_set_name(&pdev->dev, pdev->name); |
248 | 249 | ||
250 | /* We will remove platform_data field from struct device | ||
251 | * if all platform devices pass its platform specific data | ||
252 | * from platform_device. The conversion is going to be a | ||
253 | * long time, so we allow the two cases coexist to make | ||
254 | * this kind of fix more easily*/ | ||
255 | if (pdev->platform_data && pdev->dev.platform_data) { | ||
256 | printk(KERN_ERR | ||
257 | "%s: use which platform_data?\n", | ||
258 | dev_name(&pdev->dev)); | ||
259 | } else if (pdev->platform_data) { | ||
260 | pdev->dev.platform_data = pdev->platform_data; | ||
261 | } else if (pdev->dev.platform_data) { | ||
262 | pdev->platform_data = pdev->dev.platform_data; | ||
263 | } | ||
264 | |||
249 | for (i = 0; i < pdev->num_resources; i++) { | 265 | for (i = 0; i < pdev->num_resources; i++) { |
250 | struct resource *p, *r = &pdev->resource[i]; | 266 | struct resource *p, *r = &pdev->resource[i]; |
251 | 267 | ||
@@ -584,10 +600,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
584 | { | 600 | { |
585 | struct platform_device *pdev = to_platform_device(dev); | 601 | struct platform_device *pdev = to_platform_device(dev); |
586 | 602 | ||
587 | add_uevent_var(env, "MODALIAS=platform:%s", pdev->name); | 603 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
604 | (pdev->id_entry) ? pdev->id_entry->name : pdev->name); | ||
588 | return 0; | 605 | return 0; |
589 | } | 606 | } |
590 | 607 | ||
608 | static const struct platform_device_id *platform_match_id( | ||
609 | struct platform_device_id *id, | ||
610 | struct platform_device *pdev) | ||
611 | { | ||
612 | while (id->name[0]) { | ||
613 | if (strcmp(pdev->name, id->name) == 0) { | ||
614 | pdev->id_entry = id; | ||
615 | return id; | ||
616 | } | ||
617 | id++; | ||
618 | } | ||
619 | return NULL; | ||
620 | } | ||
621 | |||
591 | /** | 622 | /** |
592 | * platform_match - bind platform device to platform driver. | 623 | * platform_match - bind platform device to platform driver. |
593 | * @dev: device. | 624 | * @dev: device. |
@@ -603,9 +634,14 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
603 | */ | 634 | */ |
604 | static int platform_match(struct device *dev, struct device_driver *drv) | 635 | static int platform_match(struct device *dev, struct device_driver *drv) |
605 | { | 636 | { |
606 | struct platform_device *pdev; | 637 | struct platform_device *pdev = to_platform_device(dev); |
638 | struct platform_driver *pdrv = to_platform_driver(drv); | ||
607 | 639 | ||
608 | pdev = container_of(dev, struct platform_device, dev); | 640 | /* match against the id table first */ |
641 | if (pdrv->id_table) | ||
642 | return platform_match_id(pdrv->id_table, pdev) != NULL; | ||
643 | |||
644 | /* fall-back to driver name match */ | ||
609 | return (strcmp(pdev->name, drv->name) == 0); | 645 | return (strcmp(pdev->name, drv->name) == 0); |
610 | } | 646 | } |
611 | 647 | ||
@@ -623,26 +659,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg) | |||
623 | 659 | ||
624 | static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg) | 660 | static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg) |
625 | { | 661 | { |
626 | struct platform_driver *drv = to_platform_driver(dev->driver); | 662 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
627 | struct platform_device *pdev; | 663 | struct platform_device *pdev = to_platform_device(dev); |
628 | int ret = 0; | 664 | int ret = 0; |
629 | 665 | ||
630 | pdev = container_of(dev, struct platform_device, dev); | 666 | if (dev->driver && pdrv->suspend_late) |
631 | if (dev->driver && drv->suspend_late) | 667 | ret = pdrv->suspend_late(pdev, mesg); |
632 | ret = drv->suspend_late(pdev, mesg); | ||
633 | 668 | ||
634 | return ret; | 669 | return ret; |
635 | } | 670 | } |
636 | 671 | ||
637 | static int platform_legacy_resume_early(struct device *dev) | 672 | static int platform_legacy_resume_early(struct device *dev) |
638 | { | 673 | { |
639 | struct platform_driver *drv = to_platform_driver(dev->driver); | 674 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
640 | struct platform_device *pdev; | 675 | struct platform_device *pdev = to_platform_device(dev); |
641 | int ret = 0; | 676 | int ret = 0; |
642 | 677 | ||
643 | pdev = container_of(dev, struct platform_device, dev); | 678 | if (dev->driver && pdrv->resume_early) |
644 | if (dev->driver && drv->resume_early) | 679 | ret = pdrv->resume_early(pdev); |
645 | ret = drv->resume_early(pdev); | ||
646 | 680 | ||
647 | return ret; | 681 | return ret; |
648 | } | 682 | } |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2d14f4ae6c01..e255341682c8 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -107,6 +107,50 @@ void device_pm_remove(struct device *dev) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * device_pm_move_before - move device in dpm_list | ||
111 | * @deva: Device to move in dpm_list | ||
112 | * @devb: Device @deva should come before | ||
113 | */ | ||
114 | void device_pm_move_before(struct device *deva, struct device *devb) | ||
115 | { | ||
116 | pr_debug("PM: Moving %s:%s before %s:%s\n", | ||
117 | deva->bus ? deva->bus->name : "No Bus", | ||
118 | kobject_name(&deva->kobj), | ||
119 | devb->bus ? devb->bus->name : "No Bus", | ||
120 | kobject_name(&devb->kobj)); | ||
121 | /* Delete deva from dpm_list and reinsert before devb. */ | ||
122 | list_move_tail(&deva->power.entry, &devb->power.entry); | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * device_pm_move_after - move device in dpm_list | ||
127 | * @deva: Device to move in dpm_list | ||
128 | * @devb: Device @deva should come after | ||
129 | */ | ||
130 | void device_pm_move_after(struct device *deva, struct device *devb) | ||
131 | { | ||
132 | pr_debug("PM: Moving %s:%s after %s:%s\n", | ||
133 | deva->bus ? deva->bus->name : "No Bus", | ||
134 | kobject_name(&deva->kobj), | ||
135 | devb->bus ? devb->bus->name : "No Bus", | ||
136 | kobject_name(&devb->kobj)); | ||
137 | /* Delete deva from dpm_list and reinsert after devb. */ | ||
138 | list_move(&deva->power.entry, &devb->power.entry); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * device_pm_move_last - move device to end of dpm_list | ||
143 | * @dev: Device to move in dpm_list | ||
144 | */ | ||
145 | void device_pm_move_last(struct device *dev) | ||
146 | { | ||
147 | pr_debug("PM: Moving %s:%s to end of list\n", | ||
148 | dev->bus ? dev->bus->name : "No Bus", | ||
149 | kobject_name(&dev->kobj)); | ||
150 | list_move_tail(&dev->power.entry, &dpm_list); | ||
151 | } | ||
152 | |||
153 | /** | ||
110 | * pm_op - execute the PM operation appropiate for given PM event | 154 | * pm_op - execute the PM operation appropiate for given PM event |
111 | * @dev: Device. | 155 | * @dev: Device. |
112 | * @ops: PM operations to choose from. | 156 | * @ops: PM operations to choose from. |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 41f51fae042f..c7cb4fc3735c 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -18,11 +18,19 @@ static inline struct device *to_device(struct list_head *entry) | |||
18 | 18 | ||
19 | extern void device_pm_add(struct device *); | 19 | extern void device_pm_add(struct device *); |
20 | extern void device_pm_remove(struct device *); | 20 | extern void device_pm_remove(struct device *); |
21 | extern void device_pm_move_before(struct device *, struct device *); | ||
22 | extern void device_pm_move_after(struct device *, struct device *); | ||
23 | extern void device_pm_move_last(struct device *); | ||
21 | 24 | ||
22 | #else /* CONFIG_PM_SLEEP */ | 25 | #else /* CONFIG_PM_SLEEP */ |
23 | 26 | ||
24 | static inline void device_pm_add(struct device *dev) {} | 27 | static inline void device_pm_add(struct device *dev) {} |
25 | static inline void device_pm_remove(struct device *dev) {} | 28 | static inline void device_pm_remove(struct device *dev) {} |
29 | static inline void device_pm_move_before(struct device *deva, | ||
30 | struct device *devb) {} | ||
31 | static inline void device_pm_move_after(struct device *deva, | ||
32 | struct device *devb) {} | ||
33 | static inline void device_pm_move_last(struct device *dev) {} | ||
26 | 34 | ||
27 | #endif | 35 | #endif |
28 | 36 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index b428c8c4bc64..cbd36cf59a0f 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -30,10 +30,10 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | static ssize_t | 32 | static ssize_t |
33 | sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | 33 | sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer) |
34 | { | 34 | { |
35 | struct sys_device * sysdev = to_sysdev(kobj); | 35 | struct sys_device *sysdev = to_sysdev(kobj); |
36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 36 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); |
37 | 37 | ||
38 | if (sysdev_attr->show) | 38 | if (sysdev_attr->show) |
39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); | 39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); |
@@ -42,11 +42,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | |||
42 | 42 | ||
43 | 43 | ||
44 | static ssize_t | 44 | static ssize_t |
45 | sysdev_store(struct kobject * kobj, struct attribute * attr, | 45 | sysdev_store(struct kobject *kobj, struct attribute *attr, |
46 | const char * buffer, size_t count) | 46 | const char *buffer, size_t count) |
47 | { | 47 | { |
48 | struct sys_device * sysdev = to_sysdev(kobj); | 48 | struct sys_device *sysdev = to_sysdev(kobj); |
49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 49 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); |
50 | 50 | ||
51 | if (sysdev_attr->store) | 51 | if (sysdev_attr->store) |
52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); | 52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); |
@@ -63,13 +63,13 @@ static struct kobj_type ktype_sysdev = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | 65 | ||
66 | int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a) | 66 | int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a) |
67 | { | 67 | { |
68 | return sysfs_create_file(&s->kobj, &a->attr); | 68 | return sysfs_create_file(&s->kobj, &a->attr); |
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
72 | void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a) | 72 | void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a) |
73 | { | 73 | { |
74 | sysfs_remove_file(&s->kobj, &a->attr); | 74 | sysfs_remove_file(&s->kobj, &a->attr); |
75 | } | 75 | } |
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file); | |||
84 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | 84 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, |
85 | char *buffer) | 85 | char *buffer) |
86 | { | 86 | { |
87 | struct sysdev_class * class = to_sysdev_class(kobj); | 87 | struct sysdev_class *class = to_sysdev_class(kobj); |
88 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | 88 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
89 | 89 | ||
90 | if (class_attr->show) | 90 | if (class_attr->show) |
@@ -95,8 +95,8 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | |||
95 | static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, | 95 | static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, |
96 | const char *buffer, size_t count) | 96 | const char *buffer, size_t count) |
97 | { | 97 | { |
98 | struct sysdev_class * class = to_sysdev_class(kobj); | 98 | struct sysdev_class *class = to_sysdev_class(kobj); |
99 | struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr); | 99 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
100 | 100 | ||
101 | if (class_attr->store) | 101 | if (class_attr->store) |
102 | return class_attr->store(class, buffer, count); | 102 | return class_attr->store(class, buffer, count); |
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | |||
128 | 128 | ||
129 | static struct kset *system_kset; | 129 | static struct kset *system_kset; |
130 | 130 | ||
131 | int sysdev_class_register(struct sysdev_class * cls) | 131 | int sysdev_class_register(struct sysdev_class *cls) |
132 | { | 132 | { |
133 | pr_debug("Registering sysdev class '%s'\n", cls->name); | 133 | pr_debug("Registering sysdev class '%s'\n", cls->name); |
134 | 134 | ||
@@ -141,7 +141,7 @@ int sysdev_class_register(struct sysdev_class * cls) | |||
141 | return kset_register(&cls->kset); | 141 | return kset_register(&cls->kset); |
142 | } | 142 | } |
143 | 143 | ||
144 | void sysdev_class_unregister(struct sysdev_class * cls) | 144 | void sysdev_class_unregister(struct sysdev_class *cls) |
145 | { | 145 | { |
146 | pr_debug("Unregistering sysdev class '%s'\n", | 146 | pr_debug("Unregistering sysdev class '%s'\n", |
147 | kobject_name(&cls->kset.kobj)); | 147 | kobject_name(&cls->kset.kobj)); |
@@ -203,8 +203,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) | |||
203 | * @cls: Class driver belongs to. | 203 | * @cls: Class driver belongs to. |
204 | * @drv: Driver. | 204 | * @drv: Driver. |
205 | */ | 205 | */ |
206 | void sysdev_driver_unregister(struct sysdev_class * cls, | 206 | void sysdev_driver_unregister(struct sysdev_class *cls, |
207 | struct sysdev_driver * drv) | 207 | struct sysdev_driver *drv) |
208 | { | 208 | { |
209 | mutex_lock(&sysdev_drivers_lock); | 209 | mutex_lock(&sysdev_drivers_lock); |
210 | list_del_init(&drv->entry); | 210 | list_del_init(&drv->entry); |
@@ -229,10 +229,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister); | |||
229 | * @sysdev: device in question | 229 | * @sysdev: device in question |
230 | * | 230 | * |
231 | */ | 231 | */ |
232 | int sysdev_register(struct sys_device * sysdev) | 232 | int sysdev_register(struct sys_device *sysdev) |
233 | { | 233 | { |
234 | int error; | 234 | int error; |
235 | struct sysdev_class * cls = sysdev->cls; | 235 | struct sysdev_class *cls = sysdev->cls; |
236 | 236 | ||
237 | if (!cls) | 237 | if (!cls) |
238 | return -EINVAL; | 238 | return -EINVAL; |
@@ -252,7 +252,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
252 | sysdev->id); | 252 | sysdev->id); |
253 | 253 | ||
254 | if (!error) { | 254 | if (!error) { |
255 | struct sysdev_driver * drv; | 255 | struct sysdev_driver *drv; |
256 | 256 | ||
257 | pr_debug("Registering sys device '%s'\n", | 257 | pr_debug("Registering sys device '%s'\n", |
258 | kobject_name(&sysdev->kobj)); | 258 | kobject_name(&sysdev->kobj)); |
@@ -274,9 +274,9 @@ int sysdev_register(struct sys_device * sysdev) | |||
274 | return error; | 274 | return error; |
275 | } | 275 | } |
276 | 276 | ||
277 | void sysdev_unregister(struct sys_device * sysdev) | 277 | void sysdev_unregister(struct sys_device *sysdev) |
278 | { | 278 | { |
279 | struct sysdev_driver * drv; | 279 | struct sysdev_driver *drv; |
280 | 280 | ||
281 | mutex_lock(&sysdev_drivers_lock); | 281 | mutex_lock(&sysdev_drivers_lock); |
282 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { | 282 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { |
@@ -305,19 +305,19 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
305 | */ | 305 | */ |
306 | void sysdev_shutdown(void) | 306 | void sysdev_shutdown(void) |
307 | { | 307 | { |
308 | struct sysdev_class * cls; | 308 | struct sysdev_class *cls; |
309 | 309 | ||
310 | pr_debug("Shutting Down System Devices\n"); | 310 | pr_debug("Shutting Down System Devices\n"); |
311 | 311 | ||
312 | mutex_lock(&sysdev_drivers_lock); | 312 | mutex_lock(&sysdev_drivers_lock); |
313 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { | 313 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
314 | struct sys_device * sysdev; | 314 | struct sys_device *sysdev; |
315 | 315 | ||
316 | pr_debug("Shutting down type '%s':\n", | 316 | pr_debug("Shutting down type '%s':\n", |
317 | kobject_name(&cls->kset.kobj)); | 317 | kobject_name(&cls->kset.kobj)); |
318 | 318 | ||
319 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | 319 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { |
320 | struct sysdev_driver * drv; | 320 | struct sysdev_driver *drv; |
321 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 321 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
322 | 322 | ||
323 | /* Call auxillary drivers first */ | 323 | /* Call auxillary drivers first */ |
@@ -364,7 +364,7 @@ static void __sysdev_resume(struct sys_device *dev) | |||
364 | */ | 364 | */ |
365 | int sysdev_suspend(pm_message_t state) | 365 | int sysdev_suspend(pm_message_t state) |
366 | { | 366 | { |
367 | struct sysdev_class * cls; | 367 | struct sysdev_class *cls; |
368 | struct sys_device *sysdev, *err_dev; | 368 | struct sys_device *sysdev, *err_dev; |
369 | struct sysdev_driver *drv, *err_drv; | 369 | struct sysdev_driver *drv, *err_drv; |
370 | int ret; | 370 | int ret; |
@@ -442,12 +442,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend); | |||
442 | */ | 442 | */ |
443 | int sysdev_resume(void) | 443 | int sysdev_resume(void) |
444 | { | 444 | { |
445 | struct sysdev_class * cls; | 445 | struct sysdev_class *cls; |
446 | 446 | ||
447 | pr_debug("Resuming System Devices\n"); | 447 | pr_debug("Resuming System Devices\n"); |
448 | 448 | ||
449 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { | 449 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { |
450 | struct sys_device * sysdev; | 450 | struct sys_device *sysdev; |
451 | 451 | ||
452 | pr_debug("Resuming type '%s':\n", | 452 | pr_debug("Resuming type '%s':\n", |
453 | kobject_name(&cls->kset.kobj)); | 453 | kobject_name(&cls->kset.kobj)); |