diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Kconfig | 2 | ||||
-rw-r--r-- | drivers/base/base.h | 62 | ||||
-rw-r--r-- | drivers/base/bus.c | 15 | ||||
-rw-r--r-- | drivers/base/class.c | 42 | ||||
-rw-r--r-- | drivers/base/core.c | 65 | ||||
-rw-r--r-- | drivers/base/node.c | 21 | ||||
-rw-r--r-- | drivers/base/power/generic_ops.c | 6 | ||||
-rw-r--r-- | drivers/base/power/main.c | 176 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 47 | ||||
-rw-r--r-- | drivers/base/power/wakeup.c | 20 |
10 files changed, 238 insertions, 218 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index fd96345bc35c..d57e8d0fb823 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -70,7 +70,7 @@ config PREVENT_FIRMWARE_BUILD | |||
70 | If unsure say Y here. | 70 | If unsure say Y here. |
71 | 71 | ||
72 | config FW_LOADER | 72 | config FW_LOADER |
73 | tristate "Userspace firmware loading support" if EMBEDDED | 73 | tristate "Userspace firmware loading support" if EXPERT |
74 | default y | 74 | default y |
75 | ---help--- | 75 | ---help--- |
76 | This option is provided for the case where no in-kernel-tree modules | 76 | This option is provided for the case where no in-kernel-tree modules |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 2ca7f5b7b824..19f49e41ce5d 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -1,31 +1,46 @@ | |||
1 | 1 | ||
2 | /** | 2 | /** |
3 | * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. | 3 | * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure. |
4 | * | 4 | * |
5 | * @subsys - the struct kset that defines this bus. This is the main kobject | 5 | * @subsys - the struct kset that defines this subsystem |
6 | * @drivers_kset - the list of drivers associated with this bus | 6 | * @devices_kset - the list of devices associated |
7 | * @devices_kset - the list of devices associated with this bus | 7 | * |
8 | * @drivers_kset - the list of drivers associated | ||
8 | * @klist_devices - the klist to iterate over the @devices_kset | 9 | * @klist_devices - the klist to iterate over the @devices_kset |
9 | * @klist_drivers - the klist to iterate over the @drivers_kset | 10 | * @klist_drivers - the klist to iterate over the @drivers_kset |
10 | * @bus_notifier - the bus notifier list for anything that cares about things | 11 | * @bus_notifier - the bus notifier list for anything that cares about things |
11 | * on this bus. | 12 | * on this bus. |
12 | * @bus - pointer back to the struct bus_type that this structure is associated | 13 | * @bus - pointer back to the struct bus_type that this structure is associated |
13 | * with. | 14 | * with. |
15 | * | ||
16 | * @class_interfaces - list of class_interfaces associated | ||
17 | * @glue_dirs - "glue" directory to put in-between the parent device to | ||
18 | * avoid namespace conflicts | ||
19 | * @class_mutex - mutex to protect the children, devices, and interfaces lists. | ||
20 | * @class - pointer back to the struct class that this structure is associated | ||
21 | * with. | ||
14 | * | 22 | * |
15 | * This structure is the one that is the actual kobject allowing struct | 23 | * This structure is the one that is the actual kobject allowing struct |
16 | * bus_type to be statically allocated safely. Nothing outside of the driver | 24 | * bus_type/class to be statically allocated safely. Nothing outside of the |
17 | * core should ever touch these fields. | 25 | * driver core should ever touch these fields. |
18 | */ | 26 | */ |
19 | struct bus_type_private { | 27 | struct subsys_private { |
20 | struct kset subsys; | 28 | struct kset subsys; |
21 | struct kset *drivers_kset; | ||
22 | struct kset *devices_kset; | 29 | struct kset *devices_kset; |
30 | |||
31 | struct kset *drivers_kset; | ||
23 | struct klist klist_devices; | 32 | struct klist klist_devices; |
24 | struct klist klist_drivers; | 33 | struct klist klist_drivers; |
25 | struct blocking_notifier_head bus_notifier; | 34 | struct blocking_notifier_head bus_notifier; |
26 | unsigned int drivers_autoprobe:1; | 35 | unsigned int drivers_autoprobe:1; |
27 | struct bus_type *bus; | 36 | struct bus_type *bus; |
37 | |||
38 | struct list_head class_interfaces; | ||
39 | struct kset glue_dirs; | ||
40 | struct mutex class_mutex; | ||
41 | struct class *class; | ||
28 | }; | 42 | }; |
43 | #define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj) | ||
29 | 44 | ||
30 | struct driver_private { | 45 | struct driver_private { |
31 | struct kobject kobj; | 46 | struct kobject kobj; |
@@ -36,33 +51,6 @@ struct driver_private { | |||
36 | }; | 51 | }; |
37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) | 52 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) |
38 | 53 | ||
39 | |||
40 | /** | ||
41 | * struct class_private - structure to hold the private to the driver core portions of the class structure. | ||
42 | * | ||
43 | * @class_subsys - the struct kset that defines this class. This is the main kobject | ||
44 | * @class_devices - list of devices associated with this class | ||
45 | * @class_interfaces - list of class_interfaces associated with this class | ||
46 | * @class_dirs - "glue" directory for virtual devices associated with this class | ||
47 | * @class_mutex - mutex to protect the children, devices, and interfaces lists. | ||
48 | * @class - pointer back to the struct class that this structure is associated | ||
49 | * with. | ||
50 | * | ||
51 | * This structure is the one that is the actual kobject allowing struct | ||
52 | * class to be statically allocated safely. Nothing outside of the driver | ||
53 | * core should ever touch these fields. | ||
54 | */ | ||
55 | struct class_private { | ||
56 | struct kset class_subsys; | ||
57 | struct klist class_devices; | ||
58 | struct list_head class_interfaces; | ||
59 | struct kset class_dirs; | ||
60 | struct mutex class_mutex; | ||
61 | struct class *class; | ||
62 | }; | ||
63 | #define to_class(obj) \ | ||
64 | container_of(obj, struct class_private, class_subsys.kobj) | ||
65 | |||
66 | /** | 54 | /** |
67 | * struct device_private - structure to hold the private to the driver core portions of the device structure. | 55 | * struct device_private - structure to hold the private to the driver core portions of the device structure. |
68 | * | 56 | * |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 33c270a64db7..000e7b2006f8 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include "power/power.h" | 20 | #include "power/power.h" |
21 | 21 | ||
22 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 22 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
23 | #define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) | ||
24 | 23 | ||
25 | /* | 24 | /* |
26 | * sysfs bindings for drivers | 25 | * sysfs bindings for drivers |
@@ -96,11 +95,11 @@ static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, | |||
96 | char *buf) | 95 | char *buf) |
97 | { | 96 | { |
98 | struct bus_attribute *bus_attr = to_bus_attr(attr); | 97 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
99 | struct bus_type_private *bus_priv = to_bus(kobj); | 98 | struct subsys_private *subsys_priv = to_subsys_private(kobj); |
100 | ssize_t ret = 0; | 99 | ssize_t ret = 0; |
101 | 100 | ||
102 | if (bus_attr->show) | 101 | if (bus_attr->show) |
103 | ret = bus_attr->show(bus_priv->bus, buf); | 102 | ret = bus_attr->show(subsys_priv->bus, buf); |
104 | return ret; | 103 | return ret; |
105 | } | 104 | } |
106 | 105 | ||
@@ -108,11 +107,11 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, | |||
108 | const char *buf, size_t count) | 107 | const char *buf, size_t count) |
109 | { | 108 | { |
110 | struct bus_attribute *bus_attr = to_bus_attr(attr); | 109 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
111 | struct bus_type_private *bus_priv = to_bus(kobj); | 110 | struct subsys_private *subsys_priv = to_subsys_private(kobj); |
112 | ssize_t ret = 0; | 111 | ssize_t ret = 0; |
113 | 112 | ||
114 | if (bus_attr->store) | 113 | if (bus_attr->store) |
115 | ret = bus_attr->store(bus_priv->bus, buf, count); | 114 | ret = bus_attr->store(subsys_priv->bus, buf, count); |
116 | return ret; | 115 | return ret; |
117 | } | 116 | } |
118 | 117 | ||
@@ -858,9 +857,9 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | |||
858 | int bus_register(struct bus_type *bus) | 857 | int bus_register(struct bus_type *bus) |
859 | { | 858 | { |
860 | int retval; | 859 | int retval; |
861 | struct bus_type_private *priv; | 860 | struct subsys_private *priv; |
862 | 861 | ||
863 | priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); | 862 | priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); |
864 | if (!priv) | 863 | if (!priv) |
865 | return -ENOMEM; | 864 | return -ENOMEM; |
866 | 865 | ||
@@ -976,7 +975,7 @@ struct klist *bus_get_device_klist(struct bus_type *bus) | |||
976 | EXPORT_SYMBOL_GPL(bus_get_device_klist); | 975 | EXPORT_SYMBOL_GPL(bus_get_device_klist); |
977 | 976 | ||
978 | /* | 977 | /* |
979 | * Yes, this forcably breaks the klist abstraction temporarily. It | 978 | * Yes, this forcibly breaks the klist abstraction temporarily. It |
980 | * just wants to sort the klist, not change reference counts and | 979 | * just wants to sort the klist, not change reference counts and |
981 | * take/drop locks rapidly in the process. It does all this while | 980 | * take/drop locks rapidly in the process. It does all this while |
982 | * holding the lock for the list, so objects can't otherwise be | 981 | * holding the lock for the list, so objects can't otherwise be |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 9c63a5687d69..4f1df2e8fd74 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -27,7 +27,7 @@ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, | |||
27 | char *buf) | 27 | char *buf) |
28 | { | 28 | { |
29 | struct class_attribute *class_attr = to_class_attr(attr); | 29 | struct class_attribute *class_attr = to_class_attr(attr); |
30 | struct class_private *cp = to_class(kobj); | 30 | struct subsys_private *cp = to_subsys_private(kobj); |
31 | ssize_t ret = -EIO; | 31 | ssize_t ret = -EIO; |
32 | 32 | ||
33 | if (class_attr->show) | 33 | if (class_attr->show) |
@@ -39,7 +39,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, | |||
39 | const char *buf, size_t count) | 39 | const char *buf, size_t count) |
40 | { | 40 | { |
41 | struct class_attribute *class_attr = to_class_attr(attr); | 41 | struct class_attribute *class_attr = to_class_attr(attr); |
42 | struct class_private *cp = to_class(kobj); | 42 | struct subsys_private *cp = to_subsys_private(kobj); |
43 | ssize_t ret = -EIO; | 43 | ssize_t ret = -EIO; |
44 | 44 | ||
45 | if (class_attr->store) | 45 | if (class_attr->store) |
@@ -49,7 +49,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, | |||
49 | 49 | ||
50 | static void class_release(struct kobject *kobj) | 50 | static void class_release(struct kobject *kobj) |
51 | { | 51 | { |
52 | struct class_private *cp = to_class(kobj); | 52 | struct subsys_private *cp = to_subsys_private(kobj); |
53 | struct class *class = cp->class; | 53 | struct class *class = cp->class; |
54 | 54 | ||
55 | pr_debug("class '%s': release.\n", class->name); | 55 | pr_debug("class '%s': release.\n", class->name); |
@@ -65,7 +65,7 @@ static void class_release(struct kobject *kobj) | |||
65 | 65 | ||
66 | static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj) | 66 | static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj) |
67 | { | 67 | { |
68 | struct class_private *cp = to_class(kobj); | 68 | struct subsys_private *cp = to_subsys_private(kobj); |
69 | struct class *class = cp->class; | 69 | struct class *class = cp->class; |
70 | 70 | ||
71 | return class->ns_type; | 71 | return class->ns_type; |
@@ -82,7 +82,7 @@ static struct kobj_type class_ktype = { | |||
82 | .child_ns_type = class_child_ns_type, | 82 | .child_ns_type = class_child_ns_type, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | /* Hotplug events for classes go to the class class_subsys */ | 85 | /* Hotplug events for classes go to the class subsys */ |
86 | static struct kset *class_kset; | 86 | static struct kset *class_kset; |
87 | 87 | ||
88 | 88 | ||
@@ -90,7 +90,7 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) | |||
90 | { | 90 | { |
91 | int error; | 91 | int error; |
92 | if (cls) | 92 | if (cls) |
93 | error = sysfs_create_file(&cls->p->class_subsys.kobj, | 93 | error = sysfs_create_file(&cls->p->subsys.kobj, |
94 | &attr->attr); | 94 | &attr->attr); |
95 | else | 95 | else |
96 | error = -EINVAL; | 96 | error = -EINVAL; |
@@ -100,20 +100,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) | |||
100 | void class_remove_file(struct class *cls, const struct class_attribute *attr) | 100 | void class_remove_file(struct class *cls, const struct class_attribute *attr) |
101 | { | 101 | { |
102 | if (cls) | 102 | if (cls) |
103 | sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr); | 103 | sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr); |
104 | } | 104 | } |
105 | 105 | ||
106 | static struct class *class_get(struct class *cls) | 106 | static struct class *class_get(struct class *cls) |
107 | { | 107 | { |
108 | if (cls) | 108 | if (cls) |
109 | kset_get(&cls->p->class_subsys); | 109 | kset_get(&cls->p->subsys); |
110 | return cls; | 110 | return cls; |
111 | } | 111 | } |
112 | 112 | ||
113 | static void class_put(struct class *cls) | 113 | static void class_put(struct class *cls) |
114 | { | 114 | { |
115 | if (cls) | 115 | if (cls) |
116 | kset_put(&cls->p->class_subsys); | 116 | kset_put(&cls->p->subsys); |
117 | } | 117 | } |
118 | 118 | ||
119 | static int add_class_attrs(struct class *cls) | 119 | static int add_class_attrs(struct class *cls) |
@@ -162,7 +162,7 @@ static void klist_class_dev_put(struct klist_node *n) | |||
162 | 162 | ||
163 | int __class_register(struct class *cls, struct lock_class_key *key) | 163 | int __class_register(struct class *cls, struct lock_class_key *key) |
164 | { | 164 | { |
165 | struct class_private *cp; | 165 | struct subsys_private *cp; |
166 | int error; | 166 | int error; |
167 | 167 | ||
168 | pr_debug("device class '%s': registering\n", cls->name); | 168 | pr_debug("device class '%s': registering\n", cls->name); |
@@ -170,11 +170,11 @@ int __class_register(struct class *cls, struct lock_class_key *key) | |||
170 | cp = kzalloc(sizeof(*cp), GFP_KERNEL); | 170 | cp = kzalloc(sizeof(*cp), GFP_KERNEL); |
171 | if (!cp) | 171 | if (!cp) |
172 | return -ENOMEM; | 172 | return -ENOMEM; |
173 | klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put); | 173 | klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put); |
174 | INIT_LIST_HEAD(&cp->class_interfaces); | 174 | INIT_LIST_HEAD(&cp->class_interfaces); |
175 | kset_init(&cp->class_dirs); | 175 | kset_init(&cp->glue_dirs); |
176 | __mutex_init(&cp->class_mutex, "struct class mutex", key); | 176 | __mutex_init(&cp->class_mutex, "struct class mutex", key); |
177 | error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); | 177 | error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); |
178 | if (error) { | 178 | if (error) { |
179 | kfree(cp); | 179 | kfree(cp); |
180 | return error; | 180 | return error; |
@@ -187,15 +187,15 @@ int __class_register(struct class *cls, struct lock_class_key *key) | |||
187 | #if defined(CONFIG_BLOCK) | 187 | #if defined(CONFIG_BLOCK) |
188 | /* let the block class directory show up in the root of sysfs */ | 188 | /* let the block class directory show up in the root of sysfs */ |
189 | if (!sysfs_deprecated || cls != &block_class) | 189 | if (!sysfs_deprecated || cls != &block_class) |
190 | cp->class_subsys.kobj.kset = class_kset; | 190 | cp->subsys.kobj.kset = class_kset; |
191 | #else | 191 | #else |
192 | cp->class_subsys.kobj.kset = class_kset; | 192 | cp->subsys.kobj.kset = class_kset; |
193 | #endif | 193 | #endif |
194 | cp->class_subsys.kobj.ktype = &class_ktype; | 194 | cp->subsys.kobj.ktype = &class_ktype; |
195 | cp->class = cls; | 195 | cp->class = cls; |
196 | cls->p = cp; | 196 | cls->p = cp; |
197 | 197 | ||
198 | error = kset_register(&cp->class_subsys); | 198 | error = kset_register(&cp->subsys); |
199 | if (error) { | 199 | if (error) { |
200 | kfree(cp); | 200 | kfree(cp); |
201 | return error; | 201 | return error; |
@@ -210,7 +210,7 @@ void class_unregister(struct class *cls) | |||
210 | { | 210 | { |
211 | pr_debug("device class '%s': unregistering\n", cls->name); | 211 | pr_debug("device class '%s': unregistering\n", cls->name); |
212 | remove_class_attrs(cls); | 212 | remove_class_attrs(cls); |
213 | kset_unregister(&cls->p->class_subsys); | 213 | kset_unregister(&cls->p->subsys); |
214 | } | 214 | } |
215 | 215 | ||
216 | static void class_create_release(struct class *cls) | 216 | static void class_create_release(struct class *cls) |
@@ -295,7 +295,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, struct class *class, | |||
295 | 295 | ||
296 | if (start) | 296 | if (start) |
297 | start_knode = &start->knode_class; | 297 | start_knode = &start->knode_class; |
298 | klist_iter_init_node(&class->p->class_devices, &iter->ki, start_knode); | 298 | klist_iter_init_node(&class->p->klist_devices, &iter->ki, start_knode); |
299 | iter->type = type; | 299 | iter->type = type; |
300 | } | 300 | } |
301 | EXPORT_SYMBOL_GPL(class_dev_iter_init); | 301 | EXPORT_SYMBOL_GPL(class_dev_iter_init); |
@@ -482,8 +482,8 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
482 | class_put(parent); | 482 | class_put(parent); |
483 | } | 483 | } |
484 | 484 | ||
485 | ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, | 485 | ssize_t show_class_attr_string(struct class *class, |
486 | char *buf) | 486 | struct class_attribute *attr, char *buf) |
487 | { | 487 | { |
488 | struct class_attribute_string *cs; | 488 | struct class_attribute_string *cs; |
489 | cs = container_of(attr, struct class_attribute_string, attr); | 489 | cs = container_of(attr, struct class_attribute_string, attr); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 6ed645411c40..080e9ca11017 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -338,6 +338,35 @@ static void device_remove_attributes(struct device *dev, | |||
338 | device_remove_file(dev, &attrs[i]); | 338 | device_remove_file(dev, &attrs[i]); |
339 | } | 339 | } |
340 | 340 | ||
341 | static int device_add_bin_attributes(struct device *dev, | ||
342 | struct bin_attribute *attrs) | ||
343 | { | ||
344 | int error = 0; | ||
345 | int i; | ||
346 | |||
347 | if (attrs) { | ||
348 | for (i = 0; attr_name(attrs[i]); i++) { | ||
349 | error = device_create_bin_file(dev, &attrs[i]); | ||
350 | if (error) | ||
351 | break; | ||
352 | } | ||
353 | if (error) | ||
354 | while (--i >= 0) | ||
355 | device_remove_bin_file(dev, &attrs[i]); | ||
356 | } | ||
357 | return error; | ||
358 | } | ||
359 | |||
360 | static void device_remove_bin_attributes(struct device *dev, | ||
361 | struct bin_attribute *attrs) | ||
362 | { | ||
363 | int i; | ||
364 | |||
365 | if (attrs) | ||
366 | for (i = 0; attr_name(attrs[i]); i++) | ||
367 | device_remove_bin_file(dev, &attrs[i]); | ||
368 | } | ||
369 | |||
341 | static int device_add_groups(struct device *dev, | 370 | static int device_add_groups(struct device *dev, |
342 | const struct attribute_group **groups) | 371 | const struct attribute_group **groups) |
343 | { | 372 | { |
@@ -378,12 +407,15 @@ static int device_add_attrs(struct device *dev) | |||
378 | error = device_add_attributes(dev, class->dev_attrs); | 407 | error = device_add_attributes(dev, class->dev_attrs); |
379 | if (error) | 408 | if (error) |
380 | return error; | 409 | return error; |
410 | error = device_add_bin_attributes(dev, class->dev_bin_attrs); | ||
411 | if (error) | ||
412 | goto err_remove_class_attrs; | ||
381 | } | 413 | } |
382 | 414 | ||
383 | if (type) { | 415 | if (type) { |
384 | error = device_add_groups(dev, type->groups); | 416 | error = device_add_groups(dev, type->groups); |
385 | if (error) | 417 | if (error) |
386 | goto err_remove_class_attrs; | 418 | goto err_remove_class_bin_attrs; |
387 | } | 419 | } |
388 | 420 | ||
389 | error = device_add_groups(dev, dev->groups); | 421 | error = device_add_groups(dev, dev->groups); |
@@ -395,6 +427,9 @@ static int device_add_attrs(struct device *dev) | |||
395 | err_remove_type_groups: | 427 | err_remove_type_groups: |
396 | if (type) | 428 | if (type) |
397 | device_remove_groups(dev, type->groups); | 429 | device_remove_groups(dev, type->groups); |
430 | err_remove_class_bin_attrs: | ||
431 | if (class) | ||
432 | device_remove_bin_attributes(dev, class->dev_bin_attrs); | ||
398 | err_remove_class_attrs: | 433 | err_remove_class_attrs: |
399 | if (class) | 434 | if (class) |
400 | device_remove_attributes(dev, class->dev_attrs); | 435 | device_remove_attributes(dev, class->dev_attrs); |
@@ -412,8 +447,10 @@ static void device_remove_attrs(struct device *dev) | |||
412 | if (type) | 447 | if (type) |
413 | device_remove_groups(dev, type->groups); | 448 | device_remove_groups(dev, type->groups); |
414 | 449 | ||
415 | if (class) | 450 | if (class) { |
416 | device_remove_attributes(dev, class->dev_attrs); | 451 | device_remove_attributes(dev, class->dev_attrs); |
452 | device_remove_bin_attributes(dev, class->dev_bin_attrs); | ||
453 | } | ||
417 | } | 454 | } |
418 | 455 | ||
419 | 456 | ||
@@ -610,7 +647,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) | |||
610 | dir->class = class; | 647 | dir->class = class; |
611 | kobject_init(&dir->kobj, &class_dir_ktype); | 648 | kobject_init(&dir->kobj, &class_dir_ktype); |
612 | 649 | ||
613 | dir->kobj.kset = &class->p->class_dirs; | 650 | dir->kobj.kset = &class->p->glue_dirs; |
614 | 651 | ||
615 | retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); | 652 | retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); |
616 | if (retval < 0) { | 653 | if (retval < 0) { |
@@ -635,7 +672,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
635 | if (sysfs_deprecated && dev->class == &block_class) { | 672 | if (sysfs_deprecated && dev->class == &block_class) { |
636 | if (parent && parent->class == &block_class) | 673 | if (parent && parent->class == &block_class) |
637 | return &parent->kobj; | 674 | return &parent->kobj; |
638 | return &block_class.p->class_subsys.kobj; | 675 | return &block_class.p->subsys.kobj; |
639 | } | 676 | } |
640 | #endif | 677 | #endif |
641 | 678 | ||
@@ -654,13 +691,13 @@ static struct kobject *get_device_parent(struct device *dev, | |||
654 | mutex_lock(&gdp_mutex); | 691 | mutex_lock(&gdp_mutex); |
655 | 692 | ||
656 | /* find our class-directory at the parent and reference it */ | 693 | /* find our class-directory at the parent and reference it */ |
657 | spin_lock(&dev->class->p->class_dirs.list_lock); | 694 | spin_lock(&dev->class->p->glue_dirs.list_lock); |
658 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) | 695 | list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) |
659 | if (k->parent == parent_kobj) { | 696 | if (k->parent == parent_kobj) { |
660 | kobj = kobject_get(k); | 697 | kobj = kobject_get(k); |
661 | break; | 698 | break; |
662 | } | 699 | } |
663 | spin_unlock(&dev->class->p->class_dirs.list_lock); | 700 | spin_unlock(&dev->class->p->glue_dirs.list_lock); |
664 | if (kobj) { | 701 | if (kobj) { |
665 | mutex_unlock(&gdp_mutex); | 702 | mutex_unlock(&gdp_mutex); |
666 | return kobj; | 703 | return kobj; |
@@ -682,7 +719,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) | |||
682 | { | 719 | { |
683 | /* see if we live in a "glue" directory */ | 720 | /* see if we live in a "glue" directory */ |
684 | if (!glue_dir || !dev->class || | 721 | if (!glue_dir || !dev->class || |
685 | glue_dir->kset != &dev->class->p->class_dirs) | 722 | glue_dir->kset != &dev->class->p->glue_dirs) |
686 | return; | 723 | return; |
687 | 724 | ||
688 | kobject_put(glue_dir); | 725 | kobject_put(glue_dir); |
@@ -709,7 +746,7 @@ static int device_add_class_symlinks(struct device *dev) | |||
709 | return 0; | 746 | return 0; |
710 | 747 | ||
711 | error = sysfs_create_link(&dev->kobj, | 748 | error = sysfs_create_link(&dev->kobj, |
712 | &dev->class->p->class_subsys.kobj, | 749 | &dev->class->p->subsys.kobj, |
713 | "subsystem"); | 750 | "subsystem"); |
714 | if (error) | 751 | if (error) |
715 | goto out; | 752 | goto out; |
@@ -728,7 +765,7 @@ static int device_add_class_symlinks(struct device *dev) | |||
728 | #endif | 765 | #endif |
729 | 766 | ||
730 | /* link in the class directory pointing to the device */ | 767 | /* link in the class directory pointing to the device */ |
731 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | 768 | error = sysfs_create_link(&dev->class->p->subsys.kobj, |
732 | &dev->kobj, dev_name(dev)); | 769 | &dev->kobj, dev_name(dev)); |
733 | if (error) | 770 | if (error) |
734 | goto out_device; | 771 | goto out_device; |
@@ -756,7 +793,7 @@ static void device_remove_class_symlinks(struct device *dev) | |||
756 | if (sysfs_deprecated && dev->class == &block_class) | 793 | if (sysfs_deprecated && dev->class == &block_class) |
757 | return; | 794 | return; |
758 | #endif | 795 | #endif |
759 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | 796 | sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); |
760 | } | 797 | } |
761 | 798 | ||
762 | /** | 799 | /** |
@@ -947,7 +984,7 @@ int device_add(struct device *dev) | |||
947 | mutex_lock(&dev->class->p->class_mutex); | 984 | mutex_lock(&dev->class->p->class_mutex); |
948 | /* tie the class to the device */ | 985 | /* tie the class to the device */ |
949 | klist_add_tail(&dev->knode_class, | 986 | klist_add_tail(&dev->knode_class, |
950 | &dev->class->p->class_devices); | 987 | &dev->class->p->klist_devices); |
951 | 988 | ||
952 | /* notify any interfaces that the device is here */ | 989 | /* notify any interfaces that the device is here */ |
953 | list_for_each_entry(class_intf, | 990 | list_for_each_entry(class_intf, |
@@ -1513,6 +1550,8 @@ EXPORT_SYMBOL_GPL(device_destroy); | |||
1513 | * exclusion between two different calls of device_rename | 1550 | * exclusion between two different calls of device_rename |
1514 | * on the same device to ensure that new_name is valid and | 1551 | * on the same device to ensure that new_name is valid and |
1515 | * won't conflict with other devices. | 1552 | * won't conflict with other devices. |
1553 | * | ||
1554 | * "Never use this function, bad things will happen" - gregkh | ||
1516 | */ | 1555 | */ |
1517 | int device_rename(struct device *dev, const char *new_name) | 1556 | int device_rename(struct device *dev, const char *new_name) |
1518 | { | 1557 | { |
@@ -1535,7 +1574,7 @@ int device_rename(struct device *dev, const char *new_name) | |||
1535 | } | 1574 | } |
1536 | 1575 | ||
1537 | if (dev->class) { | 1576 | if (dev->class) { |
1538 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, | 1577 | error = sysfs_rename_link(&dev->class->p->subsys.kobj, |
1539 | &dev->kobj, old_device_name, new_name); | 1578 | &dev->kobj, old_device_name, new_name); |
1540 | if (error) | 1579 | if (error) |
1541 | goto out; | 1580 | goto out; |
diff --git a/drivers/base/node.c b/drivers/base/node.c index ce012a9c6201..36b43052001d 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -117,12 +117,21 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
117 | "Node %d WritebackTmp: %8lu kB\n" | 117 | "Node %d WritebackTmp: %8lu kB\n" |
118 | "Node %d Slab: %8lu kB\n" | 118 | "Node %d Slab: %8lu kB\n" |
119 | "Node %d SReclaimable: %8lu kB\n" | 119 | "Node %d SReclaimable: %8lu kB\n" |
120 | "Node %d SUnreclaim: %8lu kB\n", | 120 | "Node %d SUnreclaim: %8lu kB\n" |
121 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
122 | "Node %d AnonHugePages: %8lu kB\n" | ||
123 | #endif | ||
124 | , | ||
121 | nid, K(node_page_state(nid, NR_FILE_DIRTY)), | 125 | nid, K(node_page_state(nid, NR_FILE_DIRTY)), |
122 | nid, K(node_page_state(nid, NR_WRITEBACK)), | 126 | nid, K(node_page_state(nid, NR_WRITEBACK)), |
123 | nid, K(node_page_state(nid, NR_FILE_PAGES)), | 127 | nid, K(node_page_state(nid, NR_FILE_PAGES)), |
124 | nid, K(node_page_state(nid, NR_FILE_MAPPED)), | 128 | nid, K(node_page_state(nid, NR_FILE_MAPPED)), |
125 | nid, K(node_page_state(nid, NR_ANON_PAGES)), | 129 | nid, K(node_page_state(nid, NR_ANON_PAGES) |
130 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
131 | + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * | ||
132 | HPAGE_PMD_NR | ||
133 | #endif | ||
134 | ), | ||
126 | nid, K(node_page_state(nid, NR_SHMEM)), | 135 | nid, K(node_page_state(nid, NR_SHMEM)), |
127 | nid, node_page_state(nid, NR_KERNEL_STACK) * | 136 | nid, node_page_state(nid, NR_KERNEL_STACK) * |
128 | THREAD_SIZE / 1024, | 137 | THREAD_SIZE / 1024, |
@@ -133,7 +142,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
133 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + | 142 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + |
134 | node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), | 143 | node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), |
135 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), | 144 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), |
136 | nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); | 145 | nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)) |
146 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
147 | , nid, | ||
148 | K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * | ||
149 | HPAGE_PMD_NR) | ||
150 | #endif | ||
151 | ); | ||
137 | n += hugetlb_report_node_meminfo(nid, buf + n); | 152 | n += hugetlb_report_node_meminfo(nid, buf + n); |
138 | return n; | 153 | return n; |
139 | } | 154 | } |
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 81f2c84697f4..42f97f925629 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c | |||
@@ -39,7 +39,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); | |||
39 | * | 39 | * |
40 | * If PM operations are defined for the @dev's driver and they include | 40 | * If PM operations are defined for the @dev's driver and they include |
41 | * ->runtime_suspend(), execute it and return its error code. Otherwise, | 41 | * ->runtime_suspend(), execute it and return its error code. Otherwise, |
42 | * return -EINVAL. | 42 | * return 0. |
43 | */ | 43 | */ |
44 | int pm_generic_runtime_suspend(struct device *dev) | 44 | int pm_generic_runtime_suspend(struct device *dev) |
45 | { | 45 | { |
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); | |||
58 | * | 58 | * |
59 | * If PM operations are defined for the @dev's driver and they include | 59 | * If PM operations are defined for the @dev's driver and they include |
60 | * ->runtime_resume(), execute it and return its error code. Otherwise, | 60 | * ->runtime_resume(), execute it and return its error code. Otherwise, |
61 | * return -EINVAL. | 61 | * return 0. |
62 | */ | 62 | */ |
63 | int pm_generic_runtime_resume(struct device *dev) | 63 | int pm_generic_runtime_resume(struct device *dev) |
64 | { | 64 | { |
@@ -185,7 +185,7 @@ static int __pm_generic_resume(struct device *dev, int event) | |||
185 | return 0; | 185 | return 0; |
186 | 186 | ||
187 | ret = callback(dev); | 187 | ret = callback(dev); |
188 | if (!ret) { | 188 | if (!ret && pm_runtime_enabled(dev)) { |
189 | pm_runtime_disable(dev); | 189 | pm_runtime_disable(dev); |
190 | pm_runtime_set_active(dev); | 190 | pm_runtime_set_active(dev); |
191 | pm_runtime_enable(dev); | 191 | pm_runtime_enable(dev); |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index ead3e79d6fcf..83404973f97a 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * | 9 | * |
10 | * The driver model core calls device_pm_add() when a device is registered. | 10 | * The driver model core calls device_pm_add() when a device is registered. |
11 | * This will intialize the embedded device_pm_info object in the device | 11 | * This will initialize the embedded device_pm_info object in the device |
12 | * and add it to the list of power-controlled devices. sysfs entries for | 12 | * and add it to the list of power-controlled devices. sysfs entries for |
13 | * controlling device power management will also be added. | 13 | * controlling device power management will also be added. |
14 | * | 14 | * |
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/async.h> | 28 | #include <linux/async.h> |
29 | #include <linux/suspend.h> | ||
29 | 30 | ||
30 | #include "../base.h" | 31 | #include "../base.h" |
31 | #include "power.h" | 32 | #include "power.h" |
@@ -41,16 +42,13 @@ | |||
41 | */ | 42 | */ |
42 | 43 | ||
43 | LIST_HEAD(dpm_list); | 44 | LIST_HEAD(dpm_list); |
45 | LIST_HEAD(dpm_prepared_list); | ||
46 | LIST_HEAD(dpm_suspended_list); | ||
47 | LIST_HEAD(dpm_noirq_list); | ||
44 | 48 | ||
45 | static DEFINE_MUTEX(dpm_list_mtx); | 49 | static DEFINE_MUTEX(dpm_list_mtx); |
46 | static pm_message_t pm_transition; | 50 | static pm_message_t pm_transition; |
47 | 51 | ||
48 | /* | ||
49 | * Set once the preparation of devices for a PM transition has started, reset | ||
50 | * before starting to resume devices. Protected by dpm_list_mtx. | ||
51 | */ | ||
52 | static bool transition_started; | ||
53 | |||
54 | static int async_error; | 52 | static int async_error; |
55 | 53 | ||
56 | /** | 54 | /** |
@@ -59,7 +57,7 @@ static int async_error; | |||
59 | */ | 57 | */ |
60 | void device_pm_init(struct device *dev) | 58 | void device_pm_init(struct device *dev) |
61 | { | 59 | { |
62 | dev->power.status = DPM_ON; | 60 | dev->power.in_suspend = false; |
63 | init_completion(&dev->power.completion); | 61 | init_completion(&dev->power.completion); |
64 | complete_all(&dev->power.completion); | 62 | complete_all(&dev->power.completion); |
65 | dev->power.wakeup = NULL; | 63 | dev->power.wakeup = NULL; |
@@ -90,22 +88,11 @@ void device_pm_unlock(void) | |||
90 | void device_pm_add(struct device *dev) | 88 | void device_pm_add(struct device *dev) |
91 | { | 89 | { |
92 | pr_debug("PM: Adding info for %s:%s\n", | 90 | pr_debug("PM: Adding info for %s:%s\n", |
93 | dev->bus ? dev->bus->name : "No Bus", | 91 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
94 | kobject_name(&dev->kobj)); | ||
95 | mutex_lock(&dpm_list_mtx); | 92 | mutex_lock(&dpm_list_mtx); |
96 | if (dev->parent) { | 93 | if (dev->parent && dev->parent->power.in_suspend) |
97 | if (dev->parent->power.status >= DPM_SUSPENDING) | 94 | dev_warn(dev, "parent %s should not be sleeping\n", |
98 | dev_warn(dev, "parent %s should not be sleeping\n", | 95 | dev_name(dev->parent)); |
99 | dev_name(dev->parent)); | ||
100 | } else if (transition_started) { | ||
101 | /* | ||
102 | * We refuse to register parentless devices while a PM | ||
103 | * transition is in progress in order to avoid leaving them | ||
104 | * unhandled down the road | ||
105 | */ | ||
106 | dev_WARN(dev, "Parentless device registered during a PM transaction\n"); | ||
107 | } | ||
108 | |||
109 | list_add_tail(&dev->power.entry, &dpm_list); | 96 | list_add_tail(&dev->power.entry, &dpm_list); |
110 | mutex_unlock(&dpm_list_mtx); | 97 | mutex_unlock(&dpm_list_mtx); |
111 | } | 98 | } |
@@ -117,8 +104,7 @@ void device_pm_add(struct device *dev) | |||
117 | void device_pm_remove(struct device *dev) | 104 | void device_pm_remove(struct device *dev) |
118 | { | 105 | { |
119 | pr_debug("PM: Removing info for %s:%s\n", | 106 | pr_debug("PM: Removing info for %s:%s\n", |
120 | dev->bus ? dev->bus->name : "No Bus", | 107 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
121 | kobject_name(&dev->kobj)); | ||
122 | complete_all(&dev->power.completion); | 108 | complete_all(&dev->power.completion); |
123 | mutex_lock(&dpm_list_mtx); | 109 | mutex_lock(&dpm_list_mtx); |
124 | list_del_init(&dev->power.entry); | 110 | list_del_init(&dev->power.entry); |
@@ -135,10 +121,8 @@ void device_pm_remove(struct device *dev) | |||
135 | void device_pm_move_before(struct device *deva, struct device *devb) | 121 | void device_pm_move_before(struct device *deva, struct device *devb) |
136 | { | 122 | { |
137 | pr_debug("PM: Moving %s:%s before %s:%s\n", | 123 | pr_debug("PM: Moving %s:%s before %s:%s\n", |
138 | deva->bus ? deva->bus->name : "No Bus", | 124 | deva->bus ? deva->bus->name : "No Bus", dev_name(deva), |
139 | kobject_name(&deva->kobj), | 125 | devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); |
140 | devb->bus ? devb->bus->name : "No Bus", | ||
141 | kobject_name(&devb->kobj)); | ||
142 | /* Delete deva from dpm_list and reinsert before devb. */ | 126 | /* Delete deva from dpm_list and reinsert before devb. */ |
143 | list_move_tail(&deva->power.entry, &devb->power.entry); | 127 | list_move_tail(&deva->power.entry, &devb->power.entry); |
144 | } | 128 | } |
@@ -151,10 +135,8 @@ void device_pm_move_before(struct device *deva, struct device *devb) | |||
151 | void device_pm_move_after(struct device *deva, struct device *devb) | 135 | void device_pm_move_after(struct device *deva, struct device *devb) |
152 | { | 136 | { |
153 | pr_debug("PM: Moving %s:%s after %s:%s\n", | 137 | pr_debug("PM: Moving %s:%s after %s:%s\n", |
154 | deva->bus ? deva->bus->name : "No Bus", | 138 | deva->bus ? deva->bus->name : "No Bus", dev_name(deva), |
155 | kobject_name(&deva->kobj), | 139 | devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); |
156 | devb->bus ? devb->bus->name : "No Bus", | ||
157 | kobject_name(&devb->kobj)); | ||
158 | /* Delete deva from dpm_list and reinsert after devb. */ | 140 | /* Delete deva from dpm_list and reinsert after devb. */ |
159 | list_move(&deva->power.entry, &devb->power.entry); | 141 | list_move(&deva->power.entry, &devb->power.entry); |
160 | } | 142 | } |
@@ -166,8 +148,7 @@ void device_pm_move_after(struct device *deva, struct device *devb) | |||
166 | void device_pm_move_last(struct device *dev) | 148 | void device_pm_move_last(struct device *dev) |
167 | { | 149 | { |
168 | pr_debug("PM: Moving %s:%s to end of list\n", | 150 | pr_debug("PM: Moving %s:%s to end of list\n", |
169 | dev->bus ? dev->bus->name : "No Bus", | 151 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
170 | kobject_name(&dev->kobj)); | ||
171 | list_move_tail(&dev->power.entry, &dpm_list); | 152 | list_move_tail(&dev->power.entry, &dpm_list); |
172 | } | 153 | } |
173 | 154 | ||
@@ -303,7 +284,7 @@ static int pm_noirq_op(struct device *dev, | |||
303 | pm_message_t state) | 284 | pm_message_t state) |
304 | { | 285 | { |
305 | int error = 0; | 286 | int error = 0; |
306 | ktime_t calltime, delta, rettime; | 287 | ktime_t calltime = ktime_set(0, 0), delta, rettime; |
307 | 288 | ||
308 | if (initcall_debug) { | 289 | if (initcall_debug) { |
309 | pr_info("calling %s+ @ %i, parent: %s\n", | 290 | pr_info("calling %s+ @ %i, parent: %s\n", |
@@ -405,7 +386,7 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info, | |||
405 | int error) | 386 | int error) |
406 | { | 387 | { |
407 | printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", | 388 | printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", |
408 | kobject_name(&dev->kobj), pm_verb(state.event), info, error); | 389 | dev_name(dev), pm_verb(state.event), info, error); |
409 | } | 390 | } |
410 | 391 | ||
411 | static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) | 392 | static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) |
@@ -475,33 +456,24 @@ End: | |||
475 | */ | 456 | */ |
476 | void dpm_resume_noirq(pm_message_t state) | 457 | void dpm_resume_noirq(pm_message_t state) |
477 | { | 458 | { |
478 | struct list_head list; | ||
479 | ktime_t starttime = ktime_get(); | 459 | ktime_t starttime = ktime_get(); |
480 | 460 | ||
481 | INIT_LIST_HEAD(&list); | ||
482 | mutex_lock(&dpm_list_mtx); | 461 | mutex_lock(&dpm_list_mtx); |
483 | transition_started = false; | 462 | while (!list_empty(&dpm_noirq_list)) { |
484 | while (!list_empty(&dpm_list)) { | 463 | struct device *dev = to_device(dpm_noirq_list.next); |
485 | struct device *dev = to_device(dpm_list.next); | 464 | int error; |
486 | 465 | ||
487 | get_device(dev); | 466 | get_device(dev); |
488 | if (dev->power.status > DPM_OFF) { | 467 | list_move_tail(&dev->power.entry, &dpm_suspended_list); |
489 | int error; | 468 | mutex_unlock(&dpm_list_mtx); |
490 | |||
491 | dev->power.status = DPM_OFF; | ||
492 | mutex_unlock(&dpm_list_mtx); | ||
493 | 469 | ||
494 | error = device_resume_noirq(dev, state); | 470 | error = device_resume_noirq(dev, state); |
471 | if (error) | ||
472 | pm_dev_err(dev, state, " early", error); | ||
495 | 473 | ||
496 | mutex_lock(&dpm_list_mtx); | 474 | mutex_lock(&dpm_list_mtx); |
497 | if (error) | ||
498 | pm_dev_err(dev, state, " early", error); | ||
499 | } | ||
500 | if (!list_empty(&dev->power.entry)) | ||
501 | list_move_tail(&dev->power.entry, &list); | ||
502 | put_device(dev); | 475 | put_device(dev); |
503 | } | 476 | } |
504 | list_splice(&list, &dpm_list); | ||
505 | mutex_unlock(&dpm_list_mtx); | 477 | mutex_unlock(&dpm_list_mtx); |
506 | dpm_show_time(starttime, state, "early"); | 478 | dpm_show_time(starttime, state, "early"); |
507 | resume_device_irqs(); | 479 | resume_device_irqs(); |
@@ -544,7 +516,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
544 | dpm_wait(dev->parent, async); | 516 | dpm_wait(dev->parent, async); |
545 | device_lock(dev); | 517 | device_lock(dev); |
546 | 518 | ||
547 | dev->power.status = DPM_RESUMING; | 519 | dev->power.in_suspend = false; |
548 | 520 | ||
549 | if (dev->bus) { | 521 | if (dev->bus) { |
550 | if (dev->bus->pm) { | 522 | if (dev->bus->pm) { |
@@ -610,19 +582,14 @@ static bool is_async(struct device *dev) | |||
610 | */ | 582 | */ |
611 | static void dpm_resume(pm_message_t state) | 583 | static void dpm_resume(pm_message_t state) |
612 | { | 584 | { |
613 | struct list_head list; | ||
614 | struct device *dev; | 585 | struct device *dev; |
615 | ktime_t starttime = ktime_get(); | 586 | ktime_t starttime = ktime_get(); |
616 | 587 | ||
617 | INIT_LIST_HEAD(&list); | ||
618 | mutex_lock(&dpm_list_mtx); | 588 | mutex_lock(&dpm_list_mtx); |
619 | pm_transition = state; | 589 | pm_transition = state; |
620 | async_error = 0; | 590 | async_error = 0; |
621 | 591 | ||
622 | list_for_each_entry(dev, &dpm_list, power.entry) { | 592 | list_for_each_entry(dev, &dpm_suspended_list, power.entry) { |
623 | if (dev->power.status < DPM_OFF) | ||
624 | continue; | ||
625 | |||
626 | INIT_COMPLETION(dev->power.completion); | 593 | INIT_COMPLETION(dev->power.completion); |
627 | if (is_async(dev)) { | 594 | if (is_async(dev)) { |
628 | get_device(dev); | 595 | get_device(dev); |
@@ -630,28 +597,24 @@ static void dpm_resume(pm_message_t state) | |||
630 | } | 597 | } |
631 | } | 598 | } |
632 | 599 | ||
633 | while (!list_empty(&dpm_list)) { | 600 | while (!list_empty(&dpm_suspended_list)) { |
634 | dev = to_device(dpm_list.next); | 601 | dev = to_device(dpm_suspended_list.next); |
635 | get_device(dev); | 602 | get_device(dev); |
636 | if (dev->power.status >= DPM_OFF && !is_async(dev)) { | 603 | if (!is_async(dev)) { |
637 | int error; | 604 | int error; |
638 | 605 | ||
639 | mutex_unlock(&dpm_list_mtx); | 606 | mutex_unlock(&dpm_list_mtx); |
640 | 607 | ||
641 | error = device_resume(dev, state, false); | 608 | error = device_resume(dev, state, false); |
642 | |||
643 | mutex_lock(&dpm_list_mtx); | ||
644 | if (error) | 609 | if (error) |
645 | pm_dev_err(dev, state, "", error); | 610 | pm_dev_err(dev, state, "", error); |
646 | } else if (dev->power.status == DPM_SUSPENDING) { | 611 | |
647 | /* Allow new children of the device to be registered */ | 612 | mutex_lock(&dpm_list_mtx); |
648 | dev->power.status = DPM_RESUMING; | ||
649 | } | 613 | } |
650 | if (!list_empty(&dev->power.entry)) | 614 | if (!list_empty(&dev->power.entry)) |
651 | list_move_tail(&dev->power.entry, &list); | 615 | list_move_tail(&dev->power.entry, &dpm_prepared_list); |
652 | put_device(dev); | 616 | put_device(dev); |
653 | } | 617 | } |
654 | list_splice(&list, &dpm_list); | ||
655 | mutex_unlock(&dpm_list_mtx); | 618 | mutex_unlock(&dpm_list_mtx); |
656 | async_synchronize_full(); | 619 | async_synchronize_full(); |
657 | dpm_show_time(starttime, state, NULL); | 620 | dpm_show_time(starttime, state, NULL); |
@@ -697,22 +660,18 @@ static void dpm_complete(pm_message_t state) | |||
697 | 660 | ||
698 | INIT_LIST_HEAD(&list); | 661 | INIT_LIST_HEAD(&list); |
699 | mutex_lock(&dpm_list_mtx); | 662 | mutex_lock(&dpm_list_mtx); |
700 | transition_started = false; | 663 | while (!list_empty(&dpm_prepared_list)) { |
701 | while (!list_empty(&dpm_list)) { | 664 | struct device *dev = to_device(dpm_prepared_list.prev); |
702 | struct device *dev = to_device(dpm_list.prev); | ||
703 | 665 | ||
704 | get_device(dev); | 666 | get_device(dev); |
705 | if (dev->power.status > DPM_ON) { | 667 | dev->power.in_suspend = false; |
706 | dev->power.status = DPM_ON; | 668 | list_move(&dev->power.entry, &list); |
707 | mutex_unlock(&dpm_list_mtx); | 669 | mutex_unlock(&dpm_list_mtx); |
708 | 670 | ||
709 | device_complete(dev, state); | 671 | device_complete(dev, state); |
710 | pm_runtime_put_sync(dev); | 672 | pm_runtime_put_sync(dev); |
711 | 673 | ||
712 | mutex_lock(&dpm_list_mtx); | 674 | mutex_lock(&dpm_list_mtx); |
713 | } | ||
714 | if (!list_empty(&dev->power.entry)) | ||
715 | list_move(&dev->power.entry, &list); | ||
716 | put_device(dev); | 675 | put_device(dev); |
717 | } | 676 | } |
718 | list_splice(&list, &dpm_list); | 677 | list_splice(&list, &dpm_list); |
@@ -802,15 +761,13 @@ End: | |||
802 | */ | 761 | */ |
803 | int dpm_suspend_noirq(pm_message_t state) | 762 | int dpm_suspend_noirq(pm_message_t state) |
804 | { | 763 | { |
805 | struct list_head list; | ||
806 | ktime_t starttime = ktime_get(); | 764 | ktime_t starttime = ktime_get(); |
807 | int error = 0; | 765 | int error = 0; |
808 | 766 | ||
809 | INIT_LIST_HEAD(&list); | ||
810 | suspend_device_irqs(); | 767 | suspend_device_irqs(); |
811 | mutex_lock(&dpm_list_mtx); | 768 | mutex_lock(&dpm_list_mtx); |
812 | while (!list_empty(&dpm_list)) { | 769 | while (!list_empty(&dpm_suspended_list)) { |
813 | struct device *dev = to_device(dpm_list.prev); | 770 | struct device *dev = to_device(dpm_suspended_list.prev); |
814 | 771 | ||
815 | get_device(dev); | 772 | get_device(dev); |
816 | mutex_unlock(&dpm_list_mtx); | 773 | mutex_unlock(&dpm_list_mtx); |
@@ -823,12 +780,10 @@ int dpm_suspend_noirq(pm_message_t state) | |||
823 | put_device(dev); | 780 | put_device(dev); |
824 | break; | 781 | break; |
825 | } | 782 | } |
826 | dev->power.status = DPM_OFF_IRQ; | ||
827 | if (!list_empty(&dev->power.entry)) | 783 | if (!list_empty(&dev->power.entry)) |
828 | list_move(&dev->power.entry, &list); | 784 | list_move(&dev->power.entry, &dpm_noirq_list); |
829 | put_device(dev); | 785 | put_device(dev); |
830 | } | 786 | } |
831 | list_splice_tail(&list, &dpm_list); | ||
832 | mutex_unlock(&dpm_list_mtx); | 787 | mutex_unlock(&dpm_list_mtx); |
833 | if (error) | 788 | if (error) |
834 | dpm_resume_noirq(resume_event(state)); | 789 | dpm_resume_noirq(resume_event(state)); |
@@ -876,6 +831,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
876 | if (async_error) | 831 | if (async_error) |
877 | goto End; | 832 | goto End; |
878 | 833 | ||
834 | if (pm_wakeup_pending()) { | ||
835 | async_error = -EBUSY; | ||
836 | goto End; | ||
837 | } | ||
838 | |||
879 | if (dev->class) { | 839 | if (dev->class) { |
880 | if (dev->class->pm) { | 840 | if (dev->class->pm) { |
881 | pm_dev_dbg(dev, state, "class "); | 841 | pm_dev_dbg(dev, state, "class "); |
@@ -907,9 +867,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
907 | } | 867 | } |
908 | } | 868 | } |
909 | 869 | ||
910 | if (!error) | ||
911 | dev->power.status = DPM_OFF; | ||
912 | |||
913 | End: | 870 | End: |
914 | device_unlock(dev); | 871 | device_unlock(dev); |
915 | complete_all(&dev->power.completion); | 872 | complete_all(&dev->power.completion); |
@@ -951,16 +908,14 @@ static int device_suspend(struct device *dev) | |||
951 | */ | 908 | */ |
952 | static int dpm_suspend(pm_message_t state) | 909 | static int dpm_suspend(pm_message_t state) |
953 | { | 910 | { |
954 | struct list_head list; | ||
955 | ktime_t starttime = ktime_get(); | 911 | ktime_t starttime = ktime_get(); |
956 | int error = 0; | 912 | int error = 0; |
957 | 913 | ||
958 | INIT_LIST_HEAD(&list); | ||
959 | mutex_lock(&dpm_list_mtx); | 914 | mutex_lock(&dpm_list_mtx); |
960 | pm_transition = state; | 915 | pm_transition = state; |
961 | async_error = 0; | 916 | async_error = 0; |
962 | while (!list_empty(&dpm_list)) { | 917 | while (!list_empty(&dpm_prepared_list)) { |
963 | struct device *dev = to_device(dpm_list.prev); | 918 | struct device *dev = to_device(dpm_prepared_list.prev); |
964 | 919 | ||
965 | get_device(dev); | 920 | get_device(dev); |
966 | mutex_unlock(&dpm_list_mtx); | 921 | mutex_unlock(&dpm_list_mtx); |
@@ -974,12 +929,11 @@ static int dpm_suspend(pm_message_t state) | |||
974 | break; | 929 | break; |
975 | } | 930 | } |
976 | if (!list_empty(&dev->power.entry)) | 931 | if (!list_empty(&dev->power.entry)) |
977 | list_move(&dev->power.entry, &list); | 932 | list_move(&dev->power.entry, &dpm_suspended_list); |
978 | put_device(dev); | 933 | put_device(dev); |
979 | if (async_error) | 934 | if (async_error) |
980 | break; | 935 | break; |
981 | } | 936 | } |
982 | list_splice(&list, dpm_list.prev); | ||
983 | mutex_unlock(&dpm_list_mtx); | 937 | mutex_unlock(&dpm_list_mtx); |
984 | async_synchronize_full(); | 938 | async_synchronize_full(); |
985 | if (!error) | 939 | if (!error) |
@@ -1038,22 +992,20 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
1038 | */ | 992 | */ |
1039 | static int dpm_prepare(pm_message_t state) | 993 | static int dpm_prepare(pm_message_t state) |
1040 | { | 994 | { |
1041 | struct list_head list; | ||
1042 | int error = 0; | 995 | int error = 0; |
1043 | 996 | ||
1044 | INIT_LIST_HEAD(&list); | ||
1045 | mutex_lock(&dpm_list_mtx); | 997 | mutex_lock(&dpm_list_mtx); |
1046 | transition_started = true; | ||
1047 | while (!list_empty(&dpm_list)) { | 998 | while (!list_empty(&dpm_list)) { |
1048 | struct device *dev = to_device(dpm_list.next); | 999 | struct device *dev = to_device(dpm_list.next); |
1049 | 1000 | ||
1050 | get_device(dev); | 1001 | get_device(dev); |
1051 | dev->power.status = DPM_PREPARING; | ||
1052 | mutex_unlock(&dpm_list_mtx); | 1002 | mutex_unlock(&dpm_list_mtx); |
1053 | 1003 | ||
1054 | pm_runtime_get_noresume(dev); | 1004 | pm_runtime_get_noresume(dev); |
1055 | if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { | 1005 | if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) |
1056 | /* Wake-up requested during system sleep transition. */ | 1006 | pm_wakeup_event(dev, 0); |
1007 | |||
1008 | if (pm_wakeup_pending()) { | ||
1057 | pm_runtime_put_sync(dev); | 1009 | pm_runtime_put_sync(dev); |
1058 | error = -EBUSY; | 1010 | error = -EBUSY; |
1059 | } else { | 1011 | } else { |
@@ -1062,24 +1014,22 @@ static int dpm_prepare(pm_message_t state) | |||
1062 | 1014 | ||
1063 | mutex_lock(&dpm_list_mtx); | 1015 | mutex_lock(&dpm_list_mtx); |
1064 | if (error) { | 1016 | if (error) { |
1065 | dev->power.status = DPM_ON; | ||
1066 | if (error == -EAGAIN) { | 1017 | if (error == -EAGAIN) { |
1067 | put_device(dev); | 1018 | put_device(dev); |
1068 | error = 0; | 1019 | error = 0; |
1069 | continue; | 1020 | continue; |
1070 | } | 1021 | } |
1071 | printk(KERN_ERR "PM: Failed to prepare device %s " | 1022 | printk(KERN_INFO "PM: Device %s not prepared " |
1072 | "for power transition: error %d\n", | 1023 | "for power transition: code %d\n", |
1073 | kobject_name(&dev->kobj), error); | 1024 | dev_name(dev), error); |
1074 | put_device(dev); | 1025 | put_device(dev); |
1075 | break; | 1026 | break; |
1076 | } | 1027 | } |
1077 | dev->power.status = DPM_SUSPENDING; | 1028 | dev->power.in_suspend = true; |
1078 | if (!list_empty(&dev->power.entry)) | 1029 | if (!list_empty(&dev->power.entry)) |
1079 | list_move_tail(&dev->power.entry, &list); | 1030 | list_move_tail(&dev->power.entry, &dpm_prepared_list); |
1080 | put_device(dev); | 1031 | put_device(dev); |
1081 | } | 1032 | } |
1082 | list_splice(&list, &dpm_list); | ||
1083 | mutex_unlock(&dpm_list_mtx); | 1033 | mutex_unlock(&dpm_list_mtx); |
1084 | return error; | 1034 | return error; |
1085 | } | 1035 | } |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 02c652be83e7..656493a5e073 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -250,13 +250,16 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) | |||
250 | if (!cb) | 250 | if (!cb) |
251 | return -ENOSYS; | 251 | return -ENOSYS; |
252 | 252 | ||
253 | spin_unlock_irq(&dev->power.lock); | 253 | if (dev->power.irq_safe) { |
254 | retval = cb(dev); | ||
255 | } else { | ||
256 | spin_unlock_irq(&dev->power.lock); | ||
254 | 257 | ||
255 | retval = cb(dev); | 258 | retval = cb(dev); |
256 | 259 | ||
257 | spin_lock_irq(&dev->power.lock); | 260 | spin_lock_irq(&dev->power.lock); |
261 | } | ||
258 | dev->power.runtime_error = retval; | 262 | dev->power.runtime_error = retval; |
259 | |||
260 | return retval; | 263 | return retval; |
261 | } | 264 | } |
262 | 265 | ||
@@ -404,7 +407,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
404 | goto out; | 407 | goto out; |
405 | } | 408 | } |
406 | 409 | ||
407 | if (parent && !parent->power.ignore_children) { | 410 | if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { |
408 | spin_unlock_irq(&dev->power.lock); | 411 | spin_unlock_irq(&dev->power.lock); |
409 | 412 | ||
410 | pm_request_idle(parent); | 413 | pm_request_idle(parent); |
@@ -527,10 +530,13 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
527 | 530 | ||
528 | if (!parent && dev->parent) { | 531 | if (!parent && dev->parent) { |
529 | /* | 532 | /* |
530 | * Increment the parent's resume counter and resume it if | 533 | * Increment the parent's usage counter and resume it if |
531 | * necessary. | 534 | * necessary. Not needed if dev is irq-safe; then the |
535 | * parent is permanently resumed. | ||
532 | */ | 536 | */ |
533 | parent = dev->parent; | 537 | parent = dev->parent; |
538 | if (dev->power.irq_safe) | ||
539 | goto skip_parent; | ||
534 | spin_unlock(&dev->power.lock); | 540 | spin_unlock(&dev->power.lock); |
535 | 541 | ||
536 | pm_runtime_get_noresume(parent); | 542 | pm_runtime_get_noresume(parent); |
@@ -553,6 +559,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
553 | goto out; | 559 | goto out; |
554 | goto repeat; | 560 | goto repeat; |
555 | } | 561 | } |
562 | skip_parent: | ||
556 | 563 | ||
557 | if (dev->power.no_callbacks) | 564 | if (dev->power.no_callbacks) |
558 | goto no_callback; /* Assume success. */ | 565 | goto no_callback; /* Assume success. */ |
@@ -584,7 +591,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
584 | rpm_idle(dev, RPM_ASYNC); | 591 | rpm_idle(dev, RPM_ASYNC); |
585 | 592 | ||
586 | out: | 593 | out: |
587 | if (parent) { | 594 | if (parent && !dev->power.irq_safe) { |
588 | spin_unlock_irq(&dev->power.lock); | 595 | spin_unlock_irq(&dev->power.lock); |
589 | 596 | ||
590 | pm_runtime_put(parent); | 597 | pm_runtime_put(parent); |
@@ -1065,7 +1072,6 @@ EXPORT_SYMBOL_GPL(pm_runtime_allow); | |||
1065 | * Set the power.no_callbacks flag, which tells the PM core that this | 1072 | * Set the power.no_callbacks flag, which tells the PM core that this |
1066 | * device is power-managed through its parent and has no run-time PM | 1073 | * device is power-managed through its parent and has no run-time PM |
1067 | * callbacks of its own. The run-time sysfs attributes will be removed. | 1074 | * callbacks of its own. The run-time sysfs attributes will be removed. |
1068 | * | ||
1069 | */ | 1075 | */ |
1070 | void pm_runtime_no_callbacks(struct device *dev) | 1076 | void pm_runtime_no_callbacks(struct device *dev) |
1071 | { | 1077 | { |
@@ -1078,6 +1084,27 @@ void pm_runtime_no_callbacks(struct device *dev) | |||
1078 | EXPORT_SYMBOL_GPL(pm_runtime_no_callbacks); | 1084 | EXPORT_SYMBOL_GPL(pm_runtime_no_callbacks); |
1079 | 1085 | ||
1080 | /** | 1086 | /** |
1087 | * pm_runtime_irq_safe - Leave interrupts disabled during callbacks. | ||
1088 | * @dev: Device to handle | ||
1089 | * | ||
1090 | * Set the power.irq_safe flag, which tells the PM core that the | ||
1091 | * ->runtime_suspend() and ->runtime_resume() callbacks for this device should | ||
1092 | * always be invoked with the spinlock held and interrupts disabled. It also | ||
1093 | * causes the parent's usage counter to be permanently incremented, preventing | ||
1094 | * the parent from runtime suspending -- otherwise an irq-safe child might have | ||
1095 | * to wait for a non-irq-safe parent. | ||
1096 | */ | ||
1097 | void pm_runtime_irq_safe(struct device *dev) | ||
1098 | { | ||
1099 | if (dev->parent) | ||
1100 | pm_runtime_get_sync(dev->parent); | ||
1101 | spin_lock_irq(&dev->power.lock); | ||
1102 | dev->power.irq_safe = 1; | ||
1103 | spin_unlock_irq(&dev->power.lock); | ||
1104 | } | ||
1105 | EXPORT_SYMBOL_GPL(pm_runtime_irq_safe); | ||
1106 | |||
1107 | /** | ||
1081 | * update_autosuspend - Handle a change to a device's autosuspend settings. | 1108 | * update_autosuspend - Handle a change to a device's autosuspend settings. |
1082 | * @dev: Device to handle. | 1109 | * @dev: Device to handle. |
1083 | * @old_delay: The former autosuspend_delay value. | 1110 | * @old_delay: The former autosuspend_delay value. |
@@ -1199,4 +1226,6 @@ void pm_runtime_remove(struct device *dev) | |||
1199 | /* Change the status back to 'suspended' to match the initial status. */ | 1226 | /* Change the status back to 'suspended' to match the initial status. */ |
1200 | if (dev->power.runtime_status == RPM_ACTIVE) | 1227 | if (dev->power.runtime_status == RPM_ACTIVE) |
1201 | pm_runtime_set_suspended(dev); | 1228 | pm_runtime_set_suspended(dev); |
1229 | if (dev->power.irq_safe && dev->parent) | ||
1230 | pm_runtime_put_sync(dev->parent); | ||
1202 | } | 1231 | } |
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 71c5528e1c35..8ec406d8f548 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -542,26 +542,26 @@ static void pm_wakeup_update_hit_counts(void) | |||
542 | } | 542 | } |
543 | 543 | ||
544 | /** | 544 | /** |
545 | * pm_check_wakeup_events - Check for new wakeup events. | 545 | * pm_wakeup_pending - Check if power transition in progress should be aborted. |
546 | * | 546 | * |
547 | * Compare the current number of registered wakeup events with its preserved | 547 | * Compare the current number of registered wakeup events with its preserved |
548 | * value from the past to check if new wakeup events have been registered since | 548 | * value from the past and return true if new wakeup events have been registered |
549 | * the old value was stored. Check if the current number of wakeup events being | 549 | * since the old value was stored. Also return true if the current number of |
550 | * processed is zero. | 550 | * wakeup events being processed is different from zero. |
551 | */ | 551 | */ |
552 | bool pm_check_wakeup_events(void) | 552 | bool pm_wakeup_pending(void) |
553 | { | 553 | { |
554 | unsigned long flags; | 554 | unsigned long flags; |
555 | bool ret = true; | 555 | bool ret = false; |
556 | 556 | ||
557 | spin_lock_irqsave(&events_lock, flags); | 557 | spin_lock_irqsave(&events_lock, flags); |
558 | if (events_check_enabled) { | 558 | if (events_check_enabled) { |
559 | ret = ((unsigned int)atomic_read(&event_count) == saved_count) | 559 | ret = ((unsigned int)atomic_read(&event_count) != saved_count) |
560 | && !atomic_read(&events_in_progress); | 560 | || atomic_read(&events_in_progress); |
561 | events_check_enabled = ret; | 561 | events_check_enabled = !ret; |
562 | } | 562 | } |
563 | spin_unlock_irqrestore(&events_lock, flags); | 563 | spin_unlock_irqrestore(&events_lock, flags); |
564 | if (!ret) | 564 | if (ret) |
565 | pm_wakeup_update_hit_counts(); | 565 | pm_wakeup_update_hit_counts(); |
566 | return ret; | 566 | return ret; |
567 | } | 567 | } |