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 |
12 files changed, 133 insertions, 76 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 { |
