diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/bus.c | 17 | ||||
-rw-r--r-- | drivers/base/core.c | 14 | ||||
-rw-r--r-- | drivers/base/cpu.c | 34 | ||||
-rw-r--r-- | drivers/base/dd.c | 2 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 100 | ||||
-rw-r--r-- | drivers/base/driver.c | 2 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 14 | ||||
-rw-r--r-- | drivers/base/platform.c | 35 | ||||
-rw-r--r-- | drivers/base/power/main.c | 1 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 37 |
10 files changed, 159 insertions, 97 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 973bf2ad4e0d..63c143e54a57 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -689,15 +689,19 @@ int bus_add_driver(struct device_driver *drv) | |||
689 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", | 689 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", |
690 | __func__, drv->name); | 690 | __func__, drv->name); |
691 | } | 691 | } |
692 | error = add_bind_files(drv); | 692 | |
693 | if (error) { | 693 | if (!drv->suppress_bind_attrs) { |
694 | /* Ditto */ | 694 | error = add_bind_files(drv); |
695 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | 695 | if (error) { |
696 | __func__, drv->name); | 696 | /* Ditto */ |
697 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | ||
698 | __func__, drv->name); | ||
699 | } | ||
697 | } | 700 | } |
698 | 701 | ||
699 | kobject_uevent(&priv->kobj, KOBJ_ADD); | 702 | kobject_uevent(&priv->kobj, KOBJ_ADD); |
700 | return 0; | 703 | return 0; |
704 | |||
701 | out_unregister: | 705 | out_unregister: |
702 | kfree(drv->p); | 706 | kfree(drv->p); |
703 | drv->p = NULL; | 707 | drv->p = NULL; |
@@ -720,7 +724,8 @@ void bus_remove_driver(struct device_driver *drv) | |||
720 | if (!drv->bus) | 724 | if (!drv->bus) |
721 | return; | 725 | return; |
722 | 726 | ||
723 | remove_bind_files(drv); | 727 | if (!drv->suppress_bind_attrs) |
728 | remove_bind_files(drv); | ||
724 | driver_remove_attrs(drv->bus, drv); | 729 | driver_remove_attrs(drv->bus, drv); |
725 | driver_remove_file(drv, &driver_attr_uevent); | 730 | driver_remove_file(drv, &driver_attr_uevent); |
726 | klist_remove(&drv->p->knode_bus); | 731 | klist_remove(&drv->p->knode_bus); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 6bee6af8d8e1..f1290cbd1350 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -56,7 +56,14 @@ static inline int device_is_not_partition(struct device *dev) | |||
56 | */ | 56 | */ |
57 | const char *dev_driver_string(const struct device *dev) | 57 | const char *dev_driver_string(const struct device *dev) |
58 | { | 58 | { |
59 | return dev->driver ? dev->driver->name : | 59 | struct device_driver *drv; |
60 | |||
61 | /* dev->driver can change to NULL underneath us because of unbinding, | ||
62 | * so be careful about accessing it. dev->bus and dev->class should | ||
63 | * never change once they are set, so they don't need special care. | ||
64 | */ | ||
65 | drv = ACCESS_ONCE(dev->driver); | ||
66 | return drv ? drv->name : | ||
60 | (dev->bus ? dev->bus->name : | 67 | (dev->bus ? dev->bus->name : |
61 | (dev->class ? dev->class->name : "")); | 68 | (dev->class ? dev->class->name : "")); |
62 | } | 69 | } |
@@ -987,6 +994,8 @@ done: | |||
987 | device_remove_class_symlinks(dev); | 994 | device_remove_class_symlinks(dev); |
988 | SymlinkError: | 995 | SymlinkError: |
989 | if (MAJOR(dev->devt)) | 996 | if (MAJOR(dev->devt)) |
997 | devtmpfs_delete_node(dev); | ||
998 | if (MAJOR(dev->devt)) | ||
990 | device_remove_sys_dev_entry(dev); | 999 | device_remove_sys_dev_entry(dev); |
991 | devtattrError: | 1000 | devtattrError: |
992 | if (MAJOR(dev->devt)) | 1001 | if (MAJOR(dev->devt)) |
@@ -1728,8 +1737,5 @@ void device_shutdown(void) | |||
1728 | dev->driver->shutdown(dev); | 1737 | dev->driver->shutdown(dev); |
1729 | } | 1738 | } |
1730 | } | 1739 | } |
1731 | kobject_put(sysfs_dev_char_kobj); | ||
1732 | kobject_put(sysfs_dev_block_kobj); | ||
1733 | kobject_put(dev_kobj); | ||
1734 | async_synchronize_full(); | 1740 | async_synchronize_full(); |
1735 | } | 1741 | } |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 69ee5b7517ec..958bd1540c30 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -35,6 +35,7 @@ static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribut | |||
35 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); | 35 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); |
36 | ssize_t ret; | 36 | ssize_t ret; |
37 | 37 | ||
38 | cpu_hotplug_driver_lock(); | ||
38 | switch (buf[0]) { | 39 | switch (buf[0]) { |
39 | case '0': | 40 | case '0': |
40 | ret = cpu_down(cpu->sysdev.id); | 41 | ret = cpu_down(cpu->sysdev.id); |
@@ -49,6 +50,7 @@ static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribut | |||
49 | default: | 50 | default: |
50 | ret = -EINVAL; | 51 | ret = -EINVAL; |
51 | } | 52 | } |
53 | cpu_hotplug_driver_unlock(); | ||
52 | 54 | ||
53 | if (ret >= 0) | 55 | if (ret >= 0) |
54 | ret = count; | 56 | ret = count; |
@@ -72,6 +74,38 @@ void unregister_cpu(struct cpu *cpu) | |||
72 | per_cpu(cpu_sys_devices, logical_cpu) = NULL; | 74 | per_cpu(cpu_sys_devices, logical_cpu) = NULL; |
73 | return; | 75 | return; |
74 | } | 76 | } |
77 | |||
78 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE | ||
79 | static ssize_t cpu_probe_store(struct class *class, const char *buf, | ||
80 | size_t count) | ||
81 | { | ||
82 | return arch_cpu_probe(buf, count); | ||
83 | } | ||
84 | |||
85 | static ssize_t cpu_release_store(struct class *class, const char *buf, | ||
86 | size_t count) | ||
87 | { | ||
88 | return arch_cpu_release(buf, count); | ||
89 | } | ||
90 | |||
91 | static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); | ||
92 | static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store); | ||
93 | |||
94 | int __init cpu_probe_release_init(void) | ||
95 | { | ||
96 | int rc; | ||
97 | |||
98 | rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, | ||
99 | &class_attr_probe.attr); | ||
100 | if (!rc) | ||
101 | rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, | ||
102 | &class_attr_release.attr); | ||
103 | |||
104 | return rc; | ||
105 | } | ||
106 | device_initcall(cpu_probe_release_init); | ||
107 | #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ | ||
108 | |||
75 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 109 | #else /* ... !CONFIG_HOTPLUG_CPU */ |
76 | static inline void register_cpu_control(struct cpu *cpu) | 110 | static inline void register_cpu_control(struct cpu *cpu) |
77 | { | 111 | { |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 979d159b5cd1..ee95c76bfd3d 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -188,7 +188,7 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe); | |||
188 | * @dev: device to try to bind to the driver | 188 | * @dev: device to try to bind to the driver |
189 | * | 189 | * |
190 | * This function returns -ENODEV if the device is not registered, | 190 | * This function returns -ENODEV if the device is not registered, |
191 | * 1 if the device is bound sucessfully and 0 otherwise. | 191 | * 1 if the device is bound successfully and 0 otherwise. |
192 | * | 192 | * |
193 | * This function must be called with @dev->sem held. When called for a | 193 | * This function must be called with @dev->sem held. When called for a |
194 | * USB interface, @dev->parent->sem must be held as well. | 194 | * USB interface, @dev->parent->sem must be held as well. |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index a1cb5afe6801..50375bb8e51d 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -32,6 +32,8 @@ static int dev_mount = 1; | |||
32 | static int dev_mount; | 32 | static int dev_mount; |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | static rwlock_t dirlock; | ||
36 | |||
35 | static int __init mount_param(char *str) | 37 | static int __init mount_param(char *str) |
36 | { | 38 | { |
37 | dev_mount = simple_strtoul(str, NULL, 0); | 39 | dev_mount = simple_strtoul(str, NULL, 0); |
@@ -74,47 +76,35 @@ static int dev_mkdir(const char *name, mode_t mode) | |||
74 | dentry = lookup_create(&nd, 1); | 76 | dentry = lookup_create(&nd, 1); |
75 | if (!IS_ERR(dentry)) { | 77 | if (!IS_ERR(dentry)) { |
76 | err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 78 | err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
79 | if (!err) | ||
80 | /* mark as kernel-created inode */ | ||
81 | dentry->d_inode->i_private = &dev_mnt; | ||
77 | dput(dentry); | 82 | dput(dentry); |
78 | } else { | 83 | } else { |
79 | err = PTR_ERR(dentry); | 84 | err = PTR_ERR(dentry); |
80 | } | 85 | } |
81 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
82 | 86 | ||
87 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
83 | path_put(&nd.path); | 88 | path_put(&nd.path); |
84 | return err; | 89 | return err; |
85 | } | 90 | } |
86 | 91 | ||
87 | static int create_path(const char *nodepath) | 92 | static int create_path(const char *nodepath) |
88 | { | 93 | { |
89 | char *path; | 94 | int err; |
90 | struct nameidata nd; | ||
91 | int err = 0; | ||
92 | |||
93 | path = kstrdup(nodepath, GFP_KERNEL); | ||
94 | if (!path) | ||
95 | return -ENOMEM; | ||
96 | |||
97 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, | ||
98 | path, LOOKUP_PARENT, &nd); | ||
99 | if (err == 0) { | ||
100 | struct dentry *dentry; | ||
101 | |||
102 | /* create directory right away */ | ||
103 | dentry = lookup_create(&nd, 1); | ||
104 | if (!IS_ERR(dentry)) { | ||
105 | err = vfs_mkdir(nd.path.dentry->d_inode, | ||
106 | dentry, 0755); | ||
107 | dput(dentry); | ||
108 | } | ||
109 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
110 | 95 | ||
111 | path_put(&nd.path); | 96 | read_lock(&dirlock); |
112 | } else if (err == -ENOENT) { | 97 | err = dev_mkdir(nodepath, 0755); |
98 | if (err == -ENOENT) { | ||
99 | char *path; | ||
113 | char *s; | 100 | char *s; |
114 | 101 | ||
115 | /* parent directories do not exist, create them */ | 102 | /* parent directories do not exist, create them */ |
103 | path = kstrdup(nodepath, GFP_KERNEL); | ||
104 | if (!path) | ||
105 | return -ENOMEM; | ||
116 | s = path; | 106 | s = path; |
117 | while (1) { | 107 | for (;;) { |
118 | s = strchr(s, '/'); | 108 | s = strchr(s, '/'); |
119 | if (!s) | 109 | if (!s) |
120 | break; | 110 | break; |
@@ -125,9 +115,9 @@ static int create_path(const char *nodepath) | |||
125 | s[0] = '/'; | 115 | s[0] = '/'; |
126 | s++; | 116 | s++; |
127 | } | 117 | } |
118 | kfree(path); | ||
128 | } | 119 | } |
129 | 120 | read_unlock(&dirlock); | |
130 | kfree(path); | ||
131 | return err; | 121 | return err; |
132 | } | 122 | } |
133 | 123 | ||
@@ -156,34 +146,40 @@ int devtmpfs_create_node(struct device *dev) | |||
156 | mode |= S_IFCHR; | 146 | mode |= S_IFCHR; |
157 | 147 | ||
158 | curr_cred = override_creds(&init_cred); | 148 | curr_cred = override_creds(&init_cred); |
149 | |||
159 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, | 150 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, |
160 | nodename, LOOKUP_PARENT, &nd); | 151 | nodename, LOOKUP_PARENT, &nd); |
161 | if (err == -ENOENT) { | 152 | if (err == -ENOENT) { |
162 | /* create missing parent directories */ | ||
163 | create_path(nodename); | 153 | create_path(nodename); |
164 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, | 154 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, |
165 | nodename, LOOKUP_PARENT, &nd); | 155 | nodename, LOOKUP_PARENT, &nd); |
166 | if (err) | ||
167 | goto out; | ||
168 | } | 156 | } |
157 | if (err) | ||
158 | goto out; | ||
169 | 159 | ||
170 | dentry = lookup_create(&nd, 0); | 160 | dentry = lookup_create(&nd, 0); |
171 | if (!IS_ERR(dentry)) { | 161 | if (!IS_ERR(dentry)) { |
172 | int umask; | ||
173 | |||
174 | umask = sys_umask(0000); | ||
175 | err = vfs_mknod(nd.path.dentry->d_inode, | 162 | err = vfs_mknod(nd.path.dentry->d_inode, |
176 | dentry, mode, dev->devt); | 163 | dentry, mode, dev->devt); |
177 | sys_umask(umask); | 164 | if (!err) { |
178 | /* mark as kernel created inode */ | 165 | struct iattr newattrs; |
179 | if (!err) | 166 | |
167 | /* fixup possibly umasked mode */ | ||
168 | newattrs.ia_mode = mode; | ||
169 | newattrs.ia_valid = ATTR_MODE; | ||
170 | mutex_lock(&dentry->d_inode->i_mutex); | ||
171 | notify_change(dentry, &newattrs); | ||
172 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
173 | |||
174 | /* mark as kernel-created inode */ | ||
180 | dentry->d_inode->i_private = &dev_mnt; | 175 | dentry->d_inode->i_private = &dev_mnt; |
176 | } | ||
181 | dput(dentry); | 177 | dput(dentry); |
182 | } else { | 178 | } else { |
183 | err = PTR_ERR(dentry); | 179 | err = PTR_ERR(dentry); |
184 | } | 180 | } |
185 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
186 | 181 | ||
182 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
187 | path_put(&nd.path); | 183 | path_put(&nd.path); |
188 | out: | 184 | out: |
189 | kfree(tmp); | 185 | kfree(tmp); |
@@ -205,16 +201,21 @@ static int dev_rmdir(const char *name) | |||
205 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 201 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
206 | dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); | 202 | dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); |
207 | if (!IS_ERR(dentry)) { | 203 | if (!IS_ERR(dentry)) { |
208 | if (dentry->d_inode) | 204 | if (dentry->d_inode) { |
209 | err = vfs_rmdir(nd.path.dentry->d_inode, dentry); | 205 | if (dentry->d_inode->i_private == &dev_mnt) |
210 | else | 206 | err = vfs_rmdir(nd.path.dentry->d_inode, |
207 | dentry); | ||
208 | else | ||
209 | err = -EPERM; | ||
210 | } else { | ||
211 | err = -ENOENT; | 211 | err = -ENOENT; |
212 | } | ||
212 | dput(dentry); | 213 | dput(dentry); |
213 | } else { | 214 | } else { |
214 | err = PTR_ERR(dentry); | 215 | err = PTR_ERR(dentry); |
215 | } | 216 | } |
216 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
217 | 217 | ||
218 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
218 | path_put(&nd.path); | 219 | path_put(&nd.path); |
219 | return err; | 220 | return err; |
220 | } | 221 | } |
@@ -228,7 +229,8 @@ static int delete_path(const char *nodepath) | |||
228 | if (!path) | 229 | if (!path) |
229 | return -ENOMEM; | 230 | return -ENOMEM; |
230 | 231 | ||
231 | while (1) { | 232 | write_lock(&dirlock); |
233 | for (;;) { | ||
232 | char *base; | 234 | char *base; |
233 | 235 | ||
234 | base = strrchr(path, '/'); | 236 | base = strrchr(path, '/'); |
@@ -239,6 +241,7 @@ static int delete_path(const char *nodepath) | |||
239 | if (err) | 241 | if (err) |
240 | break; | 242 | break; |
241 | } | 243 | } |
244 | write_unlock(&dirlock); | ||
242 | 245 | ||
243 | kfree(path); | 246 | kfree(path); |
244 | return err; | 247 | return err; |
@@ -322,9 +325,8 @@ out: | |||
322 | * If configured, or requested by the commandline, devtmpfs will be | 325 | * If configured, or requested by the commandline, devtmpfs will be |
323 | * auto-mounted after the kernel mounted the root filesystem. | 326 | * auto-mounted after the kernel mounted the root filesystem. |
324 | */ | 327 | */ |
325 | int devtmpfs_mount(const char *mountpoint) | 328 | int devtmpfs_mount(const char *mntdir) |
326 | { | 329 | { |
327 | struct path path; | ||
328 | int err; | 330 | int err; |
329 | 331 | ||
330 | if (!dev_mount) | 332 | if (!dev_mount) |
@@ -333,15 +335,11 @@ int devtmpfs_mount(const char *mountpoint) | |||
333 | if (!dev_mnt) | 335 | if (!dev_mnt) |
334 | return 0; | 336 | return 0; |
335 | 337 | ||
336 | err = kern_path(mountpoint, LOOKUP_FOLLOW, &path); | 338 | err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); |
337 | if (err) | ||
338 | return err; | ||
339 | err = do_add_mount(dev_mnt, &path, 0, NULL); | ||
340 | if (err) | 339 | if (err) |
341 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); | 340 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); |
342 | else | 341 | else |
343 | printk(KERN_INFO "devtmpfs: mounted\n"); | 342 | printk(KERN_INFO "devtmpfs: mounted\n"); |
344 | path_put(&path); | ||
345 | return err; | 343 | return err; |
346 | } | 344 | } |
347 | 345 | ||
@@ -354,6 +352,8 @@ int __init devtmpfs_init(void) | |||
354 | int err; | 352 | int err; |
355 | struct vfsmount *mnt; | 353 | struct vfsmount *mnt; |
356 | 354 | ||
355 | rwlock_init(&dirlock); | ||
356 | |||
357 | err = register_filesystem(&dev_fs_type); | 357 | err = register_filesystem(&dev_fs_type); |
358 | if (err) { | 358 | if (err) { |
359 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " | 359 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " |
@@ -361,7 +361,7 @@ int __init devtmpfs_init(void) | |||
361 | return err; | 361 | return err; |
362 | } | 362 | } |
363 | 363 | ||
364 | mnt = kern_mount(&dev_fs_type); | 364 | mnt = kern_mount_data(&dev_fs_type, "mode=0755"); |
365 | if (IS_ERR(mnt)) { | 365 | if (IS_ERR(mnt)) { |
366 | err = PTR_ERR(mnt); | 366 | err = PTR_ERR(mnt); |
367 | printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); | 367 | printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index ed2ebd3c287d..f367885a7646 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -236,7 +236,7 @@ int driver_register(struct device_driver *drv) | |||
236 | put_driver(other); | 236 | put_driver(other); |
237 | printk(KERN_ERR "Error: Driver '%s' is already registered, " | 237 | printk(KERN_ERR "Error: Driver '%s' is already registered, " |
238 | "aborting...\n", drv->name); | 238 | "aborting...\n", drv->name); |
239 | return -EEXIST; | 239 | return -EBUSY; |
240 | } | 240 | } |
241 | 241 | ||
242 | ret = bus_add_driver(drv); | 242 | ret = bus_add_driver(drv); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 7376367bcb80..a95024166b66 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -601,12 +601,9 @@ request_firmware_work_func(void *arg) | |||
601 | } | 601 | } |
602 | ret = _request_firmware(&fw, fw_work->name, fw_work->device, | 602 | ret = _request_firmware(&fw, fw_work->name, fw_work->device, |
603 | fw_work->uevent); | 603 | fw_work->uevent); |
604 | if (ret < 0) | 604 | |
605 | fw_work->cont(NULL, fw_work->context); | 605 | fw_work->cont(fw, fw_work->context); |
606 | else { | 606 | |
607 | fw_work->cont(fw, fw_work->context); | ||
608 | release_firmware(fw); | ||
609 | } | ||
610 | module_put(fw_work->module); | 607 | module_put(fw_work->module); |
611 | kfree(fw_work); | 608 | kfree(fw_work); |
612 | return ret; | 609 | return ret; |
@@ -619,6 +616,7 @@ request_firmware_work_func(void *arg) | |||
619 | * is non-zero else the firmware copy must be done manually. | 616 | * is non-zero else the firmware copy must be done manually. |
620 | * @name: name of firmware file | 617 | * @name: name of firmware file |
621 | * @device: device for which firmware is being loaded | 618 | * @device: device for which firmware is being loaded |
619 | * @gfp: allocation flags | ||
622 | * @context: will be passed over to @cont, and | 620 | * @context: will be passed over to @cont, and |
623 | * @fw may be %NULL if firmware request fails. | 621 | * @fw may be %NULL if firmware request fails. |
624 | * @cont: function will be called asynchronously when the firmware | 622 | * @cont: function will be called asynchronously when the firmware |
@@ -631,12 +629,12 @@ request_firmware_work_func(void *arg) | |||
631 | int | 629 | int |
632 | request_firmware_nowait( | 630 | request_firmware_nowait( |
633 | struct module *module, int uevent, | 631 | struct module *module, int uevent, |
634 | const char *name, struct device *device, void *context, | 632 | const char *name, struct device *device, gfp_t gfp, void *context, |
635 | void (*cont)(const struct firmware *fw, void *context)) | 633 | void (*cont)(const struct firmware *fw, void *context)) |
636 | { | 634 | { |
637 | struct task_struct *task; | 635 | struct task_struct *task; |
638 | struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), | 636 | struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), |
639 | GFP_ATOMIC); | 637 | gfp); |
640 | 638 | ||
641 | if (!fw_work) | 639 | if (!fw_work) |
642 | return -ENOMEM; | 640 | return -ENOMEM; |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index ed156a13aa40..9d2ee25deaf5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -521,11 +521,15 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
521 | { | 521 | { |
522 | int retval, code; | 522 | int retval, code; |
523 | 523 | ||
524 | /* make sure driver won't have bind/unbind attributes */ | ||
525 | drv->driver.suppress_bind_attrs = true; | ||
526 | |||
524 | /* temporary section violation during probe() */ | 527 | /* temporary section violation during probe() */ |
525 | drv->probe = probe; | 528 | drv->probe = probe; |
526 | retval = code = platform_driver_register(drv); | 529 | retval = code = platform_driver_register(drv); |
527 | 530 | ||
528 | /* Fixup that section violation, being paranoid about code scanning | 531 | /* |
532 | * Fixup that section violation, being paranoid about code scanning | ||
529 | * the list of drivers in order to probe new devices. Check to see | 533 | * the list of drivers in order to probe new devices. Check to see |
530 | * if the probe was successful, and make sure any forced probes of | 534 | * if the probe was successful, and make sure any forced probes of |
531 | * new devices fail. | 535 | * new devices fail. |
@@ -996,7 +1000,7 @@ static __initdata LIST_HEAD(early_platform_device_list); | |||
996 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, | 1000 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, |
997 | char *buf) | 1001 | char *buf) |
998 | { | 1002 | { |
999 | unsigned long index; | 1003 | char *tmp; |
1000 | int n; | 1004 | int n; |
1001 | 1005 | ||
1002 | /* Simply add the driver to the end of the global list. | 1006 | /* Simply add the driver to the end of the global list. |
@@ -1015,13 +1019,28 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, | |||
1015 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { | 1019 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { |
1016 | list_move(&epdrv->list, &early_platform_driver_list); | 1020 | list_move(&epdrv->list, &early_platform_driver_list); |
1017 | 1021 | ||
1018 | if (!strcmp(buf, epdrv->pdrv->driver.name)) | 1022 | /* Allow passing parameters after device name */ |
1023 | if (buf[n] == '\0' || buf[n] == ',') | ||
1019 | epdrv->requested_id = -1; | 1024 | epdrv->requested_id = -1; |
1020 | else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10, | 1025 | else { |
1021 | &index) == 0) | 1026 | epdrv->requested_id = simple_strtoul(&buf[n + 1], |
1022 | epdrv->requested_id = index; | 1027 | &tmp, 10); |
1023 | else | 1028 | |
1024 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | 1029 | if (buf[n] != '.' || (tmp == &buf[n + 1])) { |
1030 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | ||
1031 | n = 0; | ||
1032 | } else | ||
1033 | n += strcspn(&buf[n + 1], ",") + 1; | ||
1034 | } | ||
1035 | |||
1036 | if (buf[n] == ',') | ||
1037 | n++; | ||
1038 | |||
1039 | if (epdrv->bufsize) { | ||
1040 | memcpy(epdrv->buffer, &buf[n], | ||
1041 | min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); | ||
1042 | epdrv->buffer[epdrv->bufsize - 1] = '\0'; | ||
1043 | } | ||
1025 | } | 1044 | } |
1026 | 1045 | ||
1027 | return 0; | 1046 | return 0; |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e0dc4071e088..8aa2443182d5 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -511,6 +511,7 @@ static void dpm_complete(pm_message_t state) | |||
511 | 511 | ||
512 | INIT_LIST_HEAD(&list); | 512 | INIT_LIST_HEAD(&list); |
513 | mutex_lock(&dpm_list_mtx); | 513 | mutex_lock(&dpm_list_mtx); |
514 | transition_started = false; | ||
514 | while (!list_empty(&dpm_list)) { | 515 | while (!list_empty(&dpm_list)) { |
515 | struct device *dev = to_device(dpm_list.prev); | 516 | struct device *dev = to_device(dpm_list.prev); |
516 | 517 | ||
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 38556f6cc22d..5a01ecef4af3 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -51,8 +51,6 @@ static int __pm_runtime_idle(struct device *dev) | |||
51 | { | 51 | { |
52 | int retval = 0; | 52 | int retval = 0; |
53 | 53 | ||
54 | dev_dbg(dev, "__pm_runtime_idle()!\n"); | ||
55 | |||
56 | if (dev->power.runtime_error) | 54 | if (dev->power.runtime_error) |
57 | retval = -EINVAL; | 55 | retval = -EINVAL; |
58 | else if (dev->power.idle_notification) | 56 | else if (dev->power.idle_notification) |
@@ -93,8 +91,6 @@ static int __pm_runtime_idle(struct device *dev) | |||
93 | wake_up_all(&dev->power.wait_queue); | 91 | wake_up_all(&dev->power.wait_queue); |
94 | 92 | ||
95 | out: | 93 | out: |
96 | dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval); | ||
97 | |||
98 | return retval; | 94 | return retval; |
99 | } | 95 | } |
100 | 96 | ||
@@ -189,6 +185,7 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) | |||
189 | } | 185 | } |
190 | 186 | ||
191 | dev->power.runtime_status = RPM_SUSPENDING; | 187 | dev->power.runtime_status = RPM_SUSPENDING; |
188 | dev->power.deferred_resume = false; | ||
192 | 189 | ||
193 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) { | 190 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) { |
194 | spin_unlock_irq(&dev->power.lock); | 191 | spin_unlock_irq(&dev->power.lock); |
@@ -204,7 +201,6 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) | |||
204 | if (retval) { | 201 | if (retval) { |
205 | dev->power.runtime_status = RPM_ACTIVE; | 202 | dev->power.runtime_status = RPM_ACTIVE; |
206 | pm_runtime_cancel_pending(dev); | 203 | pm_runtime_cancel_pending(dev); |
207 | dev->power.deferred_resume = false; | ||
208 | 204 | ||
209 | if (retval == -EAGAIN || retval == -EBUSY) { | 205 | if (retval == -EAGAIN || retval == -EBUSY) { |
210 | notify = true; | 206 | notify = true; |
@@ -221,7 +217,6 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) | |||
221 | wake_up_all(&dev->power.wait_queue); | 217 | wake_up_all(&dev->power.wait_queue); |
222 | 218 | ||
223 | if (dev->power.deferred_resume) { | 219 | if (dev->power.deferred_resume) { |
224 | dev->power.deferred_resume = false; | ||
225 | __pm_runtime_resume(dev, false); | 220 | __pm_runtime_resume(dev, false); |
226 | retval = -EAGAIN; | 221 | retval = -EAGAIN; |
227 | goto out; | 222 | goto out; |
@@ -332,11 +327,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
332 | * necessary. | 327 | * necessary. |
333 | */ | 328 | */ |
334 | parent = dev->parent; | 329 | parent = dev->parent; |
335 | spin_unlock_irq(&dev->power.lock); | 330 | spin_unlock(&dev->power.lock); |
336 | 331 | ||
337 | pm_runtime_get_noresume(parent); | 332 | pm_runtime_get_noresume(parent); |
338 | 333 | ||
339 | spin_lock_irq(&parent->power.lock); | 334 | spin_lock(&parent->power.lock); |
340 | /* | 335 | /* |
341 | * We can resume if the parent's run-time PM is disabled or it | 336 | * We can resume if the parent's run-time PM is disabled or it |
342 | * is set to ignore children. | 337 | * is set to ignore children. |
@@ -347,9 +342,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
347 | if (parent->power.runtime_status != RPM_ACTIVE) | 342 | if (parent->power.runtime_status != RPM_ACTIVE) |
348 | retval = -EBUSY; | 343 | retval = -EBUSY; |
349 | } | 344 | } |
350 | spin_unlock_irq(&parent->power.lock); | 345 | spin_unlock(&parent->power.lock); |
351 | 346 | ||
352 | spin_lock_irq(&dev->power.lock); | 347 | spin_lock(&dev->power.lock); |
353 | if (retval) | 348 | if (retval) |
354 | goto out; | 349 | goto out; |
355 | goto repeat; | 350 | goto repeat; |
@@ -630,6 +625,8 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay) | |||
630 | goto out; | 625 | goto out; |
631 | 626 | ||
632 | dev->power.timer_expires = jiffies + msecs_to_jiffies(delay); | 627 | dev->power.timer_expires = jiffies + msecs_to_jiffies(delay); |
628 | if (!dev->power.timer_expires) | ||
629 | dev->power.timer_expires = 1; | ||
633 | mod_timer(&dev->power.suspend_timer, dev->power.timer_expires); | 630 | mod_timer(&dev->power.suspend_timer, dev->power.timer_expires); |
634 | 631 | ||
635 | out: | 632 | out: |
@@ -663,13 +660,17 @@ static int __pm_request_resume(struct device *dev) | |||
663 | 660 | ||
664 | pm_runtime_deactivate_timer(dev); | 661 | pm_runtime_deactivate_timer(dev); |
665 | 662 | ||
663 | if (dev->power.runtime_status == RPM_SUSPENDING) { | ||
664 | dev->power.deferred_resume = true; | ||
665 | return retval; | ||
666 | } | ||
666 | if (dev->power.request_pending) { | 667 | if (dev->power.request_pending) { |
667 | /* If non-resume request is pending, we can overtake it. */ | 668 | /* If non-resume request is pending, we can overtake it. */ |
668 | dev->power.request = retval ? RPM_REQ_NONE : RPM_REQ_RESUME; | 669 | dev->power.request = retval ? RPM_REQ_NONE : RPM_REQ_RESUME; |
669 | return retval; | 670 | return retval; |
670 | } else if (retval) { | ||
671 | return retval; | ||
672 | } | 671 | } |
672 | if (retval) | ||
673 | return retval; | ||
673 | 674 | ||
674 | dev->power.request = RPM_REQ_RESUME; | 675 | dev->power.request = RPM_REQ_RESUME; |
675 | dev->power.request_pending = true; | 676 | dev->power.request_pending = true; |
@@ -781,7 +782,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) | |||
781 | } | 782 | } |
782 | 783 | ||
783 | if (parent) { | 784 | if (parent) { |
784 | spin_lock_irq(&parent->power.lock); | 785 | spin_lock_nested(&parent->power.lock, SINGLE_DEPTH_NESTING); |
785 | 786 | ||
786 | /* | 787 | /* |
787 | * It is invalid to put an active child under a parent that is | 788 | * It is invalid to put an active child under a parent that is |
@@ -790,14 +791,12 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) | |||
790 | */ | 791 | */ |
791 | if (!parent->power.disable_depth | 792 | if (!parent->power.disable_depth |
792 | && !parent->power.ignore_children | 793 | && !parent->power.ignore_children |
793 | && parent->power.runtime_status != RPM_ACTIVE) { | 794 | && parent->power.runtime_status != RPM_ACTIVE) |
794 | error = -EBUSY; | 795 | error = -EBUSY; |
795 | } else { | 796 | else if (dev->power.runtime_status == RPM_SUSPENDED) |
796 | if (dev->power.runtime_status == RPM_SUSPENDED) | 797 | atomic_inc(&parent->power.child_count); |
797 | atomic_inc(&parent->power.child_count); | ||
798 | } | ||
799 | 798 | ||
800 | spin_unlock_irq(&parent->power.lock); | 799 | spin_unlock(&parent->power.lock); |
801 | 800 | ||
802 | if (error) | 801 | if (error) |
803 | goto out; | 802 | goto out; |