diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:37:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:37:15 -0400 |
commit | 542a086ac72fb193cbc1b996963a572269e57743 (patch) | |
tree | b137c08037cca4ffc8a156a891a01113b3b8edce /drivers/base | |
parent | 1d1fdd95df681f0c065d90ffaafa215a0e8825e2 (diff) | |
parent | 1eeeef153c02f5856ec109fa532eb5f31c39f85c (diff) |
Merge tag 'driver-core-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core patches from Greg KH:
"Here's the big driver core pull request for 3.12-rc1.
Lots of tiny changes here fixing up the way sysfs attributes are
created, to try to make drivers simpler, and fix a whole class race
conditions with creations of device attributes after the device was
announced to userspace.
All the various pieces are acked by the different subsystem
maintainers"
* tag 'driver-core-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (119 commits)
firmware loader: fix pending_fw_head list corruption
drivers/base/memory.c: introduce help macro to_memory_block
dynamic debug: line queries failing due to uninitialized local variable
sysfs: sysfs_create_groups returns a value.
debugfs: provide debugfs_create_x64() when disabled
rbd: convert bus code to use bus_groups
firmware: dcdbas: use binary attribute groups
sysfs: add sysfs_create/remove_groups for when SYSFS is not enabled
driver core: add #include <linux/sysfs.h> to core files.
HID: convert bus code to use dev_groups
Input: serio: convert bus code to use drv_groups
Input: gameport: convert bus code to use drv_groups
driver core: firmware: use __ATTR_RW()
driver core: core: use DEVICE_ATTR_RO
driver core: bus: use DRIVER_ATTR_WO()
driver core: create write-only attribute macros for devices and drivers
sysfs: create __ATTR_WO()
driver-core: platform: convert bus code to use dev_groups
workqueue: convert bus code to use dev_groups
MEI: convert bus code to use dev_groups
...
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/base.h | 10 | ||||
-rw-r--r-- | drivers/base/bus.c | 60 | ||||
-rw-r--r-- | drivers/base/class.c | 4 | ||||
-rw-r--r-- | drivers/base/core.c | 107 | ||||
-rw-r--r-- | drivers/base/cpu.c | 6 | ||||
-rw-r--r-- | drivers/base/dma-contiguous.c | 4 | ||||
-rw-r--r-- | drivers/base/driver.c | 31 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 24 | ||||
-rw-r--r-- | drivers/base/memory.c | 258 | ||||
-rw-r--r-- | drivers/base/platform.c | 14 | ||||
-rw-r--r-- | drivers/base/power/sysfs.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-debugfs.c | 2 | ||||
-rw-r--r-- | drivers/base/topology.c | 20 |
13 files changed, 247 insertions, 295 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index b8bdfe61daa6..2cbc6774f4cd 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -119,6 +119,16 @@ static inline int driver_match_device(struct device_driver *drv, | |||
119 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; | 119 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; |
120 | } | 120 | } |
121 | 121 | ||
122 | extern int driver_add_groups(struct device_driver *drv, | ||
123 | const struct attribute_group **groups); | ||
124 | extern void driver_remove_groups(struct device_driver *drv, | ||
125 | const struct attribute_group **groups); | ||
126 | |||
127 | extern int device_add_groups(struct device *dev, | ||
128 | const struct attribute_group **groups); | ||
129 | extern void device_remove_groups(struct device *dev, | ||
130 | const struct attribute_group **groups); | ||
131 | |||
122 | extern char *make_class_name(const char *name, struct kobject *kobj); | 132 | extern char *make_class_name(const char *name, struct kobject *kobj); |
123 | 133 | ||
124 | extern int devres_release_all(struct device *dev); | 134 | extern int devres_release_all(struct device *dev); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index d414331b480e..4c289ab91357 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/sysfs.h> | ||
20 | #include "base.h" | 21 | #include "base.h" |
21 | #include "power/power.h" | 22 | #include "power/power.h" |
22 | 23 | ||
@@ -165,8 +166,8 @@ static const struct kset_uevent_ops bus_uevent_ops = { | |||
165 | static struct kset *bus_kset; | 166 | static struct kset *bus_kset; |
166 | 167 | ||
167 | /* Manually detach a device from its associated driver. */ | 168 | /* Manually detach a device from its associated driver. */ |
168 | static ssize_t driver_unbind(struct device_driver *drv, | 169 | static ssize_t unbind_store(struct device_driver *drv, const char *buf, |
169 | const char *buf, size_t count) | 170 | size_t count) |
170 | { | 171 | { |
171 | struct bus_type *bus = bus_get(drv->bus); | 172 | struct bus_type *bus = bus_get(drv->bus); |
172 | struct device *dev; | 173 | struct device *dev; |
@@ -185,15 +186,15 @@ static ssize_t driver_unbind(struct device_driver *drv, | |||
185 | bus_put(bus); | 186 | bus_put(bus); |
186 | return err; | 187 | return err; |
187 | } | 188 | } |
188 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); | 189 | static DRIVER_ATTR_WO(unbind); |
189 | 190 | ||
190 | /* | 191 | /* |
191 | * Manually attach a device to a driver. | 192 | * Manually attach a device to a driver. |
192 | * Note: the driver must want to bind to the device, | 193 | * Note: the driver must want to bind to the device, |
193 | * it is not possible to override the driver's id table. | 194 | * it is not possible to override the driver's id table. |
194 | */ | 195 | */ |
195 | static ssize_t driver_bind(struct device_driver *drv, | 196 | static ssize_t bind_store(struct device_driver *drv, const char *buf, |
196 | const char *buf, size_t count) | 197 | size_t count) |
197 | { | 198 | { |
198 | struct bus_type *bus = bus_get(drv->bus); | 199 | struct bus_type *bus = bus_get(drv->bus); |
199 | struct device *dev; | 200 | struct device *dev; |
@@ -221,7 +222,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
221 | bus_put(bus); | 222 | bus_put(bus); |
222 | return err; | 223 | return err; |
223 | } | 224 | } |
224 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 225 | static DRIVER_ATTR_WO(bind); |
225 | 226 | ||
226 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) | 227 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) |
227 | { | 228 | { |
@@ -460,7 +461,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
460 | if (!bus->dev_attrs) | 461 | if (!bus->dev_attrs) |
461 | return 0; | 462 | return 0; |
462 | 463 | ||
463 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { | 464 | for (i = 0; bus->dev_attrs[i].attr.name; i++) { |
464 | error = device_create_file(dev, &bus->dev_attrs[i]); | 465 | error = device_create_file(dev, &bus->dev_attrs[i]); |
465 | if (error) { | 466 | if (error) { |
466 | while (--i >= 0) | 467 | while (--i >= 0) |
@@ -476,7 +477,7 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev) | |||
476 | int i; | 477 | int i; |
477 | 478 | ||
478 | if (bus->dev_attrs) { | 479 | if (bus->dev_attrs) { |
479 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) | 480 | for (i = 0; bus->dev_attrs[i].attr.name; i++) |
480 | device_remove_file(dev, &bus->dev_attrs[i]); | 481 | device_remove_file(dev, &bus->dev_attrs[i]); |
481 | } | 482 | } |
482 | } | 483 | } |
@@ -499,6 +500,9 @@ int bus_add_device(struct device *dev) | |||
499 | error = device_add_attrs(bus, dev); | 500 | error = device_add_attrs(bus, dev); |
500 | if (error) | 501 | if (error) |
501 | goto out_put; | 502 | goto out_put; |
503 | error = device_add_groups(dev, bus->dev_groups); | ||
504 | if (error) | ||
505 | goto out_groups; | ||
502 | error = sysfs_create_link(&bus->p->devices_kset->kobj, | 506 | error = sysfs_create_link(&bus->p->devices_kset->kobj, |
503 | &dev->kobj, dev_name(dev)); | 507 | &dev->kobj, dev_name(dev)); |
504 | if (error) | 508 | if (error) |
@@ -513,6 +517,8 @@ int bus_add_device(struct device *dev) | |||
513 | 517 | ||
514 | out_subsys: | 518 | out_subsys: |
515 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); | 519 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); |
520 | out_groups: | ||
521 | device_remove_groups(dev, bus->dev_groups); | ||
516 | out_id: | 522 | out_id: |
517 | device_remove_attrs(bus, dev); | 523 | device_remove_attrs(bus, dev); |
518 | out_put: | 524 | out_put: |
@@ -575,6 +581,7 @@ void bus_remove_device(struct device *dev) | |||
575 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 581 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
576 | dev_name(dev)); | 582 | dev_name(dev)); |
577 | device_remove_attrs(dev->bus, dev); | 583 | device_remove_attrs(dev->bus, dev); |
584 | device_remove_groups(dev, dev->bus->dev_groups); | ||
578 | if (klist_node_attached(&dev->p->knode_bus)) | 585 | if (klist_node_attached(&dev->p->knode_bus)) |
579 | klist_del(&dev->p->knode_bus); | 586 | klist_del(&dev->p->knode_bus); |
580 | 587 | ||
@@ -590,7 +597,7 @@ static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) | |||
590 | int i; | 597 | int i; |
591 | 598 | ||
592 | if (bus->drv_attrs) { | 599 | if (bus->drv_attrs) { |
593 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { | 600 | for (i = 0; bus->drv_attrs[i].attr.name; i++) { |
594 | error = driver_create_file(drv, &bus->drv_attrs[i]); | 601 | error = driver_create_file(drv, &bus->drv_attrs[i]); |
595 | if (error) | 602 | if (error) |
596 | goto err; | 603 | goto err; |
@@ -610,7 +617,7 @@ static void driver_remove_attrs(struct bus_type *bus, | |||
610 | int i; | 617 | int i; |
611 | 618 | ||
612 | if (bus->drv_attrs) { | 619 | if (bus->drv_attrs) { |
613 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) | 620 | for (i = 0; bus->drv_attrs[i].attr.name; i++) |
614 | driver_remove_file(drv, &bus->drv_attrs[i]); | 621 | driver_remove_file(drv, &bus->drv_attrs[i]); |
615 | } | 622 | } |
616 | } | 623 | } |
@@ -659,8 +666,8 @@ static void remove_probe_files(struct bus_type *bus) | |||
659 | bus_remove_file(bus, &bus_attr_drivers_probe); | 666 | bus_remove_file(bus, &bus_attr_drivers_probe); |
660 | } | 667 | } |
661 | 668 | ||
662 | static ssize_t driver_uevent_store(struct device_driver *drv, | 669 | static ssize_t uevent_store(struct device_driver *drv, const char *buf, |
663 | const char *buf, size_t count) | 670 | size_t count) |
664 | { | 671 | { |
665 | enum kobject_action action; | 672 | enum kobject_action action; |
666 | 673 | ||
@@ -668,7 +675,7 @@ static ssize_t driver_uevent_store(struct device_driver *drv, | |||
668 | kobject_uevent(&drv->p->kobj, action); | 675 | kobject_uevent(&drv->p->kobj, action); |
669 | return count; | 676 | return count; |
670 | } | 677 | } |
671 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); | 678 | static DRIVER_ATTR_WO(uevent); |
672 | 679 | ||
673 | /** | 680 | /** |
674 | * bus_add_driver - Add a driver to the bus. | 681 | * bus_add_driver - Add a driver to the bus. |
@@ -719,6 +726,10 @@ int bus_add_driver(struct device_driver *drv) | |||
719 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", | 726 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", |
720 | __func__, drv->name); | 727 | __func__, drv->name); |
721 | } | 728 | } |
729 | error = driver_add_groups(drv, bus->drv_groups); | ||
730 | if (error) | ||
731 | printk(KERN_ERR "%s: driver_create_groups(%s) failed\n", | ||
732 | __func__, drv->name); | ||
722 | 733 | ||
723 | if (!drv->suppress_bind_attrs) { | 734 | if (!drv->suppress_bind_attrs) { |
724 | error = add_bind_files(drv); | 735 | error = add_bind_files(drv); |
@@ -756,6 +767,7 @@ void bus_remove_driver(struct device_driver *drv) | |||
756 | if (!drv->suppress_bind_attrs) | 767 | if (!drv->suppress_bind_attrs) |
757 | remove_bind_files(drv); | 768 | remove_bind_files(drv); |
758 | driver_remove_attrs(drv->bus, drv); | 769 | driver_remove_attrs(drv->bus, drv); |
770 | driver_remove_groups(drv, drv->bus->drv_groups); | ||
759 | driver_remove_file(drv, &driver_attr_uevent); | 771 | driver_remove_file(drv, &driver_attr_uevent); |
760 | klist_remove(&drv->p->knode_bus); | 772 | klist_remove(&drv->p->knode_bus); |
761 | pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); | 773 | pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); |
@@ -846,7 +858,7 @@ static int bus_add_attrs(struct bus_type *bus) | |||
846 | int i; | 858 | int i; |
847 | 859 | ||
848 | if (bus->bus_attrs) { | 860 | if (bus->bus_attrs) { |
849 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { | 861 | for (i = 0; bus->bus_attrs[i].attr.name; i++) { |
850 | error = bus_create_file(bus, &bus->bus_attrs[i]); | 862 | error = bus_create_file(bus, &bus->bus_attrs[i]); |
851 | if (error) | 863 | if (error) |
852 | goto err; | 864 | goto err; |
@@ -865,11 +877,23 @@ static void bus_remove_attrs(struct bus_type *bus) | |||
865 | int i; | 877 | int i; |
866 | 878 | ||
867 | if (bus->bus_attrs) { | 879 | if (bus->bus_attrs) { |
868 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) | 880 | for (i = 0; bus->bus_attrs[i].attr.name; i++) |
869 | bus_remove_file(bus, &bus->bus_attrs[i]); | 881 | bus_remove_file(bus, &bus->bus_attrs[i]); |
870 | } | 882 | } |
871 | } | 883 | } |
872 | 884 | ||
885 | static int bus_add_groups(struct bus_type *bus, | ||
886 | const struct attribute_group **groups) | ||
887 | { | ||
888 | return sysfs_create_groups(&bus->p->subsys.kobj, groups); | ||
889 | } | ||
890 | |||
891 | static void bus_remove_groups(struct bus_type *bus, | ||
892 | const struct attribute_group **groups) | ||
893 | { | ||
894 | sysfs_remove_groups(&bus->p->subsys.kobj, groups); | ||
895 | } | ||
896 | |||
873 | static void klist_devices_get(struct klist_node *n) | 897 | static void klist_devices_get(struct klist_node *n) |
874 | { | 898 | { |
875 | struct device_private *dev_prv = to_device_private_bus(n); | 899 | struct device_private *dev_prv = to_device_private_bus(n); |
@@ -962,10 +986,15 @@ int bus_register(struct bus_type *bus) | |||
962 | retval = bus_add_attrs(bus); | 986 | retval = bus_add_attrs(bus); |
963 | if (retval) | 987 | if (retval) |
964 | goto bus_attrs_fail; | 988 | goto bus_attrs_fail; |
989 | retval = bus_add_groups(bus, bus->bus_groups); | ||
990 | if (retval) | ||
991 | goto bus_groups_fail; | ||
965 | 992 | ||
966 | pr_debug("bus: '%s': registered\n", bus->name); | 993 | pr_debug("bus: '%s': registered\n", bus->name); |
967 | return 0; | 994 | return 0; |
968 | 995 | ||
996 | bus_groups_fail: | ||
997 | bus_remove_attrs(bus); | ||
969 | bus_attrs_fail: | 998 | bus_attrs_fail: |
970 | remove_probe_files(bus); | 999 | remove_probe_files(bus); |
971 | bus_probe_files_fail: | 1000 | bus_probe_files_fail: |
@@ -996,6 +1025,7 @@ void bus_unregister(struct bus_type *bus) | |||
996 | if (bus->dev_root) | 1025 | if (bus->dev_root) |
997 | device_unregister(bus->dev_root); | 1026 | device_unregister(bus->dev_root); |
998 | bus_remove_attrs(bus); | 1027 | bus_remove_attrs(bus); |
1028 | bus_remove_groups(bus, bus->bus_groups); | ||
999 | remove_probe_files(bus); | 1029 | remove_probe_files(bus); |
1000 | kset_unregister(bus->p->drivers_kset); | 1030 | kset_unregister(bus->p->drivers_kset); |
1001 | kset_unregister(bus->p->devices_kset); | 1031 | kset_unregister(bus->p->devices_kset); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 3ce845471327..8b7818b80056 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -135,7 +135,7 @@ static int add_class_attrs(struct class *cls) | |||
135 | int error = 0; | 135 | int error = 0; |
136 | 136 | ||
137 | if (cls->class_attrs) { | 137 | if (cls->class_attrs) { |
138 | for (i = 0; attr_name(cls->class_attrs[i]); i++) { | 138 | for (i = 0; cls->class_attrs[i].attr.name; i++) { |
139 | error = class_create_file(cls, &cls->class_attrs[i]); | 139 | error = class_create_file(cls, &cls->class_attrs[i]); |
140 | if (error) | 140 | if (error) |
141 | goto error; | 141 | goto error; |
@@ -154,7 +154,7 @@ static void remove_class_attrs(struct class *cls) | |||
154 | int i; | 154 | int i; |
155 | 155 | ||
156 | if (cls->class_attrs) { | 156 | if (cls->class_attrs) { |
157 | for (i = 0; attr_name(cls->class_attrs[i]); i++) | 157 | for (i = 0; cls->class_attrs[i].attr.name; i++) |
158 | class_remove_file(cls, &cls->class_attrs[i]); | 158 | class_remove_file(cls, &cls->class_attrs[i]); |
159 | } | 159 | } |
160 | } | 160 | } |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 8856d74545d9..c7b0925f627a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/async.h> | 26 | #include <linux/async.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
29 | #include <linux/sysfs.h> | ||
29 | 30 | ||
30 | #include "base.h" | 31 | #include "base.h" |
31 | #include "power/power.h" | 32 | #include "power/power.h" |
@@ -36,9 +37,9 @@ long sysfs_deprecated = 1; | |||
36 | #else | 37 | #else |
37 | long sysfs_deprecated = 0; | 38 | long sysfs_deprecated = 0; |
38 | #endif | 39 | #endif |
39 | static __init int sysfs_deprecated_setup(char *arg) | 40 | static int __init sysfs_deprecated_setup(char *arg) |
40 | { | 41 | { |
41 | return strict_strtol(arg, 10, &sysfs_deprecated); | 42 | return kstrtol(arg, 10, &sysfs_deprecated); |
42 | } | 43 | } |
43 | early_param("sysfs.deprecated", sysfs_deprecated_setup); | 44 | early_param("sysfs.deprecated", sysfs_deprecated_setup); |
44 | #endif | 45 | #endif |
@@ -345,7 +346,7 @@ static const struct kset_uevent_ops device_uevent_ops = { | |||
345 | .uevent = dev_uevent, | 346 | .uevent = dev_uevent, |
346 | }; | 347 | }; |
347 | 348 | ||
348 | static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, | 349 | static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, |
349 | char *buf) | 350 | char *buf) |
350 | { | 351 | { |
351 | struct kobject *top_kobj; | 352 | struct kobject *top_kobj; |
@@ -388,7 +389,7 @@ out: | |||
388 | return count; | 389 | return count; |
389 | } | 390 | } |
390 | 391 | ||
391 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | 392 | static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, |
392 | const char *buf, size_t count) | 393 | const char *buf, size_t count) |
393 | { | 394 | { |
394 | enum kobject_action action; | 395 | enum kobject_action action; |
@@ -399,11 +400,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
399 | dev_err(dev, "uevent: unknown action-string\n"); | 400 | dev_err(dev, "uevent: unknown action-string\n"); |
400 | return count; | 401 | return count; |
401 | } | 402 | } |
403 | static DEVICE_ATTR_RW(uevent); | ||
402 | 404 | ||
403 | static struct device_attribute uevent_attr = | 405 | static ssize_t online_show(struct device *dev, struct device_attribute *attr, |
404 | __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); | ||
405 | |||
406 | static ssize_t show_online(struct device *dev, struct device_attribute *attr, | ||
407 | char *buf) | 406 | char *buf) |
408 | { | 407 | { |
409 | bool val; | 408 | bool val; |
@@ -414,7 +413,7 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr, | |||
414 | return sprintf(buf, "%u\n", val); | 413 | return sprintf(buf, "%u\n", val); |
415 | } | 414 | } |
416 | 415 | ||
417 | static ssize_t store_online(struct device *dev, struct device_attribute *attr, | 416 | static ssize_t online_store(struct device *dev, struct device_attribute *attr, |
418 | const char *buf, size_t count) | 417 | const char *buf, size_t count) |
419 | { | 418 | { |
420 | bool val; | 419 | bool val; |
@@ -429,9 +428,7 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr, | |||
429 | unlock_device_hotplug(); | 428 | unlock_device_hotplug(); |
430 | return ret < 0 ? ret : count; | 429 | return ret < 0 ? ret : count; |
431 | } | 430 | } |
432 | 431 | static DEVICE_ATTR_RW(online); | |
433 | static struct device_attribute online_attr = | ||
434 | __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online); | ||
435 | 432 | ||
436 | static int device_add_attributes(struct device *dev, | 433 | static int device_add_attributes(struct device *dev, |
437 | struct device_attribute *attrs) | 434 | struct device_attribute *attrs) |
@@ -440,7 +437,7 @@ static int device_add_attributes(struct device *dev, | |||
440 | int i; | 437 | int i; |
441 | 438 | ||
442 | if (attrs) { | 439 | if (attrs) { |
443 | for (i = 0; attr_name(attrs[i]); i++) { | 440 | for (i = 0; attrs[i].attr.name; i++) { |
444 | error = device_create_file(dev, &attrs[i]); | 441 | error = device_create_file(dev, &attrs[i]); |
445 | if (error) | 442 | if (error) |
446 | break; | 443 | break; |
@@ -458,7 +455,7 @@ static void device_remove_attributes(struct device *dev, | |||
458 | int i; | 455 | int i; |
459 | 456 | ||
460 | if (attrs) | 457 | if (attrs) |
461 | for (i = 0; attr_name(attrs[i]); i++) | 458 | for (i = 0; attrs[i].attr.name; i++) |
462 | device_remove_file(dev, &attrs[i]); | 459 | device_remove_file(dev, &attrs[i]); |
463 | } | 460 | } |
464 | 461 | ||
@@ -469,7 +466,7 @@ static int device_add_bin_attributes(struct device *dev, | |||
469 | int i; | 466 | int i; |
470 | 467 | ||
471 | if (attrs) { | 468 | if (attrs) { |
472 | for (i = 0; attr_name(attrs[i]); i++) { | 469 | for (i = 0; attrs[i].attr.name; i++) { |
473 | error = device_create_bin_file(dev, &attrs[i]); | 470 | error = device_create_bin_file(dev, &attrs[i]); |
474 | if (error) | 471 | if (error) |
475 | break; | 472 | break; |
@@ -487,38 +484,19 @@ static void device_remove_bin_attributes(struct device *dev, | |||
487 | int i; | 484 | int i; |
488 | 485 | ||
489 | if (attrs) | 486 | if (attrs) |
490 | for (i = 0; attr_name(attrs[i]); i++) | 487 | for (i = 0; attrs[i].attr.name; i++) |
491 | device_remove_bin_file(dev, &attrs[i]); | 488 | device_remove_bin_file(dev, &attrs[i]); |
492 | } | 489 | } |
493 | 490 | ||
494 | static int device_add_groups(struct device *dev, | 491 | int device_add_groups(struct device *dev, const struct attribute_group **groups) |
495 | const struct attribute_group **groups) | ||
496 | { | 492 | { |
497 | int error = 0; | 493 | return sysfs_create_groups(&dev->kobj, groups); |
498 | int i; | ||
499 | |||
500 | if (groups) { | ||
501 | for (i = 0; groups[i]; i++) { | ||
502 | error = sysfs_create_group(&dev->kobj, groups[i]); | ||
503 | if (error) { | ||
504 | while (--i >= 0) | ||
505 | sysfs_remove_group(&dev->kobj, | ||
506 | groups[i]); | ||
507 | break; | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | return error; | ||
512 | } | 494 | } |
513 | 495 | ||
514 | static void device_remove_groups(struct device *dev, | 496 | void device_remove_groups(struct device *dev, |
515 | const struct attribute_group **groups) | 497 | const struct attribute_group **groups) |
516 | { | 498 | { |
517 | int i; | 499 | sysfs_remove_groups(&dev->kobj, groups); |
518 | |||
519 | if (groups) | ||
520 | for (i = 0; groups[i]; i++) | ||
521 | sysfs_remove_group(&dev->kobj, groups[i]); | ||
522 | } | 500 | } |
523 | 501 | ||
524 | static int device_add_attrs(struct device *dev) | 502 | static int device_add_attrs(struct device *dev) |
@@ -550,7 +528,7 @@ static int device_add_attrs(struct device *dev) | |||
550 | goto err_remove_type_groups; | 528 | goto err_remove_type_groups; |
551 | 529 | ||
552 | if (device_supports_offline(dev) && !dev->offline_disabled) { | 530 | if (device_supports_offline(dev) && !dev->offline_disabled) { |
553 | error = device_create_file(dev, &online_attr); | 531 | error = device_create_file(dev, &dev_attr_online); |
554 | if (error) | 532 | if (error) |
555 | goto err_remove_type_groups; | 533 | goto err_remove_type_groups; |
556 | } | 534 | } |
@@ -578,7 +556,7 @@ static void device_remove_attrs(struct device *dev) | |||
578 | struct class *class = dev->class; | 556 | struct class *class = dev->class; |
579 | const struct device_type *type = dev->type; | 557 | const struct device_type *type = dev->type; |
580 | 558 | ||
581 | device_remove_file(dev, &online_attr); | 559 | device_remove_file(dev, &dev_attr_online); |
582 | device_remove_groups(dev, dev->groups); | 560 | device_remove_groups(dev, dev->groups); |
583 | 561 | ||
584 | if (type) | 562 | if (type) |
@@ -591,15 +569,12 @@ static void device_remove_attrs(struct device *dev) | |||
591 | } | 569 | } |
592 | } | 570 | } |
593 | 571 | ||
594 | 572 | static ssize_t dev_show(struct device *dev, struct device_attribute *attr, | |
595 | static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | ||
596 | char *buf) | 573 | char *buf) |
597 | { | 574 | { |
598 | return print_dev_t(buf, dev->devt); | 575 | return print_dev_t(buf, dev->devt); |
599 | } | 576 | } |
600 | 577 | static DEVICE_ATTR_RO(dev); | |
601 | static struct device_attribute devt_attr = | ||
602 | __ATTR(dev, S_IRUGO, show_dev, NULL); | ||
603 | 578 | ||
604 | /* /sys/devices/ */ | 579 | /* /sys/devices/ */ |
605 | struct kset *devices_kset; | 580 | struct kset *devices_kset; |
@@ -626,6 +601,7 @@ int device_create_file(struct device *dev, | |||
626 | 601 | ||
627 | return error; | 602 | return error; |
628 | } | 603 | } |
604 | EXPORT_SYMBOL_GPL(device_create_file); | ||
629 | 605 | ||
630 | /** | 606 | /** |
631 | * device_remove_file - remove sysfs attribute file. | 607 | * device_remove_file - remove sysfs attribute file. |
@@ -638,6 +614,7 @@ void device_remove_file(struct device *dev, | |||
638 | if (dev) | 614 | if (dev) |
639 | sysfs_remove_file(&dev->kobj, &attr->attr); | 615 | sysfs_remove_file(&dev->kobj, &attr->attr); |
640 | } | 616 | } |
617 | EXPORT_SYMBOL_GPL(device_remove_file); | ||
641 | 618 | ||
642 | /** | 619 | /** |
643 | * device_create_bin_file - create sysfs binary attribute file for device. | 620 | * device_create_bin_file - create sysfs binary attribute file for device. |
@@ -748,6 +725,7 @@ void device_initialize(struct device *dev) | |||
748 | device_pm_init(dev); | 725 | device_pm_init(dev); |
749 | set_dev_node(dev, -1); | 726 | set_dev_node(dev, -1); |
750 | } | 727 | } |
728 | EXPORT_SYMBOL_GPL(device_initialize); | ||
751 | 729 | ||
752 | struct kobject *virtual_device_parent(struct device *dev) | 730 | struct kobject *virtual_device_parent(struct device *dev) |
753 | { | 731 | { |
@@ -1100,12 +1078,12 @@ int device_add(struct device *dev) | |||
1100 | if (platform_notify) | 1078 | if (platform_notify) |
1101 | platform_notify(dev); | 1079 | platform_notify(dev); |
1102 | 1080 | ||
1103 | error = device_create_file(dev, &uevent_attr); | 1081 | error = device_create_file(dev, &dev_attr_uevent); |
1104 | if (error) | 1082 | if (error) |
1105 | goto attrError; | 1083 | goto attrError; |
1106 | 1084 | ||
1107 | if (MAJOR(dev->devt)) { | 1085 | if (MAJOR(dev->devt)) { |
1108 | error = device_create_file(dev, &devt_attr); | 1086 | error = device_create_file(dev, &dev_attr_dev); |
1109 | if (error) | 1087 | if (error) |
1110 | goto ueventattrError; | 1088 | goto ueventattrError; |
1111 | 1089 | ||
@@ -1172,9 +1150,9 @@ done: | |||
1172 | device_remove_sys_dev_entry(dev); | 1150 | device_remove_sys_dev_entry(dev); |
1173 | devtattrError: | 1151 | devtattrError: |
1174 | if (MAJOR(dev->devt)) | 1152 | if (MAJOR(dev->devt)) |
1175 | device_remove_file(dev, &devt_attr); | 1153 | device_remove_file(dev, &dev_attr_dev); |
1176 | ueventattrError: | 1154 | ueventattrError: |
1177 | device_remove_file(dev, &uevent_attr); | 1155 | device_remove_file(dev, &dev_attr_uevent); |
1178 | attrError: | 1156 | attrError: |
1179 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 1157 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
1180 | kobject_del(&dev->kobj); | 1158 | kobject_del(&dev->kobj); |
@@ -1187,6 +1165,7 @@ name_error: | |||
1187 | dev->p = NULL; | 1165 | dev->p = NULL; |
1188 | goto done; | 1166 | goto done; |
1189 | } | 1167 | } |
1168 | EXPORT_SYMBOL_GPL(device_add); | ||
1190 | 1169 | ||
1191 | /** | 1170 | /** |
1192 | * device_register - register a device with the system. | 1171 | * device_register - register a device with the system. |
@@ -1211,6 +1190,7 @@ int device_register(struct device *dev) | |||
1211 | device_initialize(dev); | 1190 | device_initialize(dev); |
1212 | return device_add(dev); | 1191 | return device_add(dev); |
1213 | } | 1192 | } |
1193 | EXPORT_SYMBOL_GPL(device_register); | ||
1214 | 1194 | ||
1215 | /** | 1195 | /** |
1216 | * get_device - increment reference count for device. | 1196 | * get_device - increment reference count for device. |
@@ -1224,6 +1204,7 @@ struct device *get_device(struct device *dev) | |||
1224 | { | 1204 | { |
1225 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; | 1205 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; |
1226 | } | 1206 | } |
1207 | EXPORT_SYMBOL_GPL(get_device); | ||
1227 | 1208 | ||
1228 | /** | 1209 | /** |
1229 | * put_device - decrement reference count. | 1210 | * put_device - decrement reference count. |
@@ -1235,6 +1216,7 @@ void put_device(struct device *dev) | |||
1235 | if (dev) | 1216 | if (dev) |
1236 | kobject_put(&dev->kobj); | 1217 | kobject_put(&dev->kobj); |
1237 | } | 1218 | } |
1219 | EXPORT_SYMBOL_GPL(put_device); | ||
1238 | 1220 | ||
1239 | /** | 1221 | /** |
1240 | * device_del - delete device from system. | 1222 | * device_del - delete device from system. |
@@ -1266,7 +1248,7 @@ void device_del(struct device *dev) | |||
1266 | if (MAJOR(dev->devt)) { | 1248 | if (MAJOR(dev->devt)) { |
1267 | devtmpfs_delete_node(dev); | 1249 | devtmpfs_delete_node(dev); |
1268 | device_remove_sys_dev_entry(dev); | 1250 | device_remove_sys_dev_entry(dev); |
1269 | device_remove_file(dev, &devt_attr); | 1251 | device_remove_file(dev, &dev_attr_dev); |
1270 | } | 1252 | } |
1271 | if (dev->class) { | 1253 | if (dev->class) { |
1272 | device_remove_class_symlinks(dev); | 1254 | device_remove_class_symlinks(dev); |
@@ -1281,7 +1263,7 @@ void device_del(struct device *dev) | |||
1281 | klist_del(&dev->knode_class); | 1263 | klist_del(&dev->knode_class); |
1282 | mutex_unlock(&dev->class->p->mutex); | 1264 | mutex_unlock(&dev->class->p->mutex); |
1283 | } | 1265 | } |
1284 | device_remove_file(dev, &uevent_attr); | 1266 | device_remove_file(dev, &dev_attr_uevent); |
1285 | device_remove_attrs(dev); | 1267 | device_remove_attrs(dev); |
1286 | bus_remove_device(dev); | 1268 | bus_remove_device(dev); |
1287 | device_pm_remove(dev); | 1269 | device_pm_remove(dev); |
@@ -1297,6 +1279,7 @@ void device_del(struct device *dev) | |||
1297 | kobject_del(&dev->kobj); | 1279 | kobject_del(&dev->kobj); |
1298 | put_device(parent); | 1280 | put_device(parent); |
1299 | } | 1281 | } |
1282 | EXPORT_SYMBOL_GPL(device_del); | ||
1300 | 1283 | ||
1301 | /** | 1284 | /** |
1302 | * device_unregister - unregister device from system. | 1285 | * device_unregister - unregister device from system. |
@@ -1315,6 +1298,7 @@ void device_unregister(struct device *dev) | |||
1315 | device_del(dev); | 1298 | device_del(dev); |
1316 | put_device(dev); | 1299 | put_device(dev); |
1317 | } | 1300 | } |
1301 | EXPORT_SYMBOL_GPL(device_unregister); | ||
1318 | 1302 | ||
1319 | static struct device *next_device(struct klist_iter *i) | 1303 | static struct device *next_device(struct klist_iter *i) |
1320 | { | 1304 | { |
@@ -1403,6 +1387,7 @@ int device_for_each_child(struct device *parent, void *data, | |||
1403 | klist_iter_exit(&i); | 1387 | klist_iter_exit(&i); |
1404 | return error; | 1388 | return error; |
1405 | } | 1389 | } |
1390 | EXPORT_SYMBOL_GPL(device_for_each_child); | ||
1406 | 1391 | ||
1407 | /** | 1392 | /** |
1408 | * device_find_child - device iterator for locating a particular device. | 1393 | * device_find_child - device iterator for locating a particular device. |
@@ -1437,6 +1422,7 @@ struct device *device_find_child(struct device *parent, void *data, | |||
1437 | klist_iter_exit(&i); | 1422 | klist_iter_exit(&i); |
1438 | return child; | 1423 | return child; |
1439 | } | 1424 | } |
1425 | EXPORT_SYMBOL_GPL(device_find_child); | ||
1440 | 1426 | ||
1441 | int __init devices_init(void) | 1427 | int __init devices_init(void) |
1442 | { | 1428 | { |
@@ -1464,21 +1450,6 @@ int __init devices_init(void) | |||
1464 | return -ENOMEM; | 1450 | return -ENOMEM; |
1465 | } | 1451 | } |
1466 | 1452 | ||
1467 | EXPORT_SYMBOL_GPL(device_for_each_child); | ||
1468 | EXPORT_SYMBOL_GPL(device_find_child); | ||
1469 | |||
1470 | EXPORT_SYMBOL_GPL(device_initialize); | ||
1471 | EXPORT_SYMBOL_GPL(device_add); | ||
1472 | EXPORT_SYMBOL_GPL(device_register); | ||
1473 | |||
1474 | EXPORT_SYMBOL_GPL(device_del); | ||
1475 | EXPORT_SYMBOL_GPL(device_unregister); | ||
1476 | EXPORT_SYMBOL_GPL(get_device); | ||
1477 | EXPORT_SYMBOL_GPL(put_device); | ||
1478 | |||
1479 | EXPORT_SYMBOL_GPL(device_create_file); | ||
1480 | EXPORT_SYMBOL_GPL(device_remove_file); | ||
1481 | |||
1482 | static DEFINE_MUTEX(device_hotplug_lock); | 1453 | static DEFINE_MUTEX(device_hotplug_lock); |
1483 | 1454 | ||
1484 | void lock_device_hotplug(void) | 1455 | void lock_device_hotplug(void) |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4c358bc44c72..6bfaaca6955e 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -43,11 +43,14 @@ static int __ref cpu_subsys_online(struct device *dev) | |||
43 | struct cpu *cpu = container_of(dev, struct cpu, dev); | 43 | struct cpu *cpu = container_of(dev, struct cpu, dev); |
44 | int cpuid = dev->id; | 44 | int cpuid = dev->id; |
45 | int from_nid, to_nid; | 45 | int from_nid, to_nid; |
46 | int ret; | 46 | int ret = -ENODEV; |
47 | 47 | ||
48 | cpu_hotplug_driver_lock(); | 48 | cpu_hotplug_driver_lock(); |
49 | 49 | ||
50 | from_nid = cpu_to_node(cpuid); | 50 | from_nid = cpu_to_node(cpuid); |
51 | if (from_nid == NUMA_NO_NODE) | ||
52 | goto out; | ||
53 | |||
51 | ret = cpu_up(cpuid); | 54 | ret = cpu_up(cpuid); |
52 | /* | 55 | /* |
53 | * When hot adding memory to memoryless node and enabling a cpu | 56 | * When hot adding memory to memoryless node and enabling a cpu |
@@ -57,6 +60,7 @@ static int __ref cpu_subsys_online(struct device *dev) | |||
57 | if (from_nid != to_nid) | 60 | if (from_nid != to_nid) |
58 | change_cpu_under_node(cpu, from_nid, to_nid); | 61 | change_cpu_under_node(cpu, from_nid, to_nid); |
59 | 62 | ||
63 | out: | ||
60 | cpu_hotplug_driver_unlock(); | 64 | cpu_hotplug_driver_unlock(); |
61 | return ret; | 65 | return ret; |
62 | } | 66 | } |
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 0ca54421ce97..6c9cdaa9200d 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
@@ -134,7 +134,7 @@ void __init dma_contiguous_reserve(phys_addr_t limit) | |||
134 | 134 | ||
135 | static DEFINE_MUTEX(cma_mutex); | 135 | static DEFINE_MUTEX(cma_mutex); |
136 | 136 | ||
137 | static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) | 137 | static int __init cma_activate_area(unsigned long base_pfn, unsigned long count) |
138 | { | 138 | { |
139 | unsigned long pfn = base_pfn; | 139 | unsigned long pfn = base_pfn; |
140 | unsigned i = count >> pageblock_order; | 140 | unsigned i = count >> pageblock_order; |
@@ -156,7 +156,7 @@ static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static __init struct cma *cma_create_area(unsigned long base_pfn, | 159 | static struct cma * __init cma_create_area(unsigned long base_pfn, |
160 | unsigned long count) | 160 | unsigned long count) |
161 | { | 161 | { |
162 | int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); | 162 | int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 974e301a1ef0..9e29943e56ca 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/sysfs.h> | ||
18 | #include "base.h" | 19 | #include "base.h" |
19 | 20 | ||
20 | static struct device *next_device(struct klist_iter *i) | 21 | static struct device *next_device(struct klist_iter *i) |
@@ -123,34 +124,16 @@ void driver_remove_file(struct device_driver *drv, | |||
123 | } | 124 | } |
124 | EXPORT_SYMBOL_GPL(driver_remove_file); | 125 | EXPORT_SYMBOL_GPL(driver_remove_file); |
125 | 126 | ||
126 | static int driver_add_groups(struct device_driver *drv, | 127 | int driver_add_groups(struct device_driver *drv, |
127 | const struct attribute_group **groups) | 128 | const struct attribute_group **groups) |
128 | { | 129 | { |
129 | int error = 0; | 130 | return sysfs_create_groups(&drv->p->kobj, groups); |
130 | int i; | ||
131 | |||
132 | if (groups) { | ||
133 | for (i = 0; groups[i]; i++) { | ||
134 | error = sysfs_create_group(&drv->p->kobj, groups[i]); | ||
135 | if (error) { | ||
136 | while (--i >= 0) | ||
137 | sysfs_remove_group(&drv->p->kobj, | ||
138 | groups[i]); | ||
139 | break; | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | return error; | ||
144 | } | 131 | } |
145 | 132 | ||
146 | static void driver_remove_groups(struct device_driver *drv, | 133 | void driver_remove_groups(struct device_driver *drv, |
147 | const struct attribute_group **groups) | 134 | const struct attribute_group **groups) |
148 | { | 135 | { |
149 | int i; | 136 | sysfs_remove_groups(&drv->p->kobj, groups); |
150 | |||
151 | if (groups) | ||
152 | for (i = 0; groups[i]; i++) | ||
153 | sysfs_remove_group(&drv->p->kobj, groups[i]); | ||
154 | } | 137 | } |
155 | 138 | ||
156 | /** | 139 | /** |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index a439602ea919..10a4467c63f1 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -486,9 +486,8 @@ static struct notifier_block fw_shutdown_nb = { | |||
486 | .notifier_call = fw_shutdown_notify, | 486 | .notifier_call = fw_shutdown_notify, |
487 | }; | 487 | }; |
488 | 488 | ||
489 | static ssize_t firmware_timeout_show(struct class *class, | 489 | static ssize_t timeout_show(struct class *class, struct class_attribute *attr, |
490 | struct class_attribute *attr, | 490 | char *buf) |
491 | char *buf) | ||
492 | { | 491 | { |
493 | return sprintf(buf, "%d\n", loading_timeout); | 492 | return sprintf(buf, "%d\n", loading_timeout); |
494 | } | 493 | } |
@@ -506,9 +505,8 @@ static ssize_t firmware_timeout_show(struct class *class, | |||
506 | * | 505 | * |
507 | * Note: zero means 'wait forever'. | 506 | * Note: zero means 'wait forever'. |
508 | **/ | 507 | **/ |
509 | static ssize_t firmware_timeout_store(struct class *class, | 508 | static ssize_t timeout_store(struct class *class, struct class_attribute *attr, |
510 | struct class_attribute *attr, | 509 | const char *buf, size_t count) |
511 | const char *buf, size_t count) | ||
512 | { | 510 | { |
513 | loading_timeout = simple_strtol(buf, NULL, 10); | 511 | loading_timeout = simple_strtol(buf, NULL, 10); |
514 | if (loading_timeout < 0) | 512 | if (loading_timeout < 0) |
@@ -518,8 +516,7 @@ static ssize_t firmware_timeout_store(struct class *class, | |||
518 | } | 516 | } |
519 | 517 | ||
520 | static struct class_attribute firmware_class_attrs[] = { | 518 | static struct class_attribute firmware_class_attrs[] = { |
521 | __ATTR(timeout, S_IWUSR | S_IRUGO, | 519 | __ATTR_RW(timeout), |
522 | firmware_timeout_show, firmware_timeout_store), | ||
523 | __ATTR_NULL | 520 | __ATTR_NULL |
524 | }; | 521 | }; |
525 | 522 | ||
@@ -868,8 +865,15 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
868 | goto err_del_dev; | 865 | goto err_del_dev; |
869 | } | 866 | } |
870 | 867 | ||
868 | mutex_lock(&fw_lock); | ||
869 | list_add(&buf->pending_list, &pending_fw_head); | ||
870 | mutex_unlock(&fw_lock); | ||
871 | |||
871 | retval = device_create_file(f_dev, &dev_attr_loading); | 872 | retval = device_create_file(f_dev, &dev_attr_loading); |
872 | if (retval) { | 873 | if (retval) { |
874 | mutex_lock(&fw_lock); | ||
875 | list_del_init(&buf->pending_list); | ||
876 | mutex_unlock(&fw_lock); | ||
873 | dev_err(f_dev, "%s: device_create_file failed\n", __func__); | 877 | dev_err(f_dev, "%s: device_create_file failed\n", __func__); |
874 | goto err_del_bin_attr; | 878 | goto err_del_bin_attr; |
875 | } | 879 | } |
@@ -884,10 +888,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
884 | kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); | 888 | kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); |
885 | } | 889 | } |
886 | 890 | ||
887 | mutex_lock(&fw_lock); | ||
888 | list_add(&buf->pending_list, &pending_fw_head); | ||
889 | mutex_unlock(&fw_lock); | ||
890 | |||
891 | wait_for_completion(&buf->completion); | 891 | wait_for_completion(&buf->completion); |
892 | 892 | ||
893 | cancel_delayed_work_sync(&fw_priv->timeout_work); | 893 | cancel_delayed_work_sync(&fw_priv->timeout_work); |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index ec386ee9cb22..1c617623c8ae 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/memory.h> | 18 | #include <linux/memory.h> |
19 | #include <linux/kobject.h> | ||
20 | #include <linux/memory_hotplug.h> | 19 | #include <linux/memory_hotplug.h> |
21 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
22 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
@@ -30,6 +29,8 @@ static DEFINE_MUTEX(mem_sysfs_mutex); | |||
30 | 29 | ||
31 | #define MEMORY_CLASS_NAME "memory" | 30 | #define MEMORY_CLASS_NAME "memory" |
32 | 31 | ||
32 | #define to_memory_block(dev) container_of(dev, struct memory_block, dev) | ||
33 | |||
33 | static int sections_per_block; | 34 | static int sections_per_block; |
34 | 35 | ||
35 | static inline int base_memory_block_id(int section_nr) | 36 | static inline int base_memory_block_id(int section_nr) |
@@ -77,7 +78,7 @@ EXPORT_SYMBOL(unregister_memory_isolate_notifier); | |||
77 | 78 | ||
78 | static void memory_block_release(struct device *dev) | 79 | static void memory_block_release(struct device *dev) |
79 | { | 80 | { |
80 | struct memory_block *mem = container_of(dev, struct memory_block, dev); | 81 | struct memory_block *mem = to_memory_block(dev); |
81 | 82 | ||
82 | kfree(mem); | 83 | kfree(mem); |
83 | } | 84 | } |
@@ -110,8 +111,7 @@ static unsigned long get_memory_block_size(void) | |||
110 | static ssize_t show_mem_start_phys_index(struct device *dev, | 111 | static ssize_t show_mem_start_phys_index(struct device *dev, |
111 | struct device_attribute *attr, char *buf) | 112 | struct device_attribute *attr, char *buf) |
112 | { | 113 | { |
113 | struct memory_block *mem = | 114 | struct memory_block *mem = to_memory_block(dev); |
114 | container_of(dev, struct memory_block, dev); | ||
115 | unsigned long phys_index; | 115 | unsigned long phys_index; |
116 | 116 | ||
117 | phys_index = mem->start_section_nr / sections_per_block; | 117 | phys_index = mem->start_section_nr / sections_per_block; |
@@ -121,8 +121,7 @@ static ssize_t show_mem_start_phys_index(struct device *dev, | |||
121 | static ssize_t show_mem_end_phys_index(struct device *dev, | 121 | static ssize_t show_mem_end_phys_index(struct device *dev, |
122 | struct device_attribute *attr, char *buf) | 122 | struct device_attribute *attr, char *buf) |
123 | { | 123 | { |
124 | struct memory_block *mem = | 124 | struct memory_block *mem = to_memory_block(dev); |
125 | container_of(dev, struct memory_block, dev); | ||
126 | unsigned long phys_index; | 125 | unsigned long phys_index; |
127 | 126 | ||
128 | phys_index = mem->end_section_nr / sections_per_block; | 127 | phys_index = mem->end_section_nr / sections_per_block; |
@@ -137,8 +136,7 @@ static ssize_t show_mem_removable(struct device *dev, | |||
137 | { | 136 | { |
138 | unsigned long i, pfn; | 137 | unsigned long i, pfn; |
139 | int ret = 1; | 138 | int ret = 1; |
140 | struct memory_block *mem = | 139 | struct memory_block *mem = to_memory_block(dev); |
141 | container_of(dev, struct memory_block, dev); | ||
142 | 140 | ||
143 | for (i = 0; i < sections_per_block; i++) { | 141 | for (i = 0; i < sections_per_block; i++) { |
144 | if (!present_section_nr(mem->start_section_nr + i)) | 142 | if (!present_section_nr(mem->start_section_nr + i)) |
@@ -156,8 +154,7 @@ static ssize_t show_mem_removable(struct device *dev, | |||
156 | static ssize_t show_mem_state(struct device *dev, | 154 | static ssize_t show_mem_state(struct device *dev, |
157 | struct device_attribute *attr, char *buf) | 155 | struct device_attribute *attr, char *buf) |
158 | { | 156 | { |
159 | struct memory_block *mem = | 157 | struct memory_block *mem = to_memory_block(dev); |
160 | container_of(dev, struct memory_block, dev); | ||
161 | ssize_t len = 0; | 158 | ssize_t len = 0; |
162 | 159 | ||
163 | /* | 160 | /* |
@@ -263,9 +260,8 @@ memory_block_action(unsigned long phys_index, unsigned long action, int online_t | |||
263 | return ret; | 260 | return ret; |
264 | } | 261 | } |
265 | 262 | ||
266 | static int __memory_block_change_state(struct memory_block *mem, | 263 | static int memory_block_change_state(struct memory_block *mem, |
267 | unsigned long to_state, unsigned long from_state_req, | 264 | unsigned long to_state, unsigned long from_state_req) |
268 | int online_type) | ||
269 | { | 265 | { |
270 | int ret = 0; | 266 | int ret = 0; |
271 | 267 | ||
@@ -275,105 +271,89 @@ static int __memory_block_change_state(struct memory_block *mem, | |||
275 | if (to_state == MEM_OFFLINE) | 271 | if (to_state == MEM_OFFLINE) |
276 | mem->state = MEM_GOING_OFFLINE; | 272 | mem->state = MEM_GOING_OFFLINE; |
277 | 273 | ||
278 | ret = memory_block_action(mem->start_section_nr, to_state, online_type); | 274 | ret = memory_block_action(mem->start_section_nr, to_state, |
275 | mem->online_type); | ||
276 | |||
279 | mem->state = ret ? from_state_req : to_state; | 277 | mem->state = ret ? from_state_req : to_state; |
278 | |||
280 | return ret; | 279 | return ret; |
281 | } | 280 | } |
282 | 281 | ||
282 | /* The device lock serializes operations on memory_subsys_[online|offline] */ | ||
283 | static int memory_subsys_online(struct device *dev) | 283 | static int memory_subsys_online(struct device *dev) |
284 | { | 284 | { |
285 | struct memory_block *mem = container_of(dev, struct memory_block, dev); | 285 | struct memory_block *mem = to_memory_block(dev); |
286 | int ret; | 286 | int ret; |
287 | 287 | ||
288 | mutex_lock(&mem->state_mutex); | 288 | if (mem->state == MEM_ONLINE) |
289 | 289 | return 0; | |
290 | ret = mem->state == MEM_ONLINE ? 0 : | ||
291 | __memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE, | ||
292 | ONLINE_KEEP); | ||
293 | 290 | ||
294 | mutex_unlock(&mem->state_mutex); | 291 | /* |
295 | return ret; | 292 | * If we are called from store_mem_state(), online_type will be |
296 | } | 293 | * set >= 0 Otherwise we were called from the device online |
297 | 294 | * attribute and need to set the online_type. | |
298 | static int memory_subsys_offline(struct device *dev) | 295 | */ |
299 | { | 296 | if (mem->online_type < 0) |
300 | struct memory_block *mem = container_of(dev, struct memory_block, dev); | 297 | mem->online_type = ONLINE_KEEP; |
301 | int ret; | ||
302 | 298 | ||
303 | mutex_lock(&mem->state_mutex); | 299 | ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); |
304 | 300 | ||
305 | ret = mem->state == MEM_OFFLINE ? 0 : | 301 | /* clear online_type */ |
306 | __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1); | 302 | mem->online_type = -1; |
307 | 303 | ||
308 | mutex_unlock(&mem->state_mutex); | ||
309 | return ret; | 304 | return ret; |
310 | } | 305 | } |
311 | 306 | ||
312 | static int __memory_block_change_state_uevent(struct memory_block *mem, | 307 | static int memory_subsys_offline(struct device *dev) |
313 | unsigned long to_state, unsigned long from_state_req, | ||
314 | int online_type) | ||
315 | { | ||
316 | int ret = __memory_block_change_state(mem, to_state, from_state_req, | ||
317 | online_type); | ||
318 | if (!ret) { | ||
319 | switch (mem->state) { | ||
320 | case MEM_OFFLINE: | ||
321 | kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE); | ||
322 | break; | ||
323 | case MEM_ONLINE: | ||
324 | kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE); | ||
325 | break; | ||
326 | default: | ||
327 | break; | ||
328 | } | ||
329 | } | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | static int memory_block_change_state(struct memory_block *mem, | ||
334 | unsigned long to_state, unsigned long from_state_req, | ||
335 | int online_type) | ||
336 | { | 308 | { |
337 | int ret; | 309 | struct memory_block *mem = to_memory_block(dev); |
338 | 310 | ||
339 | mutex_lock(&mem->state_mutex); | 311 | if (mem->state == MEM_OFFLINE) |
340 | ret = __memory_block_change_state_uevent(mem, to_state, from_state_req, | 312 | return 0; |
341 | online_type); | ||
342 | mutex_unlock(&mem->state_mutex); | ||
343 | 313 | ||
344 | return ret; | 314 | return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); |
345 | } | 315 | } |
316 | |||
346 | static ssize_t | 317 | static ssize_t |
347 | store_mem_state(struct device *dev, | 318 | store_mem_state(struct device *dev, |
348 | struct device_attribute *attr, const char *buf, size_t count) | 319 | struct device_attribute *attr, const char *buf, size_t count) |
349 | { | 320 | { |
350 | struct memory_block *mem; | 321 | struct memory_block *mem = to_memory_block(dev); |
351 | bool offline; | 322 | int ret, online_type; |
352 | int ret = -EINVAL; | ||
353 | |||
354 | mem = container_of(dev, struct memory_block, dev); | ||
355 | 323 | ||
356 | lock_device_hotplug(); | 324 | lock_device_hotplug(); |
357 | 325 | ||
358 | if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) { | 326 | if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) |
359 | offline = false; | 327 | online_type = ONLINE_KERNEL; |
360 | ret = memory_block_change_state(mem, MEM_ONLINE, | 328 | else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) |
361 | MEM_OFFLINE, ONLINE_KERNEL); | 329 | online_type = ONLINE_MOVABLE; |
362 | } else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) { | 330 | else if (!strncmp(buf, "online", min_t(int, count, 6))) |
363 | offline = false; | 331 | online_type = ONLINE_KEEP; |
364 | ret = memory_block_change_state(mem, MEM_ONLINE, | 332 | else if (!strncmp(buf, "offline", min_t(int, count, 7))) |
365 | MEM_OFFLINE, ONLINE_MOVABLE); | 333 | online_type = -1; |
366 | } else if (!strncmp(buf, "online", min_t(int, count, 6))) { | 334 | else |
367 | offline = false; | 335 | return -EINVAL; |
368 | ret = memory_block_change_state(mem, MEM_ONLINE, | 336 | |
369 | MEM_OFFLINE, ONLINE_KEEP); | 337 | switch (online_type) { |
370 | } else if(!strncmp(buf, "offline", min_t(int, count, 7))) { | 338 | case ONLINE_KERNEL: |
371 | offline = true; | 339 | case ONLINE_MOVABLE: |
372 | ret = memory_block_change_state(mem, MEM_OFFLINE, | 340 | case ONLINE_KEEP: |
373 | MEM_ONLINE, -1); | 341 | /* |
342 | * mem->online_type is not protected so there can be a | ||
343 | * race here. However, when racing online, the first | ||
344 | * will succeed and the second will just return as the | ||
345 | * block will already be online. The online type | ||
346 | * could be either one, but that is expected. | ||
347 | */ | ||
348 | mem->online_type = online_type; | ||
349 | ret = device_online(&mem->dev); | ||
350 | break; | ||
351 | case -1: | ||
352 | ret = device_offline(&mem->dev); | ||
353 | break; | ||
354 | default: | ||
355 | ret = -EINVAL; /* should never happen */ | ||
374 | } | 356 | } |
375 | if (!ret) | ||
376 | dev->offline = offline; | ||
377 | 357 | ||
378 | unlock_device_hotplug(); | 358 | unlock_device_hotplug(); |
379 | 359 | ||
@@ -394,8 +374,7 @@ store_mem_state(struct device *dev, | |||
394 | static ssize_t show_phys_device(struct device *dev, | 374 | static ssize_t show_phys_device(struct device *dev, |
395 | struct device_attribute *attr, char *buf) | 375 | struct device_attribute *attr, char *buf) |
396 | { | 376 | { |
397 | struct memory_block *mem = | 377 | struct memory_block *mem = to_memory_block(dev); |
398 | container_of(dev, struct memory_block, dev); | ||
399 | return sprintf(buf, "%d\n", mem->phys_device); | 378 | return sprintf(buf, "%d\n", mem->phys_device); |
400 | } | 379 | } |
401 | 380 | ||
@@ -471,7 +450,7 @@ store_soft_offline_page(struct device *dev, | |||
471 | u64 pfn; | 450 | u64 pfn; |
472 | if (!capable(CAP_SYS_ADMIN)) | 451 | if (!capable(CAP_SYS_ADMIN)) |
473 | return -EPERM; | 452 | return -EPERM; |
474 | if (strict_strtoull(buf, 0, &pfn) < 0) | 453 | if (kstrtoull(buf, 0, &pfn) < 0) |
475 | return -EINVAL; | 454 | return -EINVAL; |
476 | pfn >>= PAGE_SHIFT; | 455 | pfn >>= PAGE_SHIFT; |
477 | if (!pfn_valid(pfn)) | 456 | if (!pfn_valid(pfn)) |
@@ -490,7 +469,7 @@ store_hard_offline_page(struct device *dev, | |||
490 | u64 pfn; | 469 | u64 pfn; |
491 | if (!capable(CAP_SYS_ADMIN)) | 470 | if (!capable(CAP_SYS_ADMIN)) |
492 | return -EPERM; | 471 | return -EPERM; |
493 | if (strict_strtoull(buf, 0, &pfn) < 0) | 472 | if (kstrtoull(buf, 0, &pfn) < 0) |
494 | return -EINVAL; | 473 | return -EINVAL; |
495 | pfn >>= PAGE_SHIFT; | 474 | pfn >>= PAGE_SHIFT; |
496 | ret = memory_failure(pfn, 0, 0); | 475 | ret = memory_failure(pfn, 0, 0); |
@@ -527,7 +506,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section, | |||
527 | put_device(&hint->dev); | 506 | put_device(&hint->dev); |
528 | if (!dev) | 507 | if (!dev) |
529 | return NULL; | 508 | return NULL; |
530 | return container_of(dev, struct memory_block, dev); | 509 | return to_memory_block(dev); |
531 | } | 510 | } |
532 | 511 | ||
533 | /* | 512 | /* |
@@ -567,16 +546,13 @@ static const struct attribute_group *memory_memblk_attr_groups[] = { | |||
567 | static | 546 | static |
568 | int register_memory(struct memory_block *memory) | 547 | int register_memory(struct memory_block *memory) |
569 | { | 548 | { |
570 | int error; | ||
571 | |||
572 | memory->dev.bus = &memory_subsys; | 549 | memory->dev.bus = &memory_subsys; |
573 | memory->dev.id = memory->start_section_nr / sections_per_block; | 550 | memory->dev.id = memory->start_section_nr / sections_per_block; |
574 | memory->dev.release = memory_block_release; | 551 | memory->dev.release = memory_block_release; |
575 | memory->dev.groups = memory_memblk_attr_groups; | 552 | memory->dev.groups = memory_memblk_attr_groups; |
576 | memory->dev.offline = memory->state == MEM_OFFLINE; | 553 | memory->dev.offline = memory->state == MEM_OFFLINE; |
577 | 554 | ||
578 | error = device_register(&memory->dev); | 555 | return device_register(&memory->dev); |
579 | return error; | ||
580 | } | 556 | } |
581 | 557 | ||
582 | static int init_memory_block(struct memory_block **memory, | 558 | static int init_memory_block(struct memory_block **memory, |
@@ -597,7 +573,6 @@ static int init_memory_block(struct memory_block **memory, | |||
597 | mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; | 573 | mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; |
598 | mem->state = state; | 574 | mem->state = state; |
599 | mem->section_count++; | 575 | mem->section_count++; |
600 | mutex_init(&mem->state_mutex); | ||
601 | start_pfn = section_nr_to_pfn(mem->start_section_nr); | 576 | start_pfn = section_nr_to_pfn(mem->start_section_nr); |
602 | mem->phys_device = arch_get_memory_phys_device(start_pfn); | 577 | mem->phys_device = arch_get_memory_phys_device(start_pfn); |
603 | 578 | ||
@@ -607,55 +582,57 @@ static int init_memory_block(struct memory_block **memory, | |||
607 | return ret; | 582 | return ret; |
608 | } | 583 | } |
609 | 584 | ||
610 | static int add_memory_section(int nid, struct mem_section *section, | 585 | static int add_memory_block(int base_section_nr) |
611 | struct memory_block **mem_p, | ||
612 | unsigned long state, enum mem_add_context context) | ||
613 | { | 586 | { |
614 | struct memory_block *mem = NULL; | 587 | struct memory_block *mem; |
615 | int scn_nr = __section_nr(section); | 588 | int i, ret, section_count = 0, section_nr; |
616 | int ret = 0; | ||
617 | |||
618 | mutex_lock(&mem_sysfs_mutex); | ||
619 | |||
620 | if (context == BOOT) { | ||
621 | /* same memory block ? */ | ||
622 | if (mem_p && *mem_p) | ||
623 | if (scn_nr >= (*mem_p)->start_section_nr && | ||
624 | scn_nr <= (*mem_p)->end_section_nr) { | ||
625 | mem = *mem_p; | ||
626 | kobject_get(&mem->dev.kobj); | ||
627 | } | ||
628 | } else | ||
629 | mem = find_memory_block(section); | ||
630 | |||
631 | if (mem) { | ||
632 | mem->section_count++; | ||
633 | kobject_put(&mem->dev.kobj); | ||
634 | } else { | ||
635 | ret = init_memory_block(&mem, section, state); | ||
636 | /* store memory_block pointer for next loop */ | ||
637 | if (!ret && context == BOOT) | ||
638 | if (mem_p) | ||
639 | *mem_p = mem; | ||
640 | } | ||
641 | 589 | ||
642 | if (!ret) { | 590 | for (i = base_section_nr; |
643 | if (context == HOTPLUG && | 591 | (i < base_section_nr + sections_per_block) && i < NR_MEM_SECTIONS; |
644 | mem->section_count == sections_per_block) | 592 | i++) { |
645 | ret = register_mem_sect_under_node(mem, nid); | 593 | if (!present_section_nr(i)) |
594 | continue; | ||
595 | if (section_count == 0) | ||
596 | section_nr = i; | ||
597 | section_count++; | ||
646 | } | 598 | } |
647 | 599 | ||
648 | mutex_unlock(&mem_sysfs_mutex); | 600 | if (section_count == 0) |
649 | return ret; | 601 | return 0; |
602 | ret = init_memory_block(&mem, __nr_to_section(section_nr), MEM_ONLINE); | ||
603 | if (ret) | ||
604 | return ret; | ||
605 | mem->section_count = section_count; | ||
606 | return 0; | ||
650 | } | 607 | } |
651 | 608 | ||
609 | |||
652 | /* | 610 | /* |
653 | * need an interface for the VM to add new memory regions, | 611 | * need an interface for the VM to add new memory regions, |
654 | * but without onlining it. | 612 | * but without onlining it. |
655 | */ | 613 | */ |
656 | int register_new_memory(int nid, struct mem_section *section) | 614 | int register_new_memory(int nid, struct mem_section *section) |
657 | { | 615 | { |
658 | return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG); | 616 | int ret = 0; |
617 | struct memory_block *mem; | ||
618 | |||
619 | mutex_lock(&mem_sysfs_mutex); | ||
620 | |||
621 | mem = find_memory_block(section); | ||
622 | if (mem) { | ||
623 | mem->section_count++; | ||
624 | put_device(&mem->dev); | ||
625 | } else { | ||
626 | ret = init_memory_block(&mem, section, MEM_OFFLINE); | ||
627 | if (ret) | ||
628 | goto out; | ||
629 | } | ||
630 | |||
631 | if (mem->section_count == sections_per_block) | ||
632 | ret = register_mem_sect_under_node(mem, nid); | ||
633 | out: | ||
634 | mutex_unlock(&mem_sysfs_mutex); | ||
635 | return ret; | ||
659 | } | 636 | } |
660 | 637 | ||
661 | #ifdef CONFIG_MEMORY_HOTREMOVE | 638 | #ifdef CONFIG_MEMORY_HOTREMOVE |
@@ -665,7 +642,7 @@ unregister_memory(struct memory_block *memory) | |||
665 | BUG_ON(memory->dev.bus != &memory_subsys); | 642 | BUG_ON(memory->dev.bus != &memory_subsys); |
666 | 643 | ||
667 | /* drop the ref. we got in remove_memory_block() */ | 644 | /* drop the ref. we got in remove_memory_block() */ |
668 | kobject_put(&memory->dev.kobj); | 645 | put_device(&memory->dev); |
669 | device_unregister(&memory->dev); | 646 | device_unregister(&memory->dev); |
670 | } | 647 | } |
671 | 648 | ||
@@ -682,7 +659,7 @@ static int remove_memory_block(unsigned long node_id, | |||
682 | if (mem->section_count == 0) | 659 | if (mem->section_count == 0) |
683 | unregister_memory(mem); | 660 | unregister_memory(mem); |
684 | else | 661 | else |
685 | kobject_put(&mem->dev.kobj); | 662 | put_device(&mem->dev); |
686 | 663 | ||
687 | mutex_unlock(&mem_sysfs_mutex); | 664 | mutex_unlock(&mem_sysfs_mutex); |
688 | return 0; | 665 | return 0; |
@@ -735,7 +712,6 @@ int __init memory_dev_init(void) | |||
735 | int ret; | 712 | int ret; |
736 | int err; | 713 | int err; |
737 | unsigned long block_sz; | 714 | unsigned long block_sz; |
738 | struct memory_block *mem = NULL; | ||
739 | 715 | ||
740 | ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); | 716 | ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); |
741 | if (ret) | 717 | if (ret) |
@@ -748,17 +724,13 @@ int __init memory_dev_init(void) | |||
748 | * Create entries for memory sections that were found | 724 | * Create entries for memory sections that were found |
749 | * during boot and have been initialized | 725 | * during boot and have been initialized |
750 | */ | 726 | */ |
751 | for (i = 0; i < NR_MEM_SECTIONS; i++) { | 727 | mutex_lock(&mem_sysfs_mutex); |
752 | if (!present_section_nr(i)) | 728 | for (i = 0; i < NR_MEM_SECTIONS; i += sections_per_block) { |
753 | continue; | 729 | err = add_memory_block(i); |
754 | /* don't need to reuse memory_block if only one per block */ | ||
755 | err = add_memory_section(0, __nr_to_section(i), | ||
756 | (sections_per_block == 1) ? NULL : &mem, | ||
757 | MEM_ONLINE, | ||
758 | BOOT); | ||
759 | if (!ret) | 730 | if (!ret) |
760 | ret = err; | 731 | ret = err; |
761 | } | 732 | } |
733 | mutex_unlock(&mem_sysfs_mutex); | ||
762 | 734 | ||
763 | out: | 735 | out: |
764 | if (ret) | 736 | if (ret) |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3c3197a8de41..4f8bef3eb5a8 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -672,11 +672,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
672 | 672 | ||
673 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 673 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
674 | } | 674 | } |
675 | static DEVICE_ATTR_RO(modalias); | ||
675 | 676 | ||
676 | static struct device_attribute platform_dev_attrs[] = { | 677 | static struct attribute *platform_dev_attrs[] = { |
677 | __ATTR_RO(modalias), | 678 | &dev_attr_modalias.attr, |
678 | __ATTR_NULL, | 679 | NULL, |
679 | }; | 680 | }; |
681 | ATTRIBUTE_GROUPS(platform_dev); | ||
680 | 682 | ||
681 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | 683 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) |
682 | { | 684 | { |
@@ -893,7 +895,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = { | |||
893 | 895 | ||
894 | struct bus_type platform_bus_type = { | 896 | struct bus_type platform_bus_type = { |
895 | .name = "platform", | 897 | .name = "platform", |
896 | .dev_attrs = platform_dev_attrs, | 898 | .dev_groups = platform_dev_groups, |
897 | .match = platform_match, | 899 | .match = platform_match, |
898 | .uevent = platform_uevent, | 900 | .uevent = platform_uevent, |
899 | .pm = &platform_dev_pm_ops, | 901 | .pm = &platform_dev_pm_ops, |
@@ -1054,7 +1056,7 @@ void __init early_platform_driver_register_all(char *class_str) | |||
1054 | * @epdrv: early platform driver structure | 1056 | * @epdrv: early platform driver structure |
1055 | * @id: id to match against | 1057 | * @id: id to match against |
1056 | */ | 1058 | */ |
1057 | static __init struct platform_device * | 1059 | static struct platform_device * __init |
1058 | early_platform_match(struct early_platform_driver *epdrv, int id) | 1060 | early_platform_match(struct early_platform_driver *epdrv, int id) |
1059 | { | 1061 | { |
1060 | struct platform_device *pd; | 1062 | struct platform_device *pd; |
@@ -1072,7 +1074,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id) | |||
1072 | * @epdrv: early platform driver structure | 1074 | * @epdrv: early platform driver structure |
1073 | * @id: return true if id or above exists | 1075 | * @id: return true if id or above exists |
1074 | */ | 1076 | */ |
1075 | static __init int early_platform_left(struct early_platform_driver *epdrv, | 1077 | static int __init early_platform_left(struct early_platform_driver *epdrv, |
1076 | int id) | 1078 | int id) |
1077 | { | 1079 | { |
1078 | struct platform_device *pd; | 1080 | struct platform_device *pd; |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index a53ebd265701..03e089ade5ce 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -206,7 +206,7 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev, | |||
206 | if (!dev->power.use_autosuspend) | 206 | if (!dev->power.use_autosuspend) |
207 | return -EIO; | 207 | return -EIO; |
208 | 208 | ||
209 | if (strict_strtol(buf, 10, &delay) != 0 || delay != (int) delay) | 209 | if (kstrtol(buf, 10, &delay) != 0 || delay != (int) delay) |
210 | return -EINVAL; | 210 | return -EINVAL; |
211 | 211 | ||
212 | device_lock(dev); | 212 | device_lock(dev); |
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 6c2652a8ad50..de11ecaf3833 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
@@ -281,7 +281,7 @@ static ssize_t regmap_map_write_file(struct file *file, | |||
281 | reg = simple_strtoul(start, &start, 16); | 281 | reg = simple_strtoul(start, &start, 16); |
282 | while (*start == ' ') | 282 | while (*start == ' ') |
283 | start++; | 283 | start++; |
284 | if (strict_strtoul(start, 16, &value)) | 284 | if (kstrtoul(start, 16, &value)) |
285 | return -EINVAL; | 285 | return -EINVAL; |
286 | 286 | ||
287 | /* Userspace has been fiddling around behind the kernel's back */ | 287 | /* Userspace has been fiddling around behind the kernel's back */ |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 2f5919ed91ab..94ffee378f10 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -62,25 +62,6 @@ static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf) | |||
62 | } | 62 | } |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | #ifdef arch_provides_topology_pointers | ||
66 | #define define_siblings_show_map(name) \ | ||
67 | static ssize_t show_##name(struct device *dev, \ | ||
68 | struct device_attribute *attr, char *buf) \ | ||
69 | { \ | ||
70 | unsigned int cpu = dev->id; \ | ||
71 | return show_cpumap(0, topology_##name(cpu), buf); \ | ||
72 | } | ||
73 | |||
74 | #define define_siblings_show_list(name) \ | ||
75 | static ssize_t show_##name##_list(struct device *dev, \ | ||
76 | struct device_attribute *attr, \ | ||
77 | char *buf) \ | ||
78 | { \ | ||
79 | unsigned int cpu = dev->id; \ | ||
80 | return show_cpumap(1, topology_##name(cpu), buf); \ | ||
81 | } | ||
82 | |||
83 | #else | ||
84 | #define define_siblings_show_map(name) \ | 65 | #define define_siblings_show_map(name) \ |
85 | static ssize_t show_##name(struct device *dev, \ | 66 | static ssize_t show_##name(struct device *dev, \ |
86 | struct device_attribute *attr, char *buf) \ | 67 | struct device_attribute *attr, char *buf) \ |
@@ -95,7 +76,6 @@ static ssize_t show_##name##_list(struct device *dev, \ | |||
95 | { \ | 76 | { \ |
96 | return show_cpumap(1, topology_##name(dev->id), buf); \ | 77 | return show_cpumap(1, topology_##name(dev->id), buf); \ |
97 | } | 78 | } |
98 | #endif | ||
99 | 79 | ||
100 | #define define_siblings_show_func(name) \ | 80 | #define define_siblings_show_func(name) \ |
101 | define_siblings_show_map(name); define_siblings_show_list(name) | 81 | define_siblings_show_map(name); define_siblings_show_list(name) |