diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-20 18:49:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-20 18:49:44 -0500 |
commit | d3bad75a6d57416cf7478ca2a1e42f699bc17ec5 (patch) | |
tree | d79e9403e17aef5fee028fc550eec583dda38e0c /drivers | |
parent | 9f67627a0fea99b080a190d2d24cc1e2634aa2f7 (diff) | |
parent | db4aad209bc9aefd91f0a9aeb9e37364088b39ad (diff) |
Merge tag 'driver-core-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core / sysfs patches from Greg KH:
"Here's the big driver core and sysfs patch set for 3.14-rc1.
There's a lot of work here moving sysfs logic out into a "kernfs" to
allow other subsystems to also have a virtual filesystem with the same
attributes of sysfs (handle device disconnect, dynamic creation /
removal as needed / unneeded, etc)
This is primarily being done for the cgroups filesystem, but the goal
is to also move debugfs to it when it is ready, solving all of the
known issues in that filesystem as well. The code isn't completed
yet, but all should be stable now (there is a big section that was
reverted due to problems found when testing)
There's also some other smaller fixes, and a driver core addition that
allows for a "collection" of objects, that the DRM people will be
using soon (it's in this tree to make merges after -rc1 easier)
All of this has been in linux-next with no reported issues"
* tag 'driver-core-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (113 commits)
kernfs: associate a new kernfs_node with its parent on creation
kernfs: add struct dentry declaration in kernfs.h
kernfs: fix get_active failure handling in kernfs_seq_*()
Revert "kernfs: fix get_active failure handling in kernfs_seq_*()"
Revert "kernfs: replace kernfs_node->u.completion with kernfs_root->deactivate_waitq"
Revert "kernfs: remove KERNFS_ACTIVE_REF and add kernfs_lockdep()"
Revert "kernfs: remove KERNFS_REMOVED"
Revert "kernfs: restructure removal path to fix possible premature return"
Revert "kernfs: invoke kernfs_unmap_bin_file() directly from __kernfs_remove()"
Revert "kernfs: remove kernfs_addrm_cxt"
Revert "kernfs: make kernfs_get_active() block if the node is deactivated but not removed"
Revert "kernfs: implement kernfs_{de|re}activate[_self]()"
Revert "kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers"
Revert "pci: use device_remove_file_self() instead of device_schedule_callback()"
Revert "scsi: use device_remove_file_self() instead of device_schedule_callback()"
Revert "s390: use device_remove_file_self() instead of device_schedule_callback()"
Revert "sysfs, driver-core: remove unused {sysfs|device}_schedule_callback_owner()"
Revert "kernfs: remove unnecessary NULL check in __kernfs_remove()"
kernfs: remove unnecessary NULL check in __kernfs_remove()
drivers/base: provide an infrastructure for componentised subsystems
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/Makefile | 2 | ||||
-rw-r--r-- | drivers/base/bus.c | 13 | ||||
-rw-r--r-- | drivers/base/component.c | 382 | ||||
-rw-r--r-- | drivers/base/core.c | 7 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 2 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 93 | ||||
-rw-r--r-- | drivers/firmware/dmi-sysfs.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 4 | ||||
-rw-r--r-- | drivers/md/bitmap.c | 2 | ||||
-rw-r--r-- | drivers/md/bitmap.h | 2 | ||||
-rw-r--r-- | drivers/md/md.h | 10 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_device.h | 2 |
12 files changed, 478 insertions, 44 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 94e8a80e87f8..870ecfd503af 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # Makefile for the Linux device tree | 1 | # Makefile for the Linux device tree |
2 | 2 | ||
3 | obj-y := core.o bus.o dd.o syscore.o \ | 3 | obj-y := component.o core.o bus.o dd.o syscore.o \ |
4 | driver.o class.o platform.o \ | 4 | driver.o class.o platform.o \ |
5 | cpu.o firmware.o init.o map.o devres.o \ | 5 | cpu.o firmware.o init.o map.o devres.o \ |
6 | attribute_container.o transport_class.o \ | 6 | attribute_container.o transport_class.o \ |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 73f6c2925281..59dc8086e4fa 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -146,8 +146,19 @@ void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr) | |||
146 | } | 146 | } |
147 | EXPORT_SYMBOL_GPL(bus_remove_file); | 147 | EXPORT_SYMBOL_GPL(bus_remove_file); |
148 | 148 | ||
149 | static void bus_release(struct kobject *kobj) | ||
150 | { | ||
151 | struct subsys_private *priv = | ||
152 | container_of(kobj, typeof(*priv), subsys.kobj); | ||
153 | struct bus_type *bus = priv->bus; | ||
154 | |||
155 | kfree(priv); | ||
156 | bus->p = NULL; | ||
157 | } | ||
158 | |||
149 | static struct kobj_type bus_ktype = { | 159 | static struct kobj_type bus_ktype = { |
150 | .sysfs_ops = &bus_sysfs_ops, | 160 | .sysfs_ops = &bus_sysfs_ops, |
161 | .release = bus_release, | ||
151 | }; | 162 | }; |
152 | 163 | ||
153 | static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) | 164 | static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) |
@@ -953,8 +964,6 @@ void bus_unregister(struct bus_type *bus) | |||
953 | kset_unregister(bus->p->devices_kset); | 964 | kset_unregister(bus->p->devices_kset); |
954 | bus_remove_file(bus, &bus_attr_uevent); | 965 | bus_remove_file(bus, &bus_attr_uevent); |
955 | kset_unregister(&bus->p->subsys); | 966 | kset_unregister(&bus->p->subsys); |
956 | kfree(bus->p); | ||
957 | bus->p = NULL; | ||
958 | } | 967 | } |
959 | EXPORT_SYMBOL_GPL(bus_unregister); | 968 | EXPORT_SYMBOL_GPL(bus_unregister); |
960 | 969 | ||
diff --git a/drivers/base/component.c b/drivers/base/component.c new file mode 100644 index 000000000000..c53efe6c6d8e --- /dev/null +++ b/drivers/base/component.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /* | ||
2 | * Componentized device handling. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This is work in progress. We gather up the component devices into a list, | ||
9 | * and bind them when instructed. At the moment, we're specific to the DRM | ||
10 | * subsystem, and only handles one master device, but this doesn't have to be | ||
11 | * the case. | ||
12 | */ | ||
13 | #include <linux/component.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/kref.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | struct master { | ||
22 | struct list_head node; | ||
23 | struct list_head components; | ||
24 | bool bound; | ||
25 | |||
26 | const struct component_master_ops *ops; | ||
27 | struct device *dev; | ||
28 | }; | ||
29 | |||
30 | struct component { | ||
31 | struct list_head node; | ||
32 | struct list_head master_node; | ||
33 | struct master *master; | ||
34 | bool bound; | ||
35 | |||
36 | const struct component_ops *ops; | ||
37 | struct device *dev; | ||
38 | }; | ||
39 | |||
40 | static DEFINE_MUTEX(component_mutex); | ||
41 | static LIST_HEAD(component_list); | ||
42 | static LIST_HEAD(masters); | ||
43 | |||
44 | static struct master *__master_find(struct device *dev, | ||
45 | const struct component_master_ops *ops) | ||
46 | { | ||
47 | struct master *m; | ||
48 | |||
49 | list_for_each_entry(m, &masters, node) | ||
50 | if (m->dev == dev && (!ops || m->ops == ops)) | ||
51 | return m; | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | /* Attach an unattached component to a master. */ | ||
57 | static void component_attach_master(struct master *master, struct component *c) | ||
58 | { | ||
59 | c->master = master; | ||
60 | |||
61 | list_add_tail(&c->master_node, &master->components); | ||
62 | } | ||
63 | |||
64 | /* Detach a component from a master. */ | ||
65 | static void component_detach_master(struct master *master, struct component *c) | ||
66 | { | ||
67 | list_del(&c->master_node); | ||
68 | |||
69 | c->master = NULL; | ||
70 | } | ||
71 | |||
72 | int component_master_add_child(struct master *master, | ||
73 | int (*compare)(struct device *, void *), void *compare_data) | ||
74 | { | ||
75 | struct component *c; | ||
76 | int ret = -ENXIO; | ||
77 | |||
78 | list_for_each_entry(c, &component_list, node) { | ||
79 | if (c->master) | ||
80 | continue; | ||
81 | |||
82 | if (compare(c->dev, compare_data)) { | ||
83 | component_attach_master(master, c); | ||
84 | ret = 0; | ||
85 | break; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(component_master_add_child); | ||
92 | |||
93 | /* Detach all attached components from this master */ | ||
94 | static void master_remove_components(struct master *master) | ||
95 | { | ||
96 | while (!list_empty(&master->components)) { | ||
97 | struct component *c = list_first_entry(&master->components, | ||
98 | struct component, master_node); | ||
99 | |||
100 | WARN_ON(c->master != master); | ||
101 | |||
102 | component_detach_master(master, c); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Try to bring up a master. If component is NULL, we're interested in | ||
108 | * this master, otherwise it's a component which must be present to try | ||
109 | * and bring up the master. | ||
110 | * | ||
111 | * Returns 1 for successful bringup, 0 if not ready, or -ve errno. | ||
112 | */ | ||
113 | static int try_to_bring_up_master(struct master *master, | ||
114 | struct component *component) | ||
115 | { | ||
116 | int ret = 0; | ||
117 | |||
118 | if (!master->bound) { | ||
119 | /* | ||
120 | * Search the list of components, looking for components that | ||
121 | * belong to this master, and attach them to the master. | ||
122 | */ | ||
123 | if (master->ops->add_components(master->dev, master)) { | ||
124 | /* Failed to find all components */ | ||
125 | master_remove_components(master); | ||
126 | ret = 0; | ||
127 | goto out; | ||
128 | } | ||
129 | |||
130 | if (component && component->master != master) { | ||
131 | master_remove_components(master); | ||
132 | ret = 0; | ||
133 | goto out; | ||
134 | } | ||
135 | |||
136 | /* Found all components */ | ||
137 | ret = master->ops->bind(master->dev); | ||
138 | if (ret < 0) { | ||
139 | master_remove_components(master); | ||
140 | goto out; | ||
141 | } | ||
142 | |||
143 | master->bound = true; | ||
144 | ret = 1; | ||
145 | } | ||
146 | out: | ||
147 | |||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | static int try_to_bring_up_masters(struct component *component) | ||
152 | { | ||
153 | struct master *m; | ||
154 | int ret = 0; | ||
155 | |||
156 | list_for_each_entry(m, &masters, node) { | ||
157 | ret = try_to_bring_up_master(m, component); | ||
158 | if (ret != 0) | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static void take_down_master(struct master *master) | ||
166 | { | ||
167 | if (master->bound) { | ||
168 | master->ops->unbind(master->dev); | ||
169 | master->bound = false; | ||
170 | } | ||
171 | |||
172 | master_remove_components(master); | ||
173 | } | ||
174 | |||
175 | int component_master_add(struct device *dev, | ||
176 | const struct component_master_ops *ops) | ||
177 | { | ||
178 | struct master *master; | ||
179 | int ret; | ||
180 | |||
181 | master = kzalloc(sizeof(*master), GFP_KERNEL); | ||
182 | if (!master) | ||
183 | return -ENOMEM; | ||
184 | |||
185 | master->dev = dev; | ||
186 | master->ops = ops; | ||
187 | INIT_LIST_HEAD(&master->components); | ||
188 | |||
189 | /* Add to the list of available masters. */ | ||
190 | mutex_lock(&component_mutex); | ||
191 | list_add(&master->node, &masters); | ||
192 | |||
193 | ret = try_to_bring_up_master(master, NULL); | ||
194 | |||
195 | if (ret < 0) { | ||
196 | /* Delete off the list if we weren't successful */ | ||
197 | list_del(&master->node); | ||
198 | kfree(master); | ||
199 | } | ||
200 | mutex_unlock(&component_mutex); | ||
201 | |||
202 | return ret < 0 ? ret : 0; | ||
203 | } | ||
204 | EXPORT_SYMBOL_GPL(component_master_add); | ||
205 | |||
206 | void component_master_del(struct device *dev, | ||
207 | const struct component_master_ops *ops) | ||
208 | { | ||
209 | struct master *master; | ||
210 | |||
211 | mutex_lock(&component_mutex); | ||
212 | master = __master_find(dev, ops); | ||
213 | if (master) { | ||
214 | take_down_master(master); | ||
215 | |||
216 | list_del(&master->node); | ||
217 | kfree(master); | ||
218 | } | ||
219 | mutex_unlock(&component_mutex); | ||
220 | } | ||
221 | EXPORT_SYMBOL_GPL(component_master_del); | ||
222 | |||
223 | static void component_unbind(struct component *component, | ||
224 | struct master *master, void *data) | ||
225 | { | ||
226 | WARN_ON(!component->bound); | ||
227 | |||
228 | component->ops->unbind(component->dev, master->dev, data); | ||
229 | component->bound = false; | ||
230 | |||
231 | /* Release all resources claimed in the binding of this component */ | ||
232 | devres_release_group(component->dev, component); | ||
233 | } | ||
234 | |||
235 | void component_unbind_all(struct device *master_dev, void *data) | ||
236 | { | ||
237 | struct master *master; | ||
238 | struct component *c; | ||
239 | |||
240 | WARN_ON(!mutex_is_locked(&component_mutex)); | ||
241 | |||
242 | master = __master_find(master_dev, NULL); | ||
243 | if (!master) | ||
244 | return; | ||
245 | |||
246 | list_for_each_entry_reverse(c, &master->components, master_node) | ||
247 | component_unbind(c, master, data); | ||
248 | } | ||
249 | EXPORT_SYMBOL_GPL(component_unbind_all); | ||
250 | |||
251 | static int component_bind(struct component *component, struct master *master, | ||
252 | void *data) | ||
253 | { | ||
254 | int ret; | ||
255 | |||
256 | /* | ||
257 | * Each component initialises inside its own devres group. | ||
258 | * This allows us to roll-back a failed component without | ||
259 | * affecting anything else. | ||
260 | */ | ||
261 | if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) | ||
262 | return -ENOMEM; | ||
263 | |||
264 | /* | ||
265 | * Also open a group for the device itself: this allows us | ||
266 | * to release the resources claimed against the sub-device | ||
267 | * at the appropriate moment. | ||
268 | */ | ||
269 | if (!devres_open_group(component->dev, component, GFP_KERNEL)) { | ||
270 | devres_release_group(master->dev, NULL); | ||
271 | return -ENOMEM; | ||
272 | } | ||
273 | |||
274 | dev_dbg(master->dev, "binding %s (ops %ps)\n", | ||
275 | dev_name(component->dev), component->ops); | ||
276 | |||
277 | ret = component->ops->bind(component->dev, master->dev, data); | ||
278 | if (!ret) { | ||
279 | component->bound = true; | ||
280 | |||
281 | /* | ||
282 | * Close the component device's group so that resources | ||
283 | * allocated in the binding are encapsulated for removal | ||
284 | * at unbind. Remove the group on the DRM device as we | ||
285 | * can clean those resources up independently. | ||
286 | */ | ||
287 | devres_close_group(component->dev, NULL); | ||
288 | devres_remove_group(master->dev, NULL); | ||
289 | |||
290 | dev_info(master->dev, "bound %s (ops %ps)\n", | ||
291 | dev_name(component->dev), component->ops); | ||
292 | } else { | ||
293 | devres_release_group(component->dev, NULL); | ||
294 | devres_release_group(master->dev, NULL); | ||
295 | |||
296 | dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", | ||
297 | dev_name(component->dev), component->ops, ret); | ||
298 | } | ||
299 | |||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | int component_bind_all(struct device *master_dev, void *data) | ||
304 | { | ||
305 | struct master *master; | ||
306 | struct component *c; | ||
307 | int ret = 0; | ||
308 | |||
309 | WARN_ON(!mutex_is_locked(&component_mutex)); | ||
310 | |||
311 | master = __master_find(master_dev, NULL); | ||
312 | if (!master) | ||
313 | return -EINVAL; | ||
314 | |||
315 | list_for_each_entry(c, &master->components, master_node) { | ||
316 | ret = component_bind(c, master, data); | ||
317 | if (ret) | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | if (ret != 0) { | ||
322 | list_for_each_entry_continue_reverse(c, &master->components, | ||
323 | master_node) | ||
324 | component_unbind(c, master, data); | ||
325 | } | ||
326 | |||
327 | return ret; | ||
328 | } | ||
329 | EXPORT_SYMBOL_GPL(component_bind_all); | ||
330 | |||
331 | int component_add(struct device *dev, const struct component_ops *ops) | ||
332 | { | ||
333 | struct component *component; | ||
334 | int ret; | ||
335 | |||
336 | component = kzalloc(sizeof(*component), GFP_KERNEL); | ||
337 | if (!component) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | component->ops = ops; | ||
341 | component->dev = dev; | ||
342 | |||
343 | dev_dbg(dev, "adding component (ops %ps)\n", ops); | ||
344 | |||
345 | mutex_lock(&component_mutex); | ||
346 | list_add_tail(&component->node, &component_list); | ||
347 | |||
348 | ret = try_to_bring_up_masters(component); | ||
349 | if (ret < 0) { | ||
350 | list_del(&component->node); | ||
351 | |||
352 | kfree(component); | ||
353 | } | ||
354 | mutex_unlock(&component_mutex); | ||
355 | |||
356 | return ret < 0 ? ret : 0; | ||
357 | } | ||
358 | EXPORT_SYMBOL_GPL(component_add); | ||
359 | |||
360 | void component_del(struct device *dev, const struct component_ops *ops) | ||
361 | { | ||
362 | struct component *c, *component = NULL; | ||
363 | |||
364 | mutex_lock(&component_mutex); | ||
365 | list_for_each_entry(c, &component_list, node) | ||
366 | if (c->dev == dev && c->ops == ops) { | ||
367 | list_del(&c->node); | ||
368 | component = c; | ||
369 | break; | ||
370 | } | ||
371 | |||
372 | if (component && component->master) | ||
373 | take_down_master(component->master); | ||
374 | |||
375 | mutex_unlock(&component_mutex); | ||
376 | |||
377 | WARN_ON(!component); | ||
378 | kfree(component); | ||
379 | } | ||
380 | EXPORT_SYMBOL_GPL(component_del); | ||
381 | |||
382 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index 67b180d855b2..2b567177ef78 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -491,11 +491,13 @@ static int device_add_attrs(struct device *dev) | |||
491 | if (device_supports_offline(dev) && !dev->offline_disabled) { | 491 | if (device_supports_offline(dev) && !dev->offline_disabled) { |
492 | error = device_create_file(dev, &dev_attr_online); | 492 | error = device_create_file(dev, &dev_attr_online); |
493 | if (error) | 493 | if (error) |
494 | goto err_remove_type_groups; | 494 | goto err_remove_dev_groups; |
495 | } | 495 | } |
496 | 496 | ||
497 | return 0; | 497 | return 0; |
498 | 498 | ||
499 | err_remove_dev_groups: | ||
500 | device_remove_groups(dev, dev->groups); | ||
499 | err_remove_type_groups: | 501 | err_remove_type_groups: |
500 | if (type) | 502 | if (type) |
501 | device_remove_groups(dev, type->groups); | 503 | device_remove_groups(dev, type->groups); |
@@ -1603,6 +1605,7 @@ device_create_groups_vargs(struct class *class, struct device *parent, | |||
1603 | goto error; | 1605 | goto error; |
1604 | } | 1606 | } |
1605 | 1607 | ||
1608 | device_initialize(dev); | ||
1606 | dev->devt = devt; | 1609 | dev->devt = devt; |
1607 | dev->class = class; | 1610 | dev->class = class; |
1608 | dev->parent = parent; | 1611 | dev->parent = parent; |
@@ -1614,7 +1617,7 @@ device_create_groups_vargs(struct class *class, struct device *parent, | |||
1614 | if (retval) | 1617 | if (retval) |
1615 | goto error; | 1618 | goto error; |
1616 | 1619 | ||
1617 | retval = device_register(dev); | 1620 | retval = device_add(dev); |
1618 | if (retval) | 1621 | if (retval) |
1619 | goto error; | 1622 | goto error; |
1620 | 1623 | ||
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 0f3820121e02..25798db14553 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -299,7 +299,7 @@ static int handle_remove(const char *nodename, struct device *dev) | |||
299 | { | 299 | { |
300 | struct path parent; | 300 | struct path parent; |
301 | struct dentry *dentry; | 301 | struct dentry *dentry; |
302 | int deleted = 1; | 302 | int deleted = 0; |
303 | int err; | 303 | int err; |
304 | 304 | ||
305 | dentry = kern_path_locked(nodename, &parent); | 305 | dentry = kern_path_locked(nodename, &parent); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index eb8fb94ae2c5..8a97ddfa6122 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -96,6 +96,15 @@ static inline long firmware_loading_timeout(void) | |||
96 | return loading_timeout > 0 ? loading_timeout * HZ : MAX_SCHEDULE_TIMEOUT; | 96 | return loading_timeout > 0 ? loading_timeout * HZ : MAX_SCHEDULE_TIMEOUT; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* firmware behavior options */ | ||
100 | #define FW_OPT_UEVENT (1U << 0) | ||
101 | #define FW_OPT_NOWAIT (1U << 1) | ||
102 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
103 | #define FW_OPT_FALLBACK (1U << 2) | ||
104 | #else | ||
105 | #define FW_OPT_FALLBACK 0 | ||
106 | #endif | ||
107 | |||
99 | struct firmware_cache { | 108 | struct firmware_cache { |
100 | /* firmware_buf instance will be added into the below list */ | 109 | /* firmware_buf instance will be added into the below list */ |
101 | spinlock_t lock; | 110 | spinlock_t lock; |
@@ -219,6 +228,7 @@ static int fw_lookup_and_allocate_buf(const char *fw_name, | |||
219 | } | 228 | } |
220 | 229 | ||
221 | static void __fw_free_buf(struct kref *ref) | 230 | static void __fw_free_buf(struct kref *ref) |
231 | __releases(&fwc->lock) | ||
222 | { | 232 | { |
223 | struct firmware_buf *buf = to_fwbuf(ref); | 233 | struct firmware_buf *buf = to_fwbuf(ref); |
224 | struct firmware_cache *fwc = buf->fwc; | 234 | struct firmware_cache *fwc = buf->fwc; |
@@ -270,21 +280,21 @@ module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); | |||
270 | MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); | 280 | MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); |
271 | 281 | ||
272 | /* Don't inline this: 'struct kstat' is biggish */ | 282 | /* Don't inline this: 'struct kstat' is biggish */ |
273 | static noinline_for_stack long fw_file_size(struct file *file) | 283 | static noinline_for_stack int fw_file_size(struct file *file) |
274 | { | 284 | { |
275 | struct kstat st; | 285 | struct kstat st; |
276 | if (vfs_getattr(&file->f_path, &st)) | 286 | if (vfs_getattr(&file->f_path, &st)) |
277 | return -1; | 287 | return -1; |
278 | if (!S_ISREG(st.mode)) | 288 | if (!S_ISREG(st.mode)) |
279 | return -1; | 289 | return -1; |
280 | if (st.size != (long)st.size) | 290 | if (st.size != (int)st.size) |
281 | return -1; | 291 | return -1; |
282 | return st.size; | 292 | return st.size; |
283 | } | 293 | } |
284 | 294 | ||
285 | static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | 295 | static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) |
286 | { | 296 | { |
287 | long size; | 297 | int size; |
288 | char *buf; | 298 | char *buf; |
289 | int rc; | 299 | int rc; |
290 | 300 | ||
@@ -820,7 +830,7 @@ static void firmware_class_timeout_work(struct work_struct *work) | |||
820 | 830 | ||
821 | static struct firmware_priv * | 831 | static struct firmware_priv * |
822 | fw_create_instance(struct firmware *firmware, const char *fw_name, | 832 | fw_create_instance(struct firmware *firmware, const char *fw_name, |
823 | struct device *device, bool uevent, bool nowait) | 833 | struct device *device, unsigned int opt_flags) |
824 | { | 834 | { |
825 | struct firmware_priv *fw_priv; | 835 | struct firmware_priv *fw_priv; |
826 | struct device *f_dev; | 836 | struct device *f_dev; |
@@ -832,7 +842,7 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, | |||
832 | goto exit; | 842 | goto exit; |
833 | } | 843 | } |
834 | 844 | ||
835 | fw_priv->nowait = nowait; | 845 | fw_priv->nowait = !!(opt_flags & FW_OPT_NOWAIT); |
836 | fw_priv->fw = firmware; | 846 | fw_priv->fw = firmware; |
837 | INIT_DELAYED_WORK(&fw_priv->timeout_work, | 847 | INIT_DELAYED_WORK(&fw_priv->timeout_work, |
838 | firmware_class_timeout_work); | 848 | firmware_class_timeout_work); |
@@ -848,8 +858,8 @@ exit: | |||
848 | } | 858 | } |
849 | 859 | ||
850 | /* load a firmware via user helper */ | 860 | /* load a firmware via user helper */ |
851 | static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | 861 | static int _request_firmware_load(struct firmware_priv *fw_priv, |
852 | long timeout) | 862 | unsigned int opt_flags, long timeout) |
853 | { | 863 | { |
854 | int retval = 0; | 864 | int retval = 0; |
855 | struct device *f_dev = &fw_priv->dev; | 865 | struct device *f_dev = &fw_priv->dev; |
@@ -885,7 +895,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
885 | goto err_del_bin_attr; | 895 | goto err_del_bin_attr; |
886 | } | 896 | } |
887 | 897 | ||
888 | if (uevent) { | 898 | if (opt_flags & FW_OPT_UEVENT) { |
889 | buf->need_uevent = true; | 899 | buf->need_uevent = true; |
890 | dev_set_uevent_suppress(f_dev, false); | 900 | dev_set_uevent_suppress(f_dev, false); |
891 | dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); | 901 | dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); |
@@ -911,16 +921,16 @@ err_put_dev: | |||
911 | 921 | ||
912 | static int fw_load_from_user_helper(struct firmware *firmware, | 922 | static int fw_load_from_user_helper(struct firmware *firmware, |
913 | const char *name, struct device *device, | 923 | const char *name, struct device *device, |
914 | bool uevent, bool nowait, long timeout) | 924 | unsigned int opt_flags, long timeout) |
915 | { | 925 | { |
916 | struct firmware_priv *fw_priv; | 926 | struct firmware_priv *fw_priv; |
917 | 927 | ||
918 | fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); | 928 | fw_priv = fw_create_instance(firmware, name, device, opt_flags); |
919 | if (IS_ERR(fw_priv)) | 929 | if (IS_ERR(fw_priv)) |
920 | return PTR_ERR(fw_priv); | 930 | return PTR_ERR(fw_priv); |
921 | 931 | ||
922 | fw_priv->buf = firmware->priv; | 932 | fw_priv->buf = firmware->priv; |
923 | return _request_firmware_load(fw_priv, uevent, timeout); | 933 | return _request_firmware_load(fw_priv, opt_flags, timeout); |
924 | } | 934 | } |
925 | 935 | ||
926 | #ifdef CONFIG_PM_SLEEP | 936 | #ifdef CONFIG_PM_SLEEP |
@@ -942,7 +952,7 @@ static void kill_requests_without_uevent(void) | |||
942 | #else /* CONFIG_FW_LOADER_USER_HELPER */ | 952 | #else /* CONFIG_FW_LOADER_USER_HELPER */ |
943 | static inline int | 953 | static inline int |
944 | fw_load_from_user_helper(struct firmware *firmware, const char *name, | 954 | fw_load_from_user_helper(struct firmware *firmware, const char *name, |
945 | struct device *device, bool uevent, bool nowait, | 955 | struct device *device, unsigned int opt_flags, |
946 | long timeout) | 956 | long timeout) |
947 | { | 957 | { |
948 | return -ENOENT; | 958 | return -ENOENT; |
@@ -1023,7 +1033,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, | |||
1023 | } | 1033 | } |
1024 | 1034 | ||
1025 | static int assign_firmware_buf(struct firmware *fw, struct device *device, | 1035 | static int assign_firmware_buf(struct firmware *fw, struct device *device, |
1026 | bool skip_cache) | 1036 | unsigned int opt_flags) |
1027 | { | 1037 | { |
1028 | struct firmware_buf *buf = fw->priv; | 1038 | struct firmware_buf *buf = fw->priv; |
1029 | 1039 | ||
@@ -1040,7 +1050,8 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, | |||
1040 | * device may has been deleted already, but the problem | 1050 | * device may has been deleted already, but the problem |
1041 | * should be fixed in devres or driver core. | 1051 | * should be fixed in devres or driver core. |
1042 | */ | 1052 | */ |
1043 | if (device && !skip_cache) | 1053 | /* don't cache firmware handled without uevent */ |
1054 | if (device && (opt_flags & FW_OPT_UEVENT)) | ||
1044 | fw_add_devm_name(device, buf->fw_id); | 1055 | fw_add_devm_name(device, buf->fw_id); |
1045 | 1056 | ||
1046 | /* | 1057 | /* |
@@ -1061,7 +1072,7 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, | |||
1061 | /* called from request_firmware() and request_firmware_work_func() */ | 1072 | /* called from request_firmware() and request_firmware_work_func() */ |
1062 | static int | 1073 | static int |
1063 | _request_firmware(const struct firmware **firmware_p, const char *name, | 1074 | _request_firmware(const struct firmware **firmware_p, const char *name, |
1064 | struct device *device, bool uevent, bool nowait) | 1075 | struct device *device, unsigned int opt_flags) |
1065 | { | 1076 | { |
1066 | struct firmware *fw; | 1077 | struct firmware *fw; |
1067 | long timeout; | 1078 | long timeout; |
@@ -1076,7 +1087,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
1076 | 1087 | ||
1077 | ret = 0; | 1088 | ret = 0; |
1078 | timeout = firmware_loading_timeout(); | 1089 | timeout = firmware_loading_timeout(); |
1079 | if (nowait) { | 1090 | if (opt_flags & FW_OPT_NOWAIT) { |
1080 | timeout = usermodehelper_read_lock_wait(timeout); | 1091 | timeout = usermodehelper_read_lock_wait(timeout); |
1081 | if (!timeout) { | 1092 | if (!timeout) { |
1082 | dev_dbg(device, "firmware: %s loading timed out\n", | 1093 | dev_dbg(device, "firmware: %s loading timed out\n", |
@@ -1095,16 +1106,18 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
1095 | 1106 | ||
1096 | ret = fw_get_filesystem_firmware(device, fw->priv); | 1107 | ret = fw_get_filesystem_firmware(device, fw->priv); |
1097 | if (ret) { | 1108 | if (ret) { |
1098 | dev_warn(device, "Direct firmware load failed with error %d\n", | 1109 | if (opt_flags & FW_OPT_FALLBACK) { |
1099 | ret); | 1110 | dev_warn(device, |
1100 | dev_warn(device, "Falling back to user helper\n"); | 1111 | "Direct firmware load failed with error %d\n", |
1101 | ret = fw_load_from_user_helper(fw, name, device, | 1112 | ret); |
1102 | uevent, nowait, timeout); | 1113 | dev_warn(device, "Falling back to user helper\n"); |
1114 | ret = fw_load_from_user_helper(fw, name, device, | ||
1115 | opt_flags, timeout); | ||
1116 | } | ||
1103 | } | 1117 | } |
1104 | 1118 | ||
1105 | /* don't cache firmware handled without uevent */ | ||
1106 | if (!ret) | 1119 | if (!ret) |
1107 | ret = assign_firmware_buf(fw, device, !uevent); | 1120 | ret = assign_firmware_buf(fw, device, opt_flags); |
1108 | 1121 | ||
1109 | usermodehelper_read_unlock(); | 1122 | usermodehelper_read_unlock(); |
1110 | 1123 | ||
@@ -1146,12 +1159,37 @@ request_firmware(const struct firmware **firmware_p, const char *name, | |||
1146 | 1159 | ||
1147 | /* Need to pin this module until return */ | 1160 | /* Need to pin this module until return */ |
1148 | __module_get(THIS_MODULE); | 1161 | __module_get(THIS_MODULE); |
1149 | ret = _request_firmware(firmware_p, name, device, true, false); | 1162 | ret = _request_firmware(firmware_p, name, device, |
1163 | FW_OPT_UEVENT | FW_OPT_FALLBACK); | ||
1150 | module_put(THIS_MODULE); | 1164 | module_put(THIS_MODULE); |
1151 | return ret; | 1165 | return ret; |
1152 | } | 1166 | } |
1153 | EXPORT_SYMBOL(request_firmware); | 1167 | EXPORT_SYMBOL(request_firmware); |
1154 | 1168 | ||
1169 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
1170 | /** | ||
1171 | * request_firmware: - load firmware directly without usermode helper | ||
1172 | * @firmware_p: pointer to firmware image | ||
1173 | * @name: name of firmware file | ||
1174 | * @device: device for which firmware is being loaded | ||
1175 | * | ||
1176 | * This function works pretty much like request_firmware(), but this doesn't | ||
1177 | * fall back to usermode helper even if the firmware couldn't be loaded | ||
1178 | * directly from fs. Hence it's useful for loading optional firmwares, which | ||
1179 | * aren't always present, without extra long timeouts of udev. | ||
1180 | **/ | ||
1181 | int request_firmware_direct(const struct firmware **firmware_p, | ||
1182 | const char *name, struct device *device) | ||
1183 | { | ||
1184 | int ret; | ||
1185 | __module_get(THIS_MODULE); | ||
1186 | ret = _request_firmware(firmware_p, name, device, FW_OPT_UEVENT); | ||
1187 | module_put(THIS_MODULE); | ||
1188 | return ret; | ||
1189 | } | ||
1190 | EXPORT_SYMBOL_GPL(request_firmware_direct); | ||
1191 | #endif | ||
1192 | |||
1155 | /** | 1193 | /** |
1156 | * release_firmware: - release the resource associated with a firmware image | 1194 | * release_firmware: - release the resource associated with a firmware image |
1157 | * @fw: firmware resource to release | 1195 | * @fw: firmware resource to release |
@@ -1174,7 +1212,7 @@ struct firmware_work { | |||
1174 | struct device *device; | 1212 | struct device *device; |
1175 | void *context; | 1213 | void *context; |
1176 | void (*cont)(const struct firmware *fw, void *context); | 1214 | void (*cont)(const struct firmware *fw, void *context); |
1177 | bool uevent; | 1215 | unsigned int opt_flags; |
1178 | }; | 1216 | }; |
1179 | 1217 | ||
1180 | static void request_firmware_work_func(struct work_struct *work) | 1218 | static void request_firmware_work_func(struct work_struct *work) |
@@ -1185,7 +1223,7 @@ static void request_firmware_work_func(struct work_struct *work) | |||
1185 | fw_work = container_of(work, struct firmware_work, work); | 1223 | fw_work = container_of(work, struct firmware_work, work); |
1186 | 1224 | ||
1187 | _request_firmware(&fw, fw_work->name, fw_work->device, | 1225 | _request_firmware(&fw, fw_work->name, fw_work->device, |
1188 | fw_work->uevent, true); | 1226 | fw_work->opt_flags); |
1189 | fw_work->cont(fw, fw_work->context); | 1227 | fw_work->cont(fw, fw_work->context); |
1190 | put_device(fw_work->device); /* taken in request_firmware_nowait() */ | 1228 | put_device(fw_work->device); /* taken in request_firmware_nowait() */ |
1191 | 1229 | ||
@@ -1233,7 +1271,8 @@ request_firmware_nowait( | |||
1233 | fw_work->device = device; | 1271 | fw_work->device = device; |
1234 | fw_work->context = context; | 1272 | fw_work->context = context; |
1235 | fw_work->cont = cont; | 1273 | fw_work->cont = cont; |
1236 | fw_work->uevent = uevent; | 1274 | fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK | |
1275 | (uevent ? FW_OPT_UEVENT : 0); | ||
1237 | 1276 | ||
1238 | if (!try_module_get(module)) { | 1277 | if (!try_module_get(module)) { |
1239 | kfree(fw_work); | 1278 | kfree(fw_work); |
diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c index eb26d62e5188..e0f1cb3d3598 100644 --- a/drivers/firmware/dmi-sysfs.c +++ b/drivers/firmware/dmi-sysfs.c | |||
@@ -553,7 +553,7 @@ static const struct bin_attribute dmi_entry_raw_attr = { | |||
553 | static void dmi_sysfs_entry_release(struct kobject *kobj) | 553 | static void dmi_sysfs_entry_release(struct kobject *kobj) |
554 | { | 554 | { |
555 | struct dmi_sysfs_entry *entry = to_entry(kobj); | 555 | struct dmi_sysfs_entry *entry = to_entry(kobj); |
556 | sysfs_remove_bin_file(&entry->kobj, &dmi_entry_raw_attr); | 556 | |
557 | spin_lock(&entry_list_lock); | 557 | spin_lock(&entry_list_lock); |
558 | list_del(&entry->list); | 558 | list_del(&entry->list); |
559 | spin_unlock(&entry_list_lock); | 559 | spin_unlock(&entry_list_lock); |
@@ -685,6 +685,7 @@ static void __exit dmi_sysfs_exit(void) | |||
685 | pr_debug("dmi-sysfs: unloading.\n"); | 685 | pr_debug("dmi-sysfs: unloading.\n"); |
686 | cleanup_entry_list(); | 686 | cleanup_entry_list(); |
687 | kset_unregister(dmi_kset); | 687 | kset_unregister(dmi_kset); |
688 | kobject_del(dmi_kobj); | ||
688 | kobject_put(dmi_kobj); | 689 | kobject_put(dmi_kobj); |
689 | } | 690 | } |
690 | 691 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 85f772c0b26a..c8a7c810bade 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -393,7 +393,7 @@ static const DEVICE_ATTR(value, 0644, | |||
393 | 393 | ||
394 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) | 394 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) |
395 | { | 395 | { |
396 | struct sysfs_dirent *value_sd = priv; | 396 | struct kernfs_node *value_sd = priv; |
397 | 397 | ||
398 | sysfs_notify_dirent(value_sd); | 398 | sysfs_notify_dirent(value_sd); |
399 | return IRQ_HANDLED; | 399 | return IRQ_HANDLED; |
@@ -402,7 +402,7 @@ static irqreturn_t gpio_sysfs_irq(int irq, void *priv) | |||
402 | static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | 402 | static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, |
403 | unsigned long gpio_flags) | 403 | unsigned long gpio_flags) |
404 | { | 404 | { |
405 | struct sysfs_dirent *value_sd; | 405 | struct kernfs_node *value_sd; |
406 | unsigned long irq_flags; | 406 | unsigned long irq_flags; |
407 | int ret, irq, id; | 407 | int ret, irq, id; |
408 | 408 | ||
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 12dc29ba7399..4195a01b1535 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1635,7 +1635,7 @@ int bitmap_create(struct mddev *mddev) | |||
1635 | sector_t blocks = mddev->resync_max_sectors; | 1635 | sector_t blocks = mddev->resync_max_sectors; |
1636 | struct file *file = mddev->bitmap_info.file; | 1636 | struct file *file = mddev->bitmap_info.file; |
1637 | int err; | 1637 | int err; |
1638 | struct sysfs_dirent *bm = NULL; | 1638 | struct kernfs_node *bm = NULL; |
1639 | 1639 | ||
1640 | BUILD_BUG_ON(sizeof(bitmap_super_t) != 256); | 1640 | BUILD_BUG_ON(sizeof(bitmap_super_t) != 256); |
1641 | 1641 | ||
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index df4aeb6ac6f0..30210b9c4ef9 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h | |||
@@ -225,7 +225,7 @@ struct bitmap { | |||
225 | wait_queue_head_t overflow_wait; | 225 | wait_queue_head_t overflow_wait; |
226 | wait_queue_head_t behind_wait; | 226 | wait_queue_head_t behind_wait; |
227 | 227 | ||
228 | struct sysfs_dirent *sysfs_can_clear; | 228 | struct kernfs_node *sysfs_can_clear; |
229 | }; | 229 | }; |
230 | 230 | ||
231 | /* the bitmap API */ | 231 | /* the bitmap API */ |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 0095ec84ffc7..07bba96de260 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -106,7 +106,7 @@ struct md_rdev { | |||
106 | */ | 106 | */ |
107 | struct work_struct del_work; /* used for delayed sysfs removal */ | 107 | struct work_struct del_work; /* used for delayed sysfs removal */ |
108 | 108 | ||
109 | struct sysfs_dirent *sysfs_state; /* handle for 'state' | 109 | struct kernfs_node *sysfs_state; /* handle for 'state' |
110 | * sysfs entry */ | 110 | * sysfs entry */ |
111 | 111 | ||
112 | struct badblocks { | 112 | struct badblocks { |
@@ -379,10 +379,10 @@ struct mddev { | |||
379 | sector_t resync_max; /* resync should pause | 379 | sector_t resync_max; /* resync should pause |
380 | * when it gets here */ | 380 | * when it gets here */ |
381 | 381 | ||
382 | struct sysfs_dirent *sysfs_state; /* handle for 'array_state' | 382 | struct kernfs_node *sysfs_state; /* handle for 'array_state' |
383 | * file in sysfs. | 383 | * file in sysfs. |
384 | */ | 384 | */ |
385 | struct sysfs_dirent *sysfs_action; /* handle for 'sync_action' */ | 385 | struct kernfs_node *sysfs_action; /* handle for 'sync_action' */ |
386 | 386 | ||
387 | struct work_struct del_work; /* used for delayed sysfs removal */ | 387 | struct work_struct del_work; /* used for delayed sysfs removal */ |
388 | 388 | ||
@@ -501,13 +501,13 @@ struct md_sysfs_entry { | |||
501 | }; | 501 | }; |
502 | extern struct attribute_group md_bitmap_group; | 502 | extern struct attribute_group md_bitmap_group; |
503 | 503 | ||
504 | static inline struct sysfs_dirent *sysfs_get_dirent_safe(struct sysfs_dirent *sd, char *name) | 504 | static inline struct kernfs_node *sysfs_get_dirent_safe(struct kernfs_node *sd, char *name) |
505 | { | 505 | { |
506 | if (sd) | 506 | if (sd) |
507 | return sysfs_get_dirent(sd, name); | 507 | return sysfs_get_dirent(sd, name); |
508 | return sd; | 508 | return sd; |
509 | } | 509 | } |
510 | static inline void sysfs_notify_dirent_safe(struct sysfs_dirent *sd) | 510 | static inline void sysfs_notify_dirent_safe(struct kernfs_node *sd) |
511 | { | 511 | { |
512 | if (sd) | 512 | if (sd) |
513 | sysfs_notify_dirent(sd); | 513 | sysfs_notify_dirent(sd); |
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h index b2da289320c9..1a6edce2ecde 100644 --- a/drivers/misc/mic/host/mic_device.h +++ b/drivers/misc/mic/host/mic_device.h | |||
@@ -112,7 +112,7 @@ struct mic_device { | |||
112 | struct work_struct shutdown_work; | 112 | struct work_struct shutdown_work; |
113 | u8 state; | 113 | u8 state; |
114 | u8 shutdown_status; | 114 | u8 shutdown_status; |
115 | struct sysfs_dirent *state_sysfs; | 115 | struct kernfs_node *state_sysfs; |
116 | struct completion reset_wait; | 116 | struct completion reset_wait; |
117 | void *log_buf_addr; | 117 | void *log_buf_addr; |
118 | int *log_buf_len; | 118 | int *log_buf_len; |