diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-devices-system-cpu | 12 | ||||
-rw-r--r-- | block/genhd.c | 3 | ||||
-rw-r--r-- | drivers/base/bus.c | 8 | ||||
-rw-r--r-- | drivers/base/core.c | 26 | ||||
-rw-r--r-- | drivers/base/cpu.c | 14 | ||||
-rw-r--r-- | drivers/base/dd.c | 6 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 28 | ||||
-rw-r--r-- | drivers/base/platform.c | 24 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 3 | ||||
-rw-r--r-- | fs/sysfs/dir.c | 41 | ||||
-rw-r--r-- | include/linux/device.h | 19 | ||||
-rw-r--r-- | include/linux/platform_device.h | 25 | ||||
-rw-r--r-- | kernel/rtmutex-tester.c | 4 |
13 files changed, 135 insertions, 78 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 9c978dcae07d..2447698aed41 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
@@ -173,3 +173,15 @@ Description: Processor frequency boosting control | |||
173 | Boosting allows the CPU and the firmware to run at a frequency | 173 | Boosting allows the CPU and the firmware to run at a frequency |
174 | beyound it's nominal limit. | 174 | beyound it's nominal limit. |
175 | More details can be found in Documentation/cpu-freq/boost.txt | 175 | More details can be found in Documentation/cpu-freq/boost.txt |
176 | |||
177 | |||
178 | What: /sys/devices/system/cpu/cpu#/crash_notes | ||
179 | /sys/devices/system/cpu/cpu#/crash_notes_size | ||
180 | Date: April 2013 | ||
181 | Contact: kexec@lists.infradead.org | ||
182 | Description: address and size of the percpu note. | ||
183 | |||
184 | crash_notes: the physical address of the memory that holds the | ||
185 | note of cpu#. | ||
186 | |||
187 | crash_notes_size: size of the note of cpu#. | ||
diff --git a/block/genhd.c b/block/genhd.c index 3c001fba80c7..20625eed5511 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -1111,7 +1111,8 @@ struct class block_class = { | |||
1111 | .name = "block", | 1111 | .name = "block", |
1112 | }; | 1112 | }; |
1113 | 1113 | ||
1114 | static char *block_devnode(struct device *dev, umode_t *mode) | 1114 | static char *block_devnode(struct device *dev, umode_t *mode, |
1115 | kuid_t *uid, kgid_t *gid) | ||
1115 | { | 1116 | { |
1116 | struct gendisk *disk = dev_to_disk(dev); | 1117 | struct gendisk *disk = dev_to_disk(dev); |
1117 | 1118 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 519865b53f76..8a00dec574d6 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -898,18 +898,18 @@ static ssize_t bus_uevent_store(struct bus_type *bus, | |||
898 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | 898 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); |
899 | 899 | ||
900 | /** | 900 | /** |
901 | * __bus_register - register a driver-core subsystem | 901 | * bus_register - register a driver-core subsystem |
902 | * @bus: bus to register | 902 | * @bus: bus to register |
903 | * @key: lockdep class key | ||
904 | * | 903 | * |
905 | * Once we have that, we register the bus with the kobject | 904 | * Once we have that, we register the bus with the kobject |
906 | * infrastructure, then register the children subsystems it has: | 905 | * infrastructure, then register the children subsystems it has: |
907 | * the devices and drivers that belong to the subsystem. | 906 | * the devices and drivers that belong to the subsystem. |
908 | */ | 907 | */ |
909 | int __bus_register(struct bus_type *bus, struct lock_class_key *key) | 908 | int bus_register(struct bus_type *bus) |
910 | { | 909 | { |
911 | int retval; | 910 | int retval; |
912 | struct subsys_private *priv; | 911 | struct subsys_private *priv; |
912 | struct lock_class_key *key = &bus->lock_key; | ||
913 | 913 | ||
914 | priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); | 914 | priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); |
915 | if (!priv) | 915 | if (!priv) |
@@ -981,7 +981,7 @@ out: | |||
981 | bus->p = NULL; | 981 | bus->p = NULL; |
982 | return retval; | 982 | return retval; |
983 | } | 983 | } |
984 | EXPORT_SYMBOL_GPL(__bus_register); | 984 | EXPORT_SYMBOL_GPL(bus_register); |
985 | 985 | ||
986 | /** | 986 | /** |
987 | * bus_unregister - remove a bus from the system | 987 | * bus_unregister - remove a bus from the system |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 56536f4b0f6b..f88d9e259a32 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -283,15 +283,21 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
283 | const char *tmp; | 283 | const char *tmp; |
284 | const char *name; | 284 | const char *name; |
285 | umode_t mode = 0; | 285 | umode_t mode = 0; |
286 | kuid_t uid = GLOBAL_ROOT_UID; | ||
287 | kgid_t gid = GLOBAL_ROOT_GID; | ||
286 | 288 | ||
287 | add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); | 289 | add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); |
288 | add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); | 290 | add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); |
289 | name = device_get_devnode(dev, &mode, &tmp); | 291 | name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); |
290 | if (name) { | 292 | if (name) { |
291 | add_uevent_var(env, "DEVNAME=%s", name); | 293 | add_uevent_var(env, "DEVNAME=%s", name); |
292 | kfree(tmp); | ||
293 | if (mode) | 294 | if (mode) |
294 | add_uevent_var(env, "DEVMODE=%#o", mode & 0777); | 295 | add_uevent_var(env, "DEVMODE=%#o", mode & 0777); |
296 | if (!uid_eq(uid, GLOBAL_ROOT_UID)) | ||
297 | add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); | ||
298 | if (!gid_eq(gid, GLOBAL_ROOT_GID)) | ||
299 | add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); | ||
300 | kfree(tmp); | ||
295 | } | 301 | } |
296 | } | 302 | } |
297 | 303 | ||
@@ -563,8 +569,15 @@ int device_create_file(struct device *dev, | |||
563 | const struct device_attribute *attr) | 569 | const struct device_attribute *attr) |
564 | { | 570 | { |
565 | int error = 0; | 571 | int error = 0; |
566 | if (dev) | 572 | |
573 | if (dev) { | ||
574 | WARN(((attr->attr.mode & S_IWUGO) && !attr->store), | ||
575 | "Write permission without 'store'\n"); | ||
576 | WARN(((attr->attr.mode & S_IRUGO) && !attr->show), | ||
577 | "Read permission without 'show'\n"); | ||
567 | error = sysfs_create_file(&dev->kobj, &attr->attr); | 578 | error = sysfs_create_file(&dev->kobj, &attr->attr); |
579 | } | ||
580 | |||
568 | return error; | 581 | return error; |
569 | } | 582 | } |
570 | 583 | ||
@@ -1274,6 +1287,8 @@ static struct device *next_device(struct klist_iter *i) | |||
1274 | * device_get_devnode - path of device node file | 1287 | * device_get_devnode - path of device node file |
1275 | * @dev: device | 1288 | * @dev: device |
1276 | * @mode: returned file access mode | 1289 | * @mode: returned file access mode |
1290 | * @uid: returned file owner | ||
1291 | * @gid: returned file group | ||
1277 | * @tmp: possibly allocated string | 1292 | * @tmp: possibly allocated string |
1278 | * | 1293 | * |
1279 | * Return the relative path of a possible device node. | 1294 | * Return the relative path of a possible device node. |
@@ -1282,7 +1297,8 @@ static struct device *next_device(struct klist_iter *i) | |||
1282 | * freed by the caller. | 1297 | * freed by the caller. |
1283 | */ | 1298 | */ |
1284 | const char *device_get_devnode(struct device *dev, | 1299 | const char *device_get_devnode(struct device *dev, |
1285 | umode_t *mode, const char **tmp) | 1300 | umode_t *mode, kuid_t *uid, kgid_t *gid, |
1301 | const char **tmp) | ||
1286 | { | 1302 | { |
1287 | char *s; | 1303 | char *s; |
1288 | 1304 | ||
@@ -1290,7 +1306,7 @@ const char *device_get_devnode(struct device *dev, | |||
1290 | 1306 | ||
1291 | /* the device type may provide a specific name */ | 1307 | /* the device type may provide a specific name */ |
1292 | if (dev->type && dev->type->devnode) | 1308 | if (dev->type && dev->type->devnode) |
1293 | *tmp = dev->type->devnode(dev, mode); | 1309 | *tmp = dev->type->devnode(dev, mode, uid, gid); |
1294 | if (*tmp) | 1310 | if (*tmp) |
1295 | return *tmp; | 1311 | return *tmp; |
1296 | 1312 | ||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index fb10728f6372..d8c7f3ee6e19 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -132,6 +132,17 @@ static ssize_t show_crash_notes(struct device *dev, struct device_attribute *att | |||
132 | return rc; | 132 | return rc; |
133 | } | 133 | } |
134 | static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL); | 134 | static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL); |
135 | |||
136 | static ssize_t show_crash_notes_size(struct device *dev, | ||
137 | struct device_attribute *attr, | ||
138 | char *buf) | ||
139 | { | ||
140 | ssize_t rc; | ||
141 | |||
142 | rc = sprintf(buf, "%zu\n", sizeof(note_buf_t)); | ||
143 | return rc; | ||
144 | } | ||
145 | static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL); | ||
135 | #endif | 146 | #endif |
136 | 147 | ||
137 | /* | 148 | /* |
@@ -259,6 +270,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) | |||
259 | #ifdef CONFIG_KEXEC | 270 | #ifdef CONFIG_KEXEC |
260 | if (!error) | 271 | if (!error) |
261 | error = device_create_file(&cpu->dev, &dev_attr_crash_notes); | 272 | error = device_create_file(&cpu->dev, &dev_attr_crash_notes); |
273 | if (!error) | ||
274 | error = device_create_file(&cpu->dev, | ||
275 | &dev_attr_crash_notes_size); | ||
262 | #endif | 276 | #endif |
263 | return error; | 277 | return error; |
264 | } | 278 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index bb5645ea0282..35fa36898916 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -380,7 +380,7 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
380 | 380 | ||
381 | pm_runtime_barrier(dev); | 381 | pm_runtime_barrier(dev); |
382 | ret = really_probe(dev, drv); | 382 | ret = really_probe(dev, drv); |
383 | pm_runtime_idle(dev); | 383 | pm_request_idle(dev); |
384 | 384 | ||
385 | return ret; | 385 | return ret; |
386 | } | 386 | } |
@@ -428,7 +428,7 @@ int device_attach(struct device *dev) | |||
428 | } | 428 | } |
429 | } else { | 429 | } else { |
430 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 430 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); |
431 | pm_runtime_idle(dev); | 431 | pm_request_idle(dev); |
432 | } | 432 | } |
433 | out_unlock: | 433 | out_unlock: |
434 | device_unlock(dev); | 434 | device_unlock(dev); |
@@ -499,7 +499,7 @@ static void __device_release_driver(struct device *dev) | |||
499 | BUS_NOTIFY_UNBIND_DRIVER, | 499 | BUS_NOTIFY_UNBIND_DRIVER, |
500 | dev); | 500 | dev); |
501 | 501 | ||
502 | pm_runtime_put_sync(dev); | 502 | pm_runtime_put(dev); |
503 | 503 | ||
504 | if (dev->bus && dev->bus->remove) | 504 | if (dev->bus && dev->bus->remove) |
505 | dev->bus->remove(dev); | 505 | dev->bus->remove(dev); |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 01fc5b07f951..7413d065906b 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include "base.h" | ||
27 | 28 | ||
28 | static struct task_struct *thread; | 29 | static struct task_struct *thread; |
29 | 30 | ||
@@ -41,6 +42,8 @@ static struct req { | |||
41 | int err; | 42 | int err; |
42 | const char *name; | 43 | const char *name; |
43 | umode_t mode; /* 0 => delete */ | 44 | umode_t mode; /* 0 => delete */ |
45 | kuid_t uid; | ||
46 | kgid_t gid; | ||
44 | struct device *dev; | 47 | struct device *dev; |
45 | } *requests; | 48 | } *requests; |
46 | 49 | ||
@@ -85,7 +88,9 @@ int devtmpfs_create_node(struct device *dev) | |||
85 | return 0; | 88 | return 0; |
86 | 89 | ||
87 | req.mode = 0; | 90 | req.mode = 0; |
88 | req.name = device_get_devnode(dev, &req.mode, &tmp); | 91 | req.uid = GLOBAL_ROOT_UID; |
92 | req.gid = GLOBAL_ROOT_GID; | ||
93 | req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp); | ||
89 | if (!req.name) | 94 | if (!req.name) |
90 | return -ENOMEM; | 95 | return -ENOMEM; |
91 | 96 | ||
@@ -121,7 +126,7 @@ int devtmpfs_delete_node(struct device *dev) | |||
121 | if (!thread) | 126 | if (!thread) |
122 | return 0; | 127 | return 0; |
123 | 128 | ||
124 | req.name = device_get_devnode(dev, NULL, &tmp); | 129 | req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp); |
125 | if (!req.name) | 130 | if (!req.name) |
126 | return -ENOMEM; | 131 | return -ENOMEM; |
127 | 132 | ||
@@ -187,7 +192,8 @@ static int create_path(const char *nodepath) | |||
187 | return err; | 192 | return err; |
188 | } | 193 | } |
189 | 194 | ||
190 | static int handle_create(const char *nodename, umode_t mode, struct device *dev) | 195 | static int handle_create(const char *nodename, umode_t mode, kuid_t uid, |
196 | kgid_t gid, struct device *dev) | ||
191 | { | 197 | { |
192 | struct dentry *dentry; | 198 | struct dentry *dentry; |
193 | struct path path; | 199 | struct path path; |
@@ -201,14 +207,14 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev) | |||
201 | if (IS_ERR(dentry)) | 207 | if (IS_ERR(dentry)) |
202 | return PTR_ERR(dentry); | 208 | return PTR_ERR(dentry); |
203 | 209 | ||
204 | err = vfs_mknod(path.dentry->d_inode, | 210 | err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt); |
205 | dentry, mode, dev->devt); | ||
206 | if (!err) { | 211 | if (!err) { |
207 | struct iattr newattrs; | 212 | struct iattr newattrs; |
208 | 213 | ||
209 | /* fixup possibly umasked mode */ | ||
210 | newattrs.ia_mode = mode; | 214 | newattrs.ia_mode = mode; |
211 | newattrs.ia_valid = ATTR_MODE; | 215 | newattrs.ia_uid = uid; |
216 | newattrs.ia_gid = gid; | ||
217 | newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID; | ||
212 | mutex_lock(&dentry->d_inode->i_mutex); | 218 | mutex_lock(&dentry->d_inode->i_mutex); |
213 | notify_change(dentry, &newattrs); | 219 | notify_change(dentry, &newattrs); |
214 | mutex_unlock(&dentry->d_inode->i_mutex); | 220 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -358,10 +364,11 @@ int devtmpfs_mount(const char *mntdir) | |||
358 | 364 | ||
359 | static DECLARE_COMPLETION(setup_done); | 365 | static DECLARE_COMPLETION(setup_done); |
360 | 366 | ||
361 | static int handle(const char *name, umode_t mode, struct device *dev) | 367 | static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, |
368 | struct device *dev) | ||
362 | { | 369 | { |
363 | if (mode) | 370 | if (mode) |
364 | return handle_create(name, mode, dev); | 371 | return handle_create(name, mode, uid, gid, dev); |
365 | else | 372 | else |
366 | return handle_remove(name, dev); | 373 | return handle_remove(name, dev); |
367 | } | 374 | } |
@@ -387,7 +394,8 @@ static int devtmpfsd(void *p) | |||
387 | spin_unlock(&req_lock); | 394 | spin_unlock(&req_lock); |
388 | while (req) { | 395 | while (req) { |
389 | struct req *next = req->next; | 396 | struct req *next = req->next; |
390 | req->err = handle(req->name, req->mode, req->dev); | 397 | req->err = handle(req->name, req->mode, |
398 | req->uid, req->gid, req->dev); | ||
391 | complete(&req->done); | 399 | complete(&req->done); |
392 | req = next; | 400 | req = next; |
393 | } | 401 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c0b8df38402b..9eda84246ffd 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -46,8 +46,8 @@ EXPORT_SYMBOL_GPL(platform_bus); | |||
46 | * manipulate any relevant information in the pdev_archdata they can do: | 46 | * manipulate any relevant information in the pdev_archdata they can do: |
47 | * | 47 | * |
48 | * platform_device_alloc() | 48 | * platform_device_alloc() |
49 | * ... manipulate ... | 49 | * ... manipulate ... |
50 | * platform_device_add() | 50 | * platform_device_add() |
51 | * | 51 | * |
52 | * And if they don't care they can just call platform_device_register() and | 52 | * And if they don't care they can just call platform_device_register() and |
53 | * everything will just work out. | 53 | * everything will just work out. |
@@ -326,9 +326,7 @@ int platform_device_add(struct platform_device *pdev) | |||
326 | } | 326 | } |
327 | 327 | ||
328 | if (p && insert_resource(p, r)) { | 328 | if (p && insert_resource(p, r)) { |
329 | printk(KERN_ERR | 329 | dev_err(&pdev->dev, "failed to claim resource %d\n", i); |
330 | "%s: failed to claim resource %d\n", | ||
331 | dev_name(&pdev->dev), i); | ||
332 | ret = -EBUSY; | 330 | ret = -EBUSY; |
333 | goto failed; | 331 | goto failed; |
334 | } | 332 | } |
@@ -555,7 +553,8 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister); | |||
555 | /** | 553 | /** |
556 | * platform_driver_probe - register driver for non-hotpluggable device | 554 | * platform_driver_probe - register driver for non-hotpluggable device |
557 | * @drv: platform driver structure | 555 | * @drv: platform driver structure |
558 | * @probe: the driver probe routine, probably from an __init section | 556 | * @probe: the driver probe routine, probably from an __init section, |
557 | * must not return -EPROBE_DEFER. | ||
559 | * | 558 | * |
560 | * Use this instead of platform_driver_register() when you know the device | 559 | * Use this instead of platform_driver_register() when you know the device |
561 | * is not hotpluggable and has already been registered, and you want to | 560 | * is not hotpluggable and has already been registered, and you want to |
@@ -566,6 +565,9 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister); | |||
566 | * into system-on-chip processors, where the controller devices have been | 565 | * into system-on-chip processors, where the controller devices have been |
567 | * configured as part of board setup. | 566 | * configured as part of board setup. |
568 | * | 567 | * |
568 | * This is incompatible with deferred probing so probe() must not | ||
569 | * return -EPROBE_DEFER. | ||
570 | * | ||
569 | * Returns zero if the driver registered and bound to a device, else returns | 571 | * Returns zero if the driver registered and bound to a device, else returns |
570 | * a negative error code and with the driver not registered. | 572 | * a negative error code and with the driver not registered. |
571 | */ | 573 | */ |
@@ -682,7 +684,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
682 | int rc; | 684 | int rc; |
683 | 685 | ||
684 | /* Some devices have extra OF data and an OF-style MODALIAS */ | 686 | /* Some devices have extra OF data and an OF-style MODALIAS */ |
685 | rc = of_device_uevent_modalias(dev,env); | 687 | rc = of_device_uevent_modalias(dev, env); |
686 | if (rc != -ENODEV) | 688 | if (rc != -ENODEV) |
687 | return rc; | 689 | return rc; |
688 | 690 | ||
@@ -1126,8 +1128,8 @@ static int __init early_platform_driver_probe_id(char *class_str, | |||
1126 | 1128 | ||
1127 | switch (match_id) { | 1129 | switch (match_id) { |
1128 | case EARLY_PLATFORM_ID_ERROR: | 1130 | case EARLY_PLATFORM_ID_ERROR: |
1129 | pr_warning("%s: unable to parse %s parameter\n", | 1131 | pr_warn("%s: unable to parse %s parameter\n", |
1130 | class_str, epdrv->pdrv->driver.name); | 1132 | class_str, epdrv->pdrv->driver.name); |
1131 | /* fall-through */ | 1133 | /* fall-through */ |
1132 | case EARLY_PLATFORM_ID_UNSET: | 1134 | case EARLY_PLATFORM_ID_UNSET: |
1133 | match = NULL; | 1135 | match = NULL; |
@@ -1158,8 +1160,8 @@ static int __init early_platform_driver_probe_id(char *class_str, | |||
1158 | } | 1160 | } |
1159 | 1161 | ||
1160 | if (epdrv->pdrv->probe(match)) | 1162 | if (epdrv->pdrv->probe(match)) |
1161 | pr_warning("%s: unable to probe %s early.\n", | 1163 | pr_warn("%s: unable to probe %s early.\n", |
1162 | class_str, match->name); | 1164 | class_str, match->name); |
1163 | else | 1165 | else |
1164 | n++; | 1166 | n++; |
1165 | } | 1167 | } |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index f81b92572735..e092b414dc50 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -317,7 +317,8 @@ static const struct dev_pm_ops usb_device_pm_ops = { | |||
317 | #endif /* CONFIG_PM */ | 317 | #endif /* CONFIG_PM */ |
318 | 318 | ||
319 | 319 | ||
320 | static char *usb_devnode(struct device *dev, umode_t *mode) | 320 | static char *usb_devnode(struct device *dev, |
321 | umode_t *mode, kuid_t *uid, kgid_t *gid) | ||
321 | { | 322 | { |
322 | struct usb_device *usb_dev; | 323 | struct usb_device *usb_dev; |
323 | 324 | ||
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index e14512678c9b..e8e0e71b29d5 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -165,21 +165,8 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) | |||
165 | if (unlikely(!sd)) | 165 | if (unlikely(!sd)) |
166 | return NULL; | 166 | return NULL; |
167 | 167 | ||
168 | while (1) { | 168 | if (!atomic_inc_unless_negative(&sd->s_active)) |
169 | int v, t; | 169 | return NULL; |
170 | |||
171 | v = atomic_read(&sd->s_active); | ||
172 | if (unlikely(v < 0)) | ||
173 | return NULL; | ||
174 | |||
175 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); | ||
176 | if (likely(t == v)) | ||
177 | break; | ||
178 | if (t < 0) | ||
179 | return NULL; | ||
180 | |||
181 | cpu_relax(); | ||
182 | } | ||
183 | 170 | ||
184 | if (likely(!ignore_lockdep(sd))) | 171 | if (likely(!ignore_lockdep(sd))) |
185 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | 172 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); |
@@ -281,6 +268,10 @@ void release_sysfs_dirent(struct sysfs_dirent * sd) | |||
281 | */ | 268 | */ |
282 | parent_sd = sd->s_parent; | 269 | parent_sd = sd->s_parent; |
283 | 270 | ||
271 | WARN(!(sd->s_flags & SYSFS_FLAG_REMOVED), | ||
272 | "sysfs: free using entry: %s/%s\n", | ||
273 | parent_sd ? parent_sd->s_name : "", sd->s_name); | ||
274 | |||
284 | if (sysfs_type(sd) == SYSFS_KOBJ_LINK) | 275 | if (sysfs_type(sd) == SYSFS_KOBJ_LINK) |
285 | sysfs_put(sd->s_symlink.target_sd); | 276 | sysfs_put(sd->s_symlink.target_sd); |
286 | if (sysfs_type(sd) & SYSFS_COPY_NAME) | 277 | if (sysfs_type(sd) & SYSFS_COPY_NAME) |
@@ -399,7 +390,7 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | |||
399 | 390 | ||
400 | sd->s_name = name; | 391 | sd->s_name = name; |
401 | sd->s_mode = mode; | 392 | sd->s_mode = mode; |
402 | sd->s_flags = type; | 393 | sd->s_flags = type | SYSFS_FLAG_REMOVED; |
403 | 394 | ||
404 | return sd; | 395 | return sd; |
405 | 396 | ||
@@ -479,6 +470,9 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
479 | ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; | 470 | ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; |
480 | } | 471 | } |
481 | 472 | ||
473 | /* Mark the entry added into directory tree */ | ||
474 | sd->s_flags &= ~SYSFS_FLAG_REMOVED; | ||
475 | |||
482 | return 0; | 476 | return 0; |
483 | } | 477 | } |
484 | 478 | ||
@@ -1012,6 +1006,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1012 | enum kobj_ns_type type; | 1006 | enum kobj_ns_type type; |
1013 | const void *ns; | 1007 | const void *ns; |
1014 | ino_t ino; | 1008 | ino_t ino; |
1009 | loff_t off; | ||
1015 | 1010 | ||
1016 | type = sysfs_ns_type(parent_sd); | 1011 | type = sysfs_ns_type(parent_sd); |
1017 | ns = sysfs_info(dentry->d_sb)->ns[type]; | 1012 | ns = sysfs_info(dentry->d_sb)->ns[type]; |
@@ -1034,6 +1029,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1034 | return 0; | 1029 | return 0; |
1035 | } | 1030 | } |
1036 | mutex_lock(&sysfs_mutex); | 1031 | mutex_lock(&sysfs_mutex); |
1032 | off = filp->f_pos; | ||
1037 | for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); | 1033 | for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); |
1038 | pos; | 1034 | pos; |
1039 | pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { | 1035 | pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { |
@@ -1045,19 +1041,24 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1045 | len = strlen(name); | 1041 | len = strlen(name); |
1046 | ino = pos->s_ino; | 1042 | ino = pos->s_ino; |
1047 | type = dt_type(pos); | 1043 | type = dt_type(pos); |
1048 | filp->f_pos = pos->s_hash; | 1044 | off = filp->f_pos = pos->s_hash; |
1049 | filp->private_data = sysfs_get(pos); | 1045 | filp->private_data = sysfs_get(pos); |
1050 | 1046 | ||
1051 | mutex_unlock(&sysfs_mutex); | 1047 | mutex_unlock(&sysfs_mutex); |
1052 | ret = filldir(dirent, name, len, filp->f_pos, ino, type); | 1048 | ret = filldir(dirent, name, len, off, ino, type); |
1053 | mutex_lock(&sysfs_mutex); | 1049 | mutex_lock(&sysfs_mutex); |
1054 | if (ret < 0) | 1050 | if (ret < 0) |
1055 | break; | 1051 | break; |
1056 | } | 1052 | } |
1057 | mutex_unlock(&sysfs_mutex); | 1053 | mutex_unlock(&sysfs_mutex); |
1058 | if ((filp->f_pos > 1) && !pos) { /* EOF */ | 1054 | |
1059 | filp->f_pos = INT_MAX; | 1055 | /* don't reference last entry if its refcount is dropped */ |
1056 | if (!pos) { | ||
1060 | filp->private_data = NULL; | 1057 | filp->private_data = NULL; |
1058 | |||
1059 | /* EOF and not changed as 0 or 1 in read/write path */ | ||
1060 | if (off == filp->f_pos && off > 1) | ||
1061 | filp->f_pos = INT_MAX; | ||
1061 | } | 1062 | } |
1062 | return 0; | 1063 | return 0; |
1063 | } | 1064 | } |
diff --git a/include/linux/device.h b/include/linux/device.h index 9d6464ea99c6..88615ccaf23a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/atomic.h> | 26 | #include <linux/atomic.h> |
27 | #include <linux/ratelimit.h> | 27 | #include <linux/ratelimit.h> |
28 | #include <linux/uidgid.h> | ||
28 | #include <asm/device.h> | 29 | #include <asm/device.h> |
29 | 30 | ||
30 | struct device; | 31 | struct device; |
@@ -111,17 +112,11 @@ struct bus_type { | |||
111 | struct iommu_ops *iommu_ops; | 112 | struct iommu_ops *iommu_ops; |
112 | 113 | ||
113 | struct subsys_private *p; | 114 | struct subsys_private *p; |
115 | struct lock_class_key lock_key; | ||
114 | }; | 116 | }; |
115 | 117 | ||
116 | /* This is a #define to keep the compiler from merging different | 118 | extern int __must_check bus_register(struct bus_type *bus); |
117 | * instances of the __key variable */ | 119 | |
118 | #define bus_register(subsys) \ | ||
119 | ({ \ | ||
120 | static struct lock_class_key __key; \ | ||
121 | __bus_register(subsys, &__key); \ | ||
122 | }) | ||
123 | extern int __must_check __bus_register(struct bus_type *bus, | ||
124 | struct lock_class_key *key); | ||
125 | extern void bus_unregister(struct bus_type *bus); | 120 | extern void bus_unregister(struct bus_type *bus); |
126 | 121 | ||
127 | extern int __must_check bus_rescan_devices(struct bus_type *bus); | 122 | extern int __must_check bus_rescan_devices(struct bus_type *bus); |
@@ -471,7 +466,8 @@ struct device_type { | |||
471 | const char *name; | 466 | const char *name; |
472 | const struct attribute_group **groups; | 467 | const struct attribute_group **groups; |
473 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); | 468 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); |
474 | char *(*devnode)(struct device *dev, umode_t *mode); | 469 | char *(*devnode)(struct device *dev, umode_t *mode, |
470 | kuid_t *uid, kgid_t *gid); | ||
475 | void (*release)(struct device *dev); | 471 | void (*release)(struct device *dev); |
476 | 472 | ||
477 | const struct dev_pm_ops *pm; | 473 | const struct dev_pm_ops *pm; |
@@ -849,7 +845,8 @@ extern int device_rename(struct device *dev, const char *new_name); | |||
849 | extern int device_move(struct device *dev, struct device *new_parent, | 845 | extern int device_move(struct device *dev, struct device *new_parent, |
850 | enum dpm_order dpm_order); | 846 | enum dpm_order dpm_order); |
851 | extern const char *device_get_devnode(struct device *dev, | 847 | extern const char *device_get_devnode(struct device *dev, |
852 | umode_t *mode, const char **tmp); | 848 | umode_t *mode, kuid_t *uid, kgid_t *gid, |
849 | const char **tmp); | ||
853 | extern void *dev_get_drvdata(const struct device *dev); | 850 | extern void *dev_get_drvdata(const struct device *dev); |
854 | extern int dev_set_drvdata(struct device *dev, void *data); | 851 | extern int dev_set_drvdata(struct device *dev, void *data); |
855 | 852 | ||
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index c082c71f7225..9abf1db6aea6 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -20,12 +20,12 @@ | |||
20 | struct mfd_cell; | 20 | struct mfd_cell; |
21 | 21 | ||
22 | struct platform_device { | 22 | struct platform_device { |
23 | const char * name; | 23 | const char *name; |
24 | int id; | 24 | int id; |
25 | bool id_auto; | 25 | bool id_auto; |
26 | struct device dev; | 26 | struct device dev; |
27 | u32 num_resources; | 27 | u32 num_resources; |
28 | struct resource * resource; | 28 | struct resource *resource; |
29 | 29 | ||
30 | const struct platform_device_id *id_entry; | 30 | const struct platform_device_id *id_entry; |
31 | 31 | ||
@@ -47,9 +47,12 @@ extern struct bus_type platform_bus_type; | |||
47 | extern struct device platform_bus; | 47 | extern struct device platform_bus; |
48 | 48 | ||
49 | extern void arch_setup_pdev_archdata(struct platform_device *); | 49 | extern void arch_setup_pdev_archdata(struct platform_device *); |
50 | extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); | 50 | extern struct resource *platform_get_resource(struct platform_device *, |
51 | unsigned int, unsigned int); | ||
51 | extern int platform_get_irq(struct platform_device *, unsigned int); | 52 | extern int platform_get_irq(struct platform_device *, unsigned int); |
52 | extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); | 53 | extern struct resource *platform_get_resource_byname(struct platform_device *, |
54 | unsigned int, | ||
55 | const char *); | ||
53 | extern int platform_get_irq_byname(struct platform_device *, const char *); | 56 | extern int platform_get_irq_byname(struct platform_device *, const char *); |
54 | extern int platform_add_devices(struct platform_device **, int); | 57 | extern int platform_add_devices(struct platform_device **, int); |
55 | 58 | ||
@@ -161,7 +164,8 @@ extern struct platform_device *platform_device_alloc(const char *name, int id); | |||
161 | extern int platform_device_add_resources(struct platform_device *pdev, | 164 | extern int platform_device_add_resources(struct platform_device *pdev, |
162 | const struct resource *res, | 165 | const struct resource *res, |
163 | unsigned int num); | 166 | unsigned int num); |
164 | extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size); | 167 | extern int platform_device_add_data(struct platform_device *pdev, |
168 | const void *data, size_t size); | ||
165 | extern int platform_device_add(struct platform_device *pdev); | 169 | extern int platform_device_add(struct platform_device *pdev); |
166 | extern void platform_device_del(struct platform_device *pdev); | 170 | extern void platform_device_del(struct platform_device *pdev); |
167 | extern void platform_device_put(struct platform_device *pdev); | 171 | extern void platform_device_put(struct platform_device *pdev); |
@@ -190,7 +194,8 @@ static inline void *platform_get_drvdata(const struct platform_device *pdev) | |||
190 | return dev_get_drvdata(&pdev->dev); | 194 | return dev_get_drvdata(&pdev->dev); |
191 | } | 195 | } |
192 | 196 | ||
193 | static inline void platform_set_drvdata(struct platform_device *pdev, void *data) | 197 | static inline void platform_set_drvdata(struct platform_device *pdev, |
198 | void *data) | ||
194 | { | 199 | { |
195 | dev_set_drvdata(&pdev->dev, data); | 200 | dev_set_drvdata(&pdev->dev, data); |
196 | } | 201 | } |
@@ -222,10 +227,10 @@ static void __exit __platform_driver##_exit(void) \ | |||
222 | } \ | 227 | } \ |
223 | module_exit(__platform_driver##_exit); | 228 | module_exit(__platform_driver##_exit); |
224 | 229 | ||
225 | extern struct platform_device *platform_create_bundle(struct platform_driver *driver, | 230 | extern struct platform_device *platform_create_bundle( |
226 | int (*probe)(struct platform_device *), | 231 | struct platform_driver *driver, int (*probe)(struct platform_device *), |
227 | struct resource *res, unsigned int n_res, | 232 | struct resource *res, unsigned int n_res, |
228 | const void *data, size_t size); | 233 | const void *data, size_t size); |
229 | 234 | ||
230 | /* early platform driver interface */ | 235 | /* early platform driver interface */ |
231 | struct early_platform_driver { | 236 | struct early_platform_driver { |
diff --git a/kernel/rtmutex-tester.c b/kernel/rtmutex-tester.c index 7890b10084a7..55ad765c31f1 100644 --- a/kernel/rtmutex-tester.c +++ b/kernel/rtmutex-tester.c | |||
@@ -366,8 +366,8 @@ static ssize_t sysfs_test_status(struct device *dev, struct device_attribute *at | |||
366 | return curr - buf; | 366 | return curr - buf; |
367 | } | 367 | } |
368 | 368 | ||
369 | static DEVICE_ATTR(status, 0600, sysfs_test_status, NULL); | 369 | static DEVICE_ATTR(status, 0400, sysfs_test_status, NULL); |
370 | static DEVICE_ATTR(command, 0600, NULL, sysfs_test_command); | 370 | static DEVICE_ATTR(command, 0200, NULL, sysfs_test_command); |
371 | 371 | ||
372 | static struct bus_type rttest_subsys = { | 372 | static struct bus_type rttest_subsys = { |
373 | .name = "rttest", | 373 | .name = "rttest", |