diff options
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/cpu.c | 4 | ||||
-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 | 64 | ||||
-rw-r--r-- | drivers/base/power/power.h | 8 | ||||
-rw-r--r-- | drivers/base/sys.c | 62 | ||||
-rw-r--r-- | drivers/base/topology.c | 33 |
13 files changed, 327 insertions, 148 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/cpu.c b/drivers/base/cpu.c index 719ee5c1c8d9..e62a4ccea54d 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -107,7 +107,7 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); | |||
107 | /* | 107 | /* |
108 | * Print cpu online, possible, present, and system maps | 108 | * Print cpu online, possible, present, and system maps |
109 | */ | 109 | */ |
110 | static ssize_t print_cpus_map(char *buf, cpumask_t *map) | 110 | static ssize_t print_cpus_map(char *buf, const struct cpumask *map) |
111 | { | 111 | { |
112 | int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map); | 112 | int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map); |
113 | 113 | ||
@@ -119,7 +119,7 @@ static ssize_t print_cpus_map(char *buf, cpumask_t *map) | |||
119 | #define print_cpus_func(type) \ | 119 | #define print_cpus_func(type) \ |
120 | static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ | 120 | static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ |
121 | { \ | 121 | { \ |
122 | return print_cpus_map(buf, &cpu_##type##_map); \ | 122 | return print_cpus_map(buf, cpu_##type##_mask); \ |
123 | } \ | 123 | } \ |
124 | static struct sysdev_class_attribute attr_##type##_map = \ | 124 | static struct sysdev_class_attribute attr_##type##_map = \ |
125 | _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL) | 125 | _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL) |
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 c314f144825f..9f0e672f4be8 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..69b4ddb7de3b 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/resume-trace.h> | 24 | #include <linux/resume-trace.h> |
25 | #include <linux/rwsem.h> | 25 | #include <linux/rwsem.h> |
26 | #include <linux/interrupt.h> | ||
26 | 27 | ||
27 | #include "../base.h" | 28 | #include "../base.h" |
28 | #include "power.h" | 29 | #include "power.h" |
@@ -107,6 +108,50 @@ void device_pm_remove(struct device *dev) | |||
107 | } | 108 | } |
108 | 109 | ||
109 | /** | 110 | /** |
111 | * device_pm_move_before - move device in dpm_list | ||
112 | * @deva: Device to move in dpm_list | ||
113 | * @devb: Device @deva should come before | ||
114 | */ | ||
115 | void device_pm_move_before(struct device *deva, struct device *devb) | ||
116 | { | ||
117 | pr_debug("PM: Moving %s:%s before %s:%s\n", | ||
118 | deva->bus ? deva->bus->name : "No Bus", | ||
119 | kobject_name(&deva->kobj), | ||
120 | devb->bus ? devb->bus->name : "No Bus", | ||
121 | kobject_name(&devb->kobj)); | ||
122 | /* Delete deva from dpm_list and reinsert before devb. */ | ||
123 | list_move_tail(&deva->power.entry, &devb->power.entry); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * device_pm_move_after - move device in dpm_list | ||
128 | * @deva: Device to move in dpm_list | ||
129 | * @devb: Device @deva should come after | ||
130 | */ | ||
131 | void device_pm_move_after(struct device *deva, struct device *devb) | ||
132 | { | ||
133 | pr_debug("PM: Moving %s:%s after %s:%s\n", | ||
134 | deva->bus ? deva->bus->name : "No Bus", | ||
135 | kobject_name(&deva->kobj), | ||
136 | devb->bus ? devb->bus->name : "No Bus", | ||
137 | kobject_name(&devb->kobj)); | ||
138 | /* Delete deva from dpm_list and reinsert after devb. */ | ||
139 | list_move(&deva->power.entry, &devb->power.entry); | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * device_pm_move_last - move device to end of dpm_list | ||
144 | * @dev: Device to move in dpm_list | ||
145 | */ | ||
146 | void device_pm_move_last(struct device *dev) | ||
147 | { | ||
148 | pr_debug("PM: Moving %s:%s to end of list\n", | ||
149 | dev->bus ? dev->bus->name : "No Bus", | ||
150 | kobject_name(&dev->kobj)); | ||
151 | list_move_tail(&dev->power.entry, &dpm_list); | ||
152 | } | ||
153 | |||
154 | /** | ||
110 | * pm_op - execute the PM operation appropiate for given PM event | 155 | * pm_op - execute the PM operation appropiate for given PM event |
111 | * @dev: Device. | 156 | * @dev: Device. |
112 | * @ops: PM operations to choose from. | 157 | * @ops: PM operations to choose from. |
@@ -305,7 +350,8 @@ static int resume_device_noirq(struct device *dev, pm_message_t state) | |||
305 | * Execute the appropriate "noirq resume" callback for all devices marked | 350 | * Execute the appropriate "noirq resume" callback for all devices marked |
306 | * as DPM_OFF_IRQ. | 351 | * as DPM_OFF_IRQ. |
307 | * | 352 | * |
308 | * Must be called with interrupts disabled and only one CPU running. | 353 | * Must be called under dpm_list_mtx. Device drivers should not receive |
354 | * interrupts while it's being executed. | ||
309 | */ | 355 | */ |
310 | static void dpm_power_up(pm_message_t state) | 356 | static void dpm_power_up(pm_message_t state) |
311 | { | 357 | { |
@@ -326,14 +372,13 @@ static void dpm_power_up(pm_message_t state) | |||
326 | * device_power_up - Turn on all devices that need special attention. | 372 | * device_power_up - Turn on all devices that need special attention. |
327 | * @state: PM transition of the system being carried out. | 373 | * @state: PM transition of the system being carried out. |
328 | * | 374 | * |
329 | * Power on system devices, then devices that required we shut them down | 375 | * Call the "early" resume handlers and enable device drivers to receive |
330 | * with interrupts disabled. | 376 | * interrupts. |
331 | * | ||
332 | * Must be called with interrupts disabled. | ||
333 | */ | 377 | */ |
334 | void device_power_up(pm_message_t state) | 378 | void device_power_up(pm_message_t state) |
335 | { | 379 | { |
336 | dpm_power_up(state); | 380 | dpm_power_up(state); |
381 | resume_device_irqs(); | ||
337 | } | 382 | } |
338 | EXPORT_SYMBOL_GPL(device_power_up); | 383 | EXPORT_SYMBOL_GPL(device_power_up); |
339 | 384 | ||
@@ -558,16 +603,17 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state) | |||
558 | * device_power_down - Shut down special devices. | 603 | * device_power_down - Shut down special devices. |
559 | * @state: PM transition of the system being carried out. | 604 | * @state: PM transition of the system being carried out. |
560 | * | 605 | * |
561 | * Power down devices that require interrupts to be disabled. | 606 | * Prevent device drivers from receiving interrupts and call the "late" |
562 | * Then power down system devices. | 607 | * suspend handlers. |
563 | * | 608 | * |
564 | * Must be called with interrupts disabled and only one CPU running. | 609 | * Must be called under dpm_list_mtx. |
565 | */ | 610 | */ |
566 | int device_power_down(pm_message_t state) | 611 | int device_power_down(pm_message_t state) |
567 | { | 612 | { |
568 | struct device *dev; | 613 | struct device *dev; |
569 | int error = 0; | 614 | int error = 0; |
570 | 615 | ||
616 | suspend_device_irqs(); | ||
571 | list_for_each_entry_reverse(dev, &dpm_list, power.entry) { | 617 | list_for_each_entry_reverse(dev, &dpm_list, power.entry) { |
572 | error = suspend_device_noirq(dev, state); | 618 | error = suspend_device_noirq(dev, state); |
573 | if (error) { | 619 | if (error) { |
@@ -577,7 +623,7 @@ int device_power_down(pm_message_t state) | |||
577 | dev->power.status = DPM_OFF_IRQ; | 623 | dev->power.status = DPM_OFF_IRQ; |
578 | } | 624 | } |
579 | if (error) | 625 | if (error) |
580 | dpm_power_up(resume_event(state)); | 626 | device_power_up(resume_event(state)); |
581 | return error; | 627 | return error; |
582 | } | 628 | } |
583 | EXPORT_SYMBOL_GPL(device_power_down); | 629 | EXPORT_SYMBOL_GPL(device_power_down); |
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..76ce75bad91e 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/pm.h> | 22 | #include <linux/pm.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/interrupt.h> | ||
25 | 26 | ||
26 | #include "base.h" | 27 | #include "base.h" |
27 | 28 | ||
@@ -30,10 +31,10 @@ | |||
30 | 31 | ||
31 | 32 | ||
32 | static ssize_t | 33 | static ssize_t |
33 | sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | 34 | sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer) |
34 | { | 35 | { |
35 | struct sys_device * sysdev = to_sysdev(kobj); | 36 | struct sys_device *sysdev = to_sysdev(kobj); |
36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 37 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); |
37 | 38 | ||
38 | if (sysdev_attr->show) | 39 | if (sysdev_attr->show) |
39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); | 40 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); |
@@ -42,11 +43,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | |||
42 | 43 | ||
43 | 44 | ||
44 | static ssize_t | 45 | static ssize_t |
45 | sysdev_store(struct kobject * kobj, struct attribute * attr, | 46 | sysdev_store(struct kobject *kobj, struct attribute *attr, |
46 | const char * buffer, size_t count) | 47 | const char *buffer, size_t count) |
47 | { | 48 | { |
48 | struct sys_device * sysdev = to_sysdev(kobj); | 49 | struct sys_device *sysdev = to_sysdev(kobj); |
49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 50 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); |
50 | 51 | ||
51 | if (sysdev_attr->store) | 52 | if (sysdev_attr->store) |
52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); | 53 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); |
@@ -63,13 +64,13 @@ static struct kobj_type ktype_sysdev = { | |||
63 | }; | 64 | }; |
64 | 65 | ||
65 | 66 | ||
66 | int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a) | 67 | int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a) |
67 | { | 68 | { |
68 | return sysfs_create_file(&s->kobj, &a->attr); | 69 | return sysfs_create_file(&s->kobj, &a->attr); |
69 | } | 70 | } |
70 | 71 | ||
71 | 72 | ||
72 | void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a) | 73 | void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a) |
73 | { | 74 | { |
74 | sysfs_remove_file(&s->kobj, &a->attr); | 75 | sysfs_remove_file(&s->kobj, &a->attr); |
75 | } | 76 | } |
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file); | |||
84 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | 85 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, |
85 | char *buffer) | 86 | char *buffer) |
86 | { | 87 | { |
87 | struct sysdev_class * class = to_sysdev_class(kobj); | 88 | struct sysdev_class *class = to_sysdev_class(kobj); |
88 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | 89 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
89 | 90 | ||
90 | if (class_attr->show) | 91 | if (class_attr->show) |
@@ -95,8 +96,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, | 96 | static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, |
96 | const char *buffer, size_t count) | 97 | const char *buffer, size_t count) |
97 | { | 98 | { |
98 | struct sysdev_class * class = to_sysdev_class(kobj); | 99 | struct sysdev_class *class = to_sysdev_class(kobj); |
99 | struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr); | 100 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
100 | 101 | ||
101 | if (class_attr->store) | 102 | if (class_attr->store) |
102 | return class_attr->store(class, buffer, count); | 103 | return class_attr->store(class, buffer, count); |
@@ -128,7 +129,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | |||
128 | 129 | ||
129 | static struct kset *system_kset; | 130 | static struct kset *system_kset; |
130 | 131 | ||
131 | int sysdev_class_register(struct sysdev_class * cls) | 132 | int sysdev_class_register(struct sysdev_class *cls) |
132 | { | 133 | { |
133 | pr_debug("Registering sysdev class '%s'\n", cls->name); | 134 | pr_debug("Registering sysdev class '%s'\n", cls->name); |
134 | 135 | ||
@@ -141,7 +142,7 @@ int sysdev_class_register(struct sysdev_class * cls) | |||
141 | return kset_register(&cls->kset); | 142 | return kset_register(&cls->kset); |
142 | } | 143 | } |
143 | 144 | ||
144 | void sysdev_class_unregister(struct sysdev_class * cls) | 145 | void sysdev_class_unregister(struct sysdev_class *cls) |
145 | { | 146 | { |
146 | pr_debug("Unregistering sysdev class '%s'\n", | 147 | pr_debug("Unregistering sysdev class '%s'\n", |
147 | kobject_name(&cls->kset.kobj)); | 148 | kobject_name(&cls->kset.kobj)); |
@@ -203,8 +204,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) | |||
203 | * @cls: Class driver belongs to. | 204 | * @cls: Class driver belongs to. |
204 | * @drv: Driver. | 205 | * @drv: Driver. |
205 | */ | 206 | */ |
206 | void sysdev_driver_unregister(struct sysdev_class * cls, | 207 | void sysdev_driver_unregister(struct sysdev_class *cls, |
207 | struct sysdev_driver * drv) | 208 | struct sysdev_driver *drv) |
208 | { | 209 | { |
209 | mutex_lock(&sysdev_drivers_lock); | 210 | mutex_lock(&sysdev_drivers_lock); |
210 | list_del_init(&drv->entry); | 211 | list_del_init(&drv->entry); |
@@ -229,10 +230,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister); | |||
229 | * @sysdev: device in question | 230 | * @sysdev: device in question |
230 | * | 231 | * |
231 | */ | 232 | */ |
232 | int sysdev_register(struct sys_device * sysdev) | 233 | int sysdev_register(struct sys_device *sysdev) |
233 | { | 234 | { |
234 | int error; | 235 | int error; |
235 | struct sysdev_class * cls = sysdev->cls; | 236 | struct sysdev_class *cls = sysdev->cls; |
236 | 237 | ||
237 | if (!cls) | 238 | if (!cls) |
238 | return -EINVAL; | 239 | return -EINVAL; |
@@ -252,7 +253,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
252 | sysdev->id); | 253 | sysdev->id); |
253 | 254 | ||
254 | if (!error) { | 255 | if (!error) { |
255 | struct sysdev_driver * drv; | 256 | struct sysdev_driver *drv; |
256 | 257 | ||
257 | pr_debug("Registering sys device '%s'\n", | 258 | pr_debug("Registering sys device '%s'\n", |
258 | kobject_name(&sysdev->kobj)); | 259 | kobject_name(&sysdev->kobj)); |
@@ -274,9 +275,9 @@ int sysdev_register(struct sys_device * sysdev) | |||
274 | return error; | 275 | return error; |
275 | } | 276 | } |
276 | 277 | ||
277 | void sysdev_unregister(struct sys_device * sysdev) | 278 | void sysdev_unregister(struct sys_device *sysdev) |
278 | { | 279 | { |
279 | struct sysdev_driver * drv; | 280 | struct sysdev_driver *drv; |
280 | 281 | ||
281 | mutex_lock(&sysdev_drivers_lock); | 282 | mutex_lock(&sysdev_drivers_lock); |
282 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { | 283 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { |
@@ -305,19 +306,19 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
305 | */ | 306 | */ |
306 | void sysdev_shutdown(void) | 307 | void sysdev_shutdown(void) |
307 | { | 308 | { |
308 | struct sysdev_class * cls; | 309 | struct sysdev_class *cls; |
309 | 310 | ||
310 | pr_debug("Shutting Down System Devices\n"); | 311 | pr_debug("Shutting Down System Devices\n"); |
311 | 312 | ||
312 | mutex_lock(&sysdev_drivers_lock); | 313 | mutex_lock(&sysdev_drivers_lock); |
313 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { | 314 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
314 | struct sys_device * sysdev; | 315 | struct sys_device *sysdev; |
315 | 316 | ||
316 | pr_debug("Shutting down type '%s':\n", | 317 | pr_debug("Shutting down type '%s':\n", |
317 | kobject_name(&cls->kset.kobj)); | 318 | kobject_name(&cls->kset.kobj)); |
318 | 319 | ||
319 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | 320 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { |
320 | struct sysdev_driver * drv; | 321 | struct sysdev_driver *drv; |
321 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 322 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
322 | 323 | ||
323 | /* Call auxillary drivers first */ | 324 | /* Call auxillary drivers first */ |
@@ -364,11 +365,18 @@ static void __sysdev_resume(struct sys_device *dev) | |||
364 | */ | 365 | */ |
365 | int sysdev_suspend(pm_message_t state) | 366 | int sysdev_suspend(pm_message_t state) |
366 | { | 367 | { |
367 | struct sysdev_class * cls; | 368 | struct sysdev_class *cls; |
368 | struct sys_device *sysdev, *err_dev; | 369 | struct sys_device *sysdev, *err_dev; |
369 | struct sysdev_driver *drv, *err_drv; | 370 | struct sysdev_driver *drv, *err_drv; |
370 | int ret; | 371 | int ret; |
371 | 372 | ||
373 | pr_debug("Checking wake-up interrupts\n"); | ||
374 | |||
375 | /* Return error code if there are any wake-up interrupts pending */ | ||
376 | ret = check_wakeup_irqs(); | ||
377 | if (ret) | ||
378 | return ret; | ||
379 | |||
372 | pr_debug("Suspending System Devices\n"); | 380 | pr_debug("Suspending System Devices\n"); |
373 | 381 | ||
374 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { | 382 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
@@ -442,12 +450,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend); | |||
442 | */ | 450 | */ |
443 | int sysdev_resume(void) | 451 | int sysdev_resume(void) |
444 | { | 452 | { |
445 | struct sysdev_class * cls; | 453 | struct sysdev_class *cls; |
446 | 454 | ||
447 | pr_debug("Resuming System Devices\n"); | 455 | pr_debug("Resuming System Devices\n"); |
448 | 456 | ||
449 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { | 457 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { |
450 | struct sys_device * sysdev; | 458 | struct sys_device *sysdev; |
451 | 459 | ||
452 | pr_debug("Resuming type '%s':\n", | 460 | pr_debug("Resuming type '%s':\n", |
453 | kobject_name(&cls->kset.kobj)); | 461 | kobject_name(&cls->kset.kobj)); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index a778fb52b11f..bf6b13206d00 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -31,7 +31,10 @@ | |||
31 | #include <linux/hardirq.h> | 31 | #include <linux/hardirq.h> |
32 | #include <linux/topology.h> | 32 | #include <linux/topology.h> |
33 | 33 | ||
34 | #define define_one_ro(_name) \ | 34 | #define define_one_ro_named(_name, _func) \ |
35 | static SYSDEV_ATTR(_name, 0444, _func, NULL) | ||
36 | |||
37 | #define define_one_ro(_name) \ | ||
35 | static SYSDEV_ATTR(_name, 0444, show_##_name, NULL) | 38 | static SYSDEV_ATTR(_name, 0444, show_##_name, NULL) |
36 | 39 | ||
37 | #define define_id_show_func(name) \ | 40 | #define define_id_show_func(name) \ |
@@ -42,8 +45,8 @@ static ssize_t show_##name(struct sys_device *dev, \ | |||
42 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | 45 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ |
43 | } | 46 | } |
44 | 47 | ||
45 | #if defined(topology_thread_siblings) || defined(topology_core_siblings) | 48 | #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) |
46 | static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf) | 49 | static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf) |
47 | { | 50 | { |
48 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; | 51 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; |
49 | int n = 0; | 52 | int n = 0; |
@@ -65,7 +68,7 @@ static ssize_t show_##name(struct sys_device *dev, \ | |||
65 | struct sysdev_attribute *attr, char *buf) \ | 68 | struct sysdev_attribute *attr, char *buf) \ |
66 | { \ | 69 | { \ |
67 | unsigned int cpu = dev->id; \ | 70 | unsigned int cpu = dev->id; \ |
68 | return show_cpumap(0, &(topology_##name(cpu)), buf); \ | 71 | return show_cpumap(0, topology_##name(cpu), buf); \ |
69 | } | 72 | } |
70 | 73 | ||
71 | #define define_siblings_show_list(name) \ | 74 | #define define_siblings_show_list(name) \ |
@@ -74,7 +77,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \ | |||
74 | char *buf) \ | 77 | char *buf) \ |
75 | { \ | 78 | { \ |
76 | unsigned int cpu = dev->id; \ | 79 | unsigned int cpu = dev->id; \ |
77 | return show_cpumap(1, &(topology_##name(cpu)), buf); \ | 80 | return show_cpumap(1, topology_##name(cpu), buf); \ |
78 | } | 81 | } |
79 | 82 | ||
80 | #else | 83 | #else |
@@ -82,9 +85,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \ | |||
82 | static ssize_t show_##name(struct sys_device *dev, \ | 85 | static ssize_t show_##name(struct sys_device *dev, \ |
83 | struct sysdev_attribute *attr, char *buf) \ | 86 | struct sysdev_attribute *attr, char *buf) \ |
84 | { \ | 87 | { \ |
85 | unsigned int cpu = dev->id; \ | 88 | return show_cpumap(0, topology_##name(dev->id), buf); \ |
86 | cpumask_t mask = topology_##name(cpu); \ | ||
87 | return show_cpumap(0, &mask, buf); \ | ||
88 | } | 89 | } |
89 | 90 | ||
90 | #define define_siblings_show_list(name) \ | 91 | #define define_siblings_show_list(name) \ |
@@ -92,9 +93,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \ | |||
92 | struct sysdev_attribute *attr, \ | 93 | struct sysdev_attribute *attr, \ |
93 | char *buf) \ | 94 | char *buf) \ |
94 | { \ | 95 | { \ |
95 | unsigned int cpu = dev->id; \ | 96 | return show_cpumap(1, topology_##name(dev->id), buf); \ |
96 | cpumask_t mask = topology_##name(cpu); \ | ||
97 | return show_cpumap(1, &mask, buf); \ | ||
98 | } | 97 | } |
99 | #endif | 98 | #endif |
100 | 99 | ||
@@ -107,13 +106,13 @@ define_one_ro(physical_package_id); | |||
107 | define_id_show_func(core_id); | 106 | define_id_show_func(core_id); |
108 | define_one_ro(core_id); | 107 | define_one_ro(core_id); |
109 | 108 | ||
110 | define_siblings_show_func(thread_siblings); | 109 | define_siblings_show_func(thread_cpumask); |
111 | define_one_ro(thread_siblings); | 110 | define_one_ro_named(thread_siblings, show_thread_cpumask); |
112 | define_one_ro(thread_siblings_list); | 111 | define_one_ro_named(thread_siblings_list, show_thread_cpumask_list); |
113 | 112 | ||
114 | define_siblings_show_func(core_siblings); | 113 | define_siblings_show_func(core_cpumask); |
115 | define_one_ro(core_siblings); | 114 | define_one_ro_named(core_siblings, show_core_cpumask); |
116 | define_one_ro(core_siblings_list); | 115 | define_one_ro_named(core_siblings_list, show_core_cpumask_list); |
117 | 116 | ||
118 | static struct attribute *default_attrs[] = { | 117 | static struct attribute *default_attrs[] = { |
119 | &attr_physical_package_id.attr, | 118 | &attr_physical_package_id.attr, |