diff options
author | Jiri Kosina <jkosina@suse.cz> | 2014-02-20 08:54:28 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-02-20 08:54:28 -0500 |
commit | d4263348f796f29546f90802177865dd4379dd0a (patch) | |
tree | adcbdaebae584eee2f32fab95e826e8e49eef385 /drivers/base | |
parent | be873ac782f5ff5ee6675f83929f4fe6737eead2 (diff) | |
parent | 6d0abeca3242a88cab8232e4acd7e2bf088f3bc2 (diff) |
Merge branch 'master' into for-next
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Makefile | 4 | ||||
-rw-r--r-- | drivers/base/base.h | 1 | ||||
-rw-r--r-- | drivers/base/bus.c | 13 | ||||
-rw-r--r-- | drivers/base/component.c | 390 | ||||
-rw-r--r-- | drivers/base/container.c | 44 | ||||
-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/base/init.c | 1 | ||||
-rw-r--r-- | drivers/base/platform.c | 16 | ||||
-rw-r--r-- | drivers/base/power/clock_ops.c | 30 | ||||
-rw-r--r-- | drivers/base/power/generic_ops.c | 4 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 6 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 72 |
14 files changed, 608 insertions, 75 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 94e8a80e87f8..04b314e0fa51 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -1,10 +1,10 @@ | |||
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 \ |
7 | topology.o | 7 | topology.o container.o |
8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o | 8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o |
9 | obj-$(CONFIG_DMA_CMA) += dma-contiguous.o | 9 | obj-$(CONFIG_DMA_CMA) += dma-contiguous.o |
10 | obj-y += power/ | 10 | obj-y += power/ |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 2cbc6774f4cd..24f424249d9b 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -100,6 +100,7 @@ static inline int hypervisor_init(void) { return 0; } | |||
100 | #endif | 100 | #endif |
101 | extern int platform_bus_init(void); | 101 | extern int platform_bus_init(void); |
102 | extern void cpu_dev_init(void); | 102 | extern void cpu_dev_init(void); |
103 | extern void container_dev_init(void); | ||
103 | 104 | ||
104 | struct kobject *virtual_device_parent(struct device *dev); | 105 | struct kobject *virtual_device_parent(struct device *dev); |
105 | 106 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 1db22d3c4036..83e910a57563 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..c4778995cd72 --- /dev/null +++ b/drivers/base/component.c | |||
@@ -0,0 +1,390 @@ | |||
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 | if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) { | ||
137 | ret = -ENOMEM; | ||
138 | goto out; | ||
139 | } | ||
140 | |||
141 | /* Found all components */ | ||
142 | ret = master->ops->bind(master->dev); | ||
143 | if (ret < 0) { | ||
144 | devres_release_group(master->dev, NULL); | ||
145 | dev_info(master->dev, "master bind failed: %d\n", ret); | ||
146 | master_remove_components(master); | ||
147 | goto out; | ||
148 | } | ||
149 | |||
150 | master->bound = true; | ||
151 | ret = 1; | ||
152 | } | ||
153 | out: | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static int try_to_bring_up_masters(struct component *component) | ||
159 | { | ||
160 | struct master *m; | ||
161 | int ret = 0; | ||
162 | |||
163 | list_for_each_entry(m, &masters, node) { | ||
164 | ret = try_to_bring_up_master(m, component); | ||
165 | if (ret != 0) | ||
166 | break; | ||
167 | } | ||
168 | |||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static void take_down_master(struct master *master) | ||
173 | { | ||
174 | if (master->bound) { | ||
175 | master->ops->unbind(master->dev); | ||
176 | devres_release_group(master->dev, NULL); | ||
177 | master->bound = false; | ||
178 | } | ||
179 | |||
180 | master_remove_components(master); | ||
181 | } | ||
182 | |||
183 | int component_master_add(struct device *dev, | ||
184 | const struct component_master_ops *ops) | ||
185 | { | ||
186 | struct master *master; | ||
187 | int ret; | ||
188 | |||
189 | master = kzalloc(sizeof(*master), GFP_KERNEL); | ||
190 | if (!master) | ||
191 | return -ENOMEM; | ||
192 | |||
193 | master->dev = dev; | ||
194 | master->ops = ops; | ||
195 | INIT_LIST_HEAD(&master->components); | ||
196 | |||
197 | /* Add to the list of available masters. */ | ||
198 | mutex_lock(&component_mutex); | ||
199 | list_add(&master->node, &masters); | ||
200 | |||
201 | ret = try_to_bring_up_master(master, NULL); | ||
202 | |||
203 | if (ret < 0) { | ||
204 | /* Delete off the list if we weren't successful */ | ||
205 | list_del(&master->node); | ||
206 | kfree(master); | ||
207 | } | ||
208 | mutex_unlock(&component_mutex); | ||
209 | |||
210 | return ret < 0 ? ret : 0; | ||
211 | } | ||
212 | EXPORT_SYMBOL_GPL(component_master_add); | ||
213 | |||
214 | void component_master_del(struct device *dev, | ||
215 | const struct component_master_ops *ops) | ||
216 | { | ||
217 | struct master *master; | ||
218 | |||
219 | mutex_lock(&component_mutex); | ||
220 | master = __master_find(dev, ops); | ||
221 | if (master) { | ||
222 | take_down_master(master); | ||
223 | |||
224 | list_del(&master->node); | ||
225 | kfree(master); | ||
226 | } | ||
227 | mutex_unlock(&component_mutex); | ||
228 | } | ||
229 | EXPORT_SYMBOL_GPL(component_master_del); | ||
230 | |||
231 | static void component_unbind(struct component *component, | ||
232 | struct master *master, void *data) | ||
233 | { | ||
234 | WARN_ON(!component->bound); | ||
235 | |||
236 | component->ops->unbind(component->dev, master->dev, data); | ||
237 | component->bound = false; | ||
238 | |||
239 | /* Release all resources claimed in the binding of this component */ | ||
240 | devres_release_group(component->dev, component); | ||
241 | } | ||
242 | |||
243 | void component_unbind_all(struct device *master_dev, void *data) | ||
244 | { | ||
245 | struct master *master; | ||
246 | struct component *c; | ||
247 | |||
248 | WARN_ON(!mutex_is_locked(&component_mutex)); | ||
249 | |||
250 | master = __master_find(master_dev, NULL); | ||
251 | if (!master) | ||
252 | return; | ||
253 | |||
254 | list_for_each_entry_reverse(c, &master->components, master_node) | ||
255 | component_unbind(c, master, data); | ||
256 | } | ||
257 | EXPORT_SYMBOL_GPL(component_unbind_all); | ||
258 | |||
259 | static int component_bind(struct component *component, struct master *master, | ||
260 | void *data) | ||
261 | { | ||
262 | int ret; | ||
263 | |||
264 | /* | ||
265 | * Each component initialises inside its own devres group. | ||
266 | * This allows us to roll-back a failed component without | ||
267 | * affecting anything else. | ||
268 | */ | ||
269 | if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) | ||
270 | return -ENOMEM; | ||
271 | |||
272 | /* | ||
273 | * Also open a group for the device itself: this allows us | ||
274 | * to release the resources claimed against the sub-device | ||
275 | * at the appropriate moment. | ||
276 | */ | ||
277 | if (!devres_open_group(component->dev, component, GFP_KERNEL)) { | ||
278 | devres_release_group(master->dev, NULL); | ||
279 | return -ENOMEM; | ||
280 | } | ||
281 | |||
282 | dev_dbg(master->dev, "binding %s (ops %ps)\n", | ||
283 | dev_name(component->dev), component->ops); | ||
284 | |||
285 | ret = component->ops->bind(component->dev, master->dev, data); | ||
286 | if (!ret) { | ||
287 | component->bound = true; | ||
288 | |||
289 | /* | ||
290 | * Close the component device's group so that resources | ||
291 | * allocated in the binding are encapsulated for removal | ||
292 | * at unbind. Remove the group on the DRM device as we | ||
293 | * can clean those resources up independently. | ||
294 | */ | ||
295 | devres_close_group(component->dev, NULL); | ||
296 | devres_remove_group(master->dev, NULL); | ||
297 | |||
298 | dev_info(master->dev, "bound %s (ops %ps)\n", | ||
299 | dev_name(component->dev), component->ops); | ||
300 | } else { | ||
301 | devres_release_group(component->dev, NULL); | ||
302 | devres_release_group(master->dev, NULL); | ||
303 | |||
304 | dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", | ||
305 | dev_name(component->dev), component->ops, ret); | ||
306 | } | ||
307 | |||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | int component_bind_all(struct device *master_dev, void *data) | ||
312 | { | ||
313 | struct master *master; | ||
314 | struct component *c; | ||
315 | int ret = 0; | ||
316 | |||
317 | WARN_ON(!mutex_is_locked(&component_mutex)); | ||
318 | |||
319 | master = __master_find(master_dev, NULL); | ||
320 | if (!master) | ||
321 | return -EINVAL; | ||
322 | |||
323 | list_for_each_entry(c, &master->components, master_node) { | ||
324 | ret = component_bind(c, master, data); | ||
325 | if (ret) | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | if (ret != 0) { | ||
330 | list_for_each_entry_continue_reverse(c, &master->components, | ||
331 | master_node) | ||
332 | component_unbind(c, master, data); | ||
333 | } | ||
334 | |||
335 | return ret; | ||
336 | } | ||
337 | EXPORT_SYMBOL_GPL(component_bind_all); | ||
338 | |||
339 | int component_add(struct device *dev, const struct component_ops *ops) | ||
340 | { | ||
341 | struct component *component; | ||
342 | int ret; | ||
343 | |||
344 | component = kzalloc(sizeof(*component), GFP_KERNEL); | ||
345 | if (!component) | ||
346 | return -ENOMEM; | ||
347 | |||
348 | component->ops = ops; | ||
349 | component->dev = dev; | ||
350 | |||
351 | dev_dbg(dev, "adding component (ops %ps)\n", ops); | ||
352 | |||
353 | mutex_lock(&component_mutex); | ||
354 | list_add_tail(&component->node, &component_list); | ||
355 | |||
356 | ret = try_to_bring_up_masters(component); | ||
357 | if (ret < 0) { | ||
358 | list_del(&component->node); | ||
359 | |||
360 | kfree(component); | ||
361 | } | ||
362 | mutex_unlock(&component_mutex); | ||
363 | |||
364 | return ret < 0 ? ret : 0; | ||
365 | } | ||
366 | EXPORT_SYMBOL_GPL(component_add); | ||
367 | |||
368 | void component_del(struct device *dev, const struct component_ops *ops) | ||
369 | { | ||
370 | struct component *c, *component = NULL; | ||
371 | |||
372 | mutex_lock(&component_mutex); | ||
373 | list_for_each_entry(c, &component_list, node) | ||
374 | if (c->dev == dev && c->ops == ops) { | ||
375 | list_del(&c->node); | ||
376 | component = c; | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | if (component && component->master) | ||
381 | take_down_master(component->master); | ||
382 | |||
383 | mutex_unlock(&component_mutex); | ||
384 | |||
385 | WARN_ON(!component); | ||
386 | kfree(component); | ||
387 | } | ||
388 | EXPORT_SYMBOL_GPL(component_del); | ||
389 | |||
390 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/base/container.c b/drivers/base/container.c new file mode 100644 index 000000000000..ecbfbe2e908f --- /dev/null +++ b/drivers/base/container.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * System bus type for containers. | ||
3 | * | ||
4 | * Copyright (C) 2013, Intel Corporation | ||
5 | * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/container.h> | ||
13 | |||
14 | #include "base.h" | ||
15 | |||
16 | #define CONTAINER_BUS_NAME "container" | ||
17 | |||
18 | static int trivial_online(struct device *dev) | ||
19 | { | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | static int container_offline(struct device *dev) | ||
24 | { | ||
25 | struct container_dev *cdev = to_container_dev(dev); | ||
26 | |||
27 | return cdev->offline ? cdev->offline(cdev) : 0; | ||
28 | } | ||
29 | |||
30 | struct bus_type container_subsys = { | ||
31 | .name = CONTAINER_BUS_NAME, | ||
32 | .dev_name = CONTAINER_BUS_NAME, | ||
33 | .online = trivial_online, | ||
34 | .offline = container_offline, | ||
35 | }; | ||
36 | |||
37 | void __init container_dev_init(void) | ||
38 | { | ||
39 | int ret; | ||
40 | |||
41 | ret = subsys_system_register(&container_subsys, NULL); | ||
42 | if (ret) | ||
43 | pr_err("%s() failed: %d\n", __func__, ret); | ||
44 | } | ||
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/base/init.c b/drivers/base/init.c index c16f0b808a17..da033d3bab3c 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c | |||
@@ -33,4 +33,5 @@ void __init driver_init(void) | |||
33 | platform_bus_init(); | 33 | platform_bus_init(); |
34 | cpu_dev_init(); | 34 | cpu_dev_init(); |
35 | memory_dev_init(); | 35 | memory_dev_init(); |
36 | container_dev_init(); | ||
36 | } | 37 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3a94b799f166..bc78848dd59a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -677,7 +677,17 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
677 | char *buf) | 677 | char *buf) |
678 | { | 678 | { |
679 | struct platform_device *pdev = to_platform_device(dev); | 679 | struct platform_device *pdev = to_platform_device(dev); |
680 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | 680 | int len; |
681 | |||
682 | len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); | ||
683 | if (len != -ENODEV) | ||
684 | return len; | ||
685 | |||
686 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); | ||
687 | if (len != -ENODEV) | ||
688 | return len; | ||
689 | |||
690 | len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | ||
681 | 691 | ||
682 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 692 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
683 | } | 693 | } |
@@ -699,6 +709,10 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
699 | if (rc != -ENODEV) | 709 | if (rc != -ENODEV) |
700 | return rc; | 710 | return rc; |
701 | 711 | ||
712 | rc = acpi_device_uevent_modalias(dev, env); | ||
713 | if (rc != -ENODEV) | ||
714 | return rc; | ||
715 | |||
702 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, | 716 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
703 | pdev->name); | 717 | pdev->name); |
704 | return 0; | 718 | return 0; |
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 9d8fde709390..e870bbe9ec4e 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
@@ -33,6 +33,21 @@ struct pm_clock_entry { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * pm_clk_enable - Enable a clock, reporting any errors | ||
37 | * @dev: The device for the given clock | ||
38 | * @clk: The clock being enabled. | ||
39 | */ | ||
40 | static inline int __pm_clk_enable(struct device *dev, struct clk *clk) | ||
41 | { | ||
42 | int ret = clk_enable(clk); | ||
43 | if (ret) | ||
44 | dev_err(dev, "%s: failed to enable clk %p, error %d\n", | ||
45 | __func__, clk, ret); | ||
46 | |||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | /** | ||
36 | * pm_clk_acquire - Acquire a device clock. | 51 | * pm_clk_acquire - Acquire a device clock. |
37 | * @dev: Device whose clock is to be acquired. | 52 | * @dev: Device whose clock is to be acquired. |
38 | * @ce: PM clock entry corresponding to the clock. | 53 | * @ce: PM clock entry corresponding to the clock. |
@@ -43,6 +58,7 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) | |||
43 | if (IS_ERR(ce->clk)) { | 58 | if (IS_ERR(ce->clk)) { |
44 | ce->status = PCE_STATUS_ERROR; | 59 | ce->status = PCE_STATUS_ERROR; |
45 | } else { | 60 | } else { |
61 | clk_prepare(ce->clk); | ||
46 | ce->status = PCE_STATUS_ACQUIRED; | 62 | ce->status = PCE_STATUS_ACQUIRED; |
47 | dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); | 63 | dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); |
48 | } | 64 | } |
@@ -99,10 +115,12 @@ static void __pm_clk_remove(struct pm_clock_entry *ce) | |||
99 | 115 | ||
100 | if (ce->status < PCE_STATUS_ERROR) { | 116 | if (ce->status < PCE_STATUS_ERROR) { |
101 | if (ce->status == PCE_STATUS_ENABLED) | 117 | if (ce->status == PCE_STATUS_ENABLED) |
102 | clk_disable_unprepare(ce->clk); | 118 | clk_disable(ce->clk); |
103 | 119 | ||
104 | if (ce->status >= PCE_STATUS_ACQUIRED) | 120 | if (ce->status >= PCE_STATUS_ACQUIRED) { |
121 | clk_unprepare(ce->clk); | ||
105 | clk_put(ce->clk); | 122 | clk_put(ce->clk); |
123 | } | ||
106 | } | 124 | } |
107 | 125 | ||
108 | kfree(ce->con_id); | 126 | kfree(ce->con_id); |
@@ -249,6 +267,7 @@ int pm_clk_resume(struct device *dev) | |||
249 | struct pm_subsys_data *psd = dev_to_psd(dev); | 267 | struct pm_subsys_data *psd = dev_to_psd(dev); |
250 | struct pm_clock_entry *ce; | 268 | struct pm_clock_entry *ce; |
251 | unsigned long flags; | 269 | unsigned long flags; |
270 | int ret; | ||
252 | 271 | ||
253 | dev_dbg(dev, "%s()\n", __func__); | 272 | dev_dbg(dev, "%s()\n", __func__); |
254 | 273 | ||
@@ -259,8 +278,9 @@ int pm_clk_resume(struct device *dev) | |||
259 | 278 | ||
260 | list_for_each_entry(ce, &psd->clock_list, node) { | 279 | list_for_each_entry(ce, &psd->clock_list, node) { |
261 | if (ce->status < PCE_STATUS_ERROR) { | 280 | if (ce->status < PCE_STATUS_ERROR) { |
262 | clk_enable(ce->clk); | 281 | ret = __pm_clk_enable(dev, ce->clk); |
263 | ce->status = PCE_STATUS_ENABLED; | 282 | if (!ret) |
283 | ce->status = PCE_STATUS_ENABLED; | ||
264 | } | 284 | } |
265 | } | 285 | } |
266 | 286 | ||
@@ -376,7 +396,7 @@ int pm_clk_resume(struct device *dev) | |||
376 | spin_lock_irqsave(&psd->lock, flags); | 396 | spin_lock_irqsave(&psd->lock, flags); |
377 | 397 | ||
378 | list_for_each_entry(ce, &psd->clock_list, node) | 398 | list_for_each_entry(ce, &psd->clock_list, node) |
379 | clk_enable(ce->clk); | 399 | __pm_clk_enable(dev, ce->clk); |
380 | 400 | ||
381 | spin_unlock_irqrestore(&psd->lock, flags); | 401 | spin_unlock_irqrestore(&psd->lock, flags); |
382 | 402 | ||
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 5ee030a864f9..a2e55bfdf572 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/pm_runtime.h> | 10 | #include <linux/pm_runtime.h> |
11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
12 | 12 | ||
13 | #ifdef CONFIG_PM_RUNTIME | 13 | #ifdef CONFIG_PM |
14 | /** | 14 | /** |
15 | * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. | 15 | * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. |
16 | * @dev: Device to suspend. | 16 | * @dev: Device to suspend. |
@@ -48,7 +48,7 @@ int pm_generic_runtime_resume(struct device *dev) | |||
48 | return ret; | 48 | return ret; |
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); | 50 | EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); |
51 | #endif /* CONFIG_PM_RUNTIME */ | 51 | #endif /* CONFIG_PM */ |
52 | 52 | ||
53 | #ifdef CONFIG_PM_SLEEP | 53 | #ifdef CONFIG_PM_SLEEP |
54 | /** | 54 | /** |
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 763c60d3d277..82692068d3cb 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c | |||
@@ -113,7 +113,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) | |||
113 | * OR if there is masked interrupt which hasn't been Acked, | 113 | * OR if there is masked interrupt which hasn't been Acked, |
114 | * it'll be ignored in irq handler, then may introduce irq storm | 114 | * it'll be ignored in irq handler, then may introduce irq storm |
115 | */ | 115 | */ |
116 | if (d->mask_buf[i] && d->chip->ack_base) { | 116 | if (d->mask_buf[i] && (d->chip->ack_base || d->chip->use_ack)) { |
117 | reg = d->chip->ack_base + | 117 | reg = d->chip->ack_base + |
118 | (i * map->reg_stride * d->irq_reg_stride); | 118 | (i * map->reg_stride * d->irq_reg_stride); |
119 | ret = regmap_write(map, reg, d->mask_buf[i]); | 119 | ret = regmap_write(map, reg, d->mask_buf[i]); |
@@ -271,7 +271,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
271 | for (i = 0; i < data->chip->num_regs; i++) { | 271 | for (i = 0; i < data->chip->num_regs; i++) { |
272 | data->status_buf[i] &= ~data->mask_buf[i]; | 272 | data->status_buf[i] &= ~data->mask_buf[i]; |
273 | 273 | ||
274 | if (data->status_buf[i] && chip->ack_base) { | 274 | if (data->status_buf[i] && (chip->ack_base || chip->use_ack)) { |
275 | reg = chip->ack_base + | 275 | reg = chip->ack_base + |
276 | (i * map->reg_stride * data->irq_reg_stride); | 276 | (i * map->reg_stride * data->irq_reg_stride); |
277 | ret = regmap_write(map, reg, data->status_buf[i]); | 277 | ret = regmap_write(map, reg, data->status_buf[i]); |
@@ -448,7 +448,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
448 | goto err_alloc; | 448 | goto err_alloc; |
449 | } | 449 | } |
450 | 450 | ||
451 | if (d->status_buf[i] && chip->ack_base) { | 451 | if (d->status_buf[i] && (chip->ack_base || chip->use_ack)) { |
452 | reg = chip->ack_base + | 452 | reg = chip->ack_base + |
453 | (i * map->reg_stride * d->irq_reg_stride); | 453 | (i * map->reg_stride * d->irq_reg_stride); |
454 | ret = regmap_write(map, reg, | 454 | ret = regmap_write(map, reg, |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index c2e002100949..6a19515f8a45 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -1514,21 +1514,49 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | |||
1514 | { | 1514 | { |
1515 | int ret = 0, i; | 1515 | int ret = 0, i; |
1516 | size_t val_bytes = map->format.val_bytes; | 1516 | size_t val_bytes = map->format.val_bytes; |
1517 | void *wval; | ||
1518 | 1517 | ||
1519 | if (!map->bus) | 1518 | if (map->bus && !map->format.parse_inplace) |
1520 | return -EINVAL; | ||
1521 | if (!map->format.parse_inplace) | ||
1522 | return -EINVAL; | 1519 | return -EINVAL; |
1523 | if (reg % map->reg_stride) | 1520 | if (reg % map->reg_stride) |
1524 | return -EINVAL; | 1521 | return -EINVAL; |
1525 | 1522 | ||
1526 | map->lock(map->lock_arg); | 1523 | map->lock(map->lock_arg); |
1524 | /* | ||
1525 | * Some devices don't support bulk write, for | ||
1526 | * them we have a series of single write operations. | ||
1527 | */ | ||
1528 | if (!map->bus || map->use_single_rw) { | ||
1529 | for (i = 0; i < val_count; i++) { | ||
1530 | unsigned int ival; | ||
1531 | |||
1532 | switch (val_bytes) { | ||
1533 | case 1: | ||
1534 | ival = *(u8 *)(val + (i * val_bytes)); | ||
1535 | break; | ||
1536 | case 2: | ||
1537 | ival = *(u16 *)(val + (i * val_bytes)); | ||
1538 | break; | ||
1539 | case 4: | ||
1540 | ival = *(u32 *)(val + (i * val_bytes)); | ||
1541 | break; | ||
1542 | #ifdef CONFIG_64BIT | ||
1543 | case 8: | ||
1544 | ival = *(u64 *)(val + (i * val_bytes)); | ||
1545 | break; | ||
1546 | #endif | ||
1547 | default: | ||
1548 | ret = -EINVAL; | ||
1549 | goto out; | ||
1550 | } | ||
1527 | 1551 | ||
1528 | /* No formatting is require if val_byte is 1 */ | 1552 | ret = _regmap_write(map, reg + (i * map->reg_stride), |
1529 | if (val_bytes == 1) { | 1553 | ival); |
1530 | wval = (void *)val; | 1554 | if (ret != 0) |
1555 | goto out; | ||
1556 | } | ||
1531 | } else { | 1557 | } else { |
1558 | void *wval; | ||
1559 | |||
1532 | wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); | 1560 | wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); |
1533 | if (!wval) { | 1561 | if (!wval) { |
1534 | ret = -ENOMEM; | 1562 | ret = -ENOMEM; |
@@ -1537,27 +1565,11 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | |||
1537 | } | 1565 | } |
1538 | for (i = 0; i < val_count * val_bytes; i += val_bytes) | 1566 | for (i = 0; i < val_count * val_bytes; i += val_bytes) |
1539 | map->format.parse_inplace(wval + i); | 1567 | map->format.parse_inplace(wval + i); |
1540 | } | 1568 | |
1541 | /* | ||
1542 | * Some devices does not support bulk write, for | ||
1543 | * them we have a series of single write operations. | ||
1544 | */ | ||
1545 | if (map->use_single_rw) { | ||
1546 | for (i = 0; i < val_count; i++) { | ||
1547 | ret = _regmap_raw_write(map, | ||
1548 | reg + (i * map->reg_stride), | ||
1549 | val + (i * val_bytes), | ||
1550 | val_bytes); | ||
1551 | if (ret != 0) | ||
1552 | goto out; | ||
1553 | } | ||
1554 | } else { | ||
1555 | ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); | 1569 | ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); |
1556 | } | ||
1557 | 1570 | ||
1558 | if (val_bytes != 1) | ||
1559 | kfree(wval); | 1571 | kfree(wval); |
1560 | 1572 | } | |
1561 | out: | 1573 | out: |
1562 | map->unlock(map->lock_arg); | 1574 | map->unlock(map->lock_arg); |
1563 | return ret; | 1575 | return ret; |
@@ -1897,14 +1909,10 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, | |||
1897 | size_t val_bytes = map->format.val_bytes; | 1909 | size_t val_bytes = map->format.val_bytes; |
1898 | bool vol = regmap_volatile_range(map, reg, val_count); | 1910 | bool vol = regmap_volatile_range(map, reg, val_count); |
1899 | 1911 | ||
1900 | if (!map->bus) | ||
1901 | return -EINVAL; | ||
1902 | if (!map->format.parse_inplace) | ||
1903 | return -EINVAL; | ||
1904 | if (reg % map->reg_stride) | 1912 | if (reg % map->reg_stride) |
1905 | return -EINVAL; | 1913 | return -EINVAL; |
1906 | 1914 | ||
1907 | if (vol || map->cache_type == REGCACHE_NONE) { | 1915 | if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { |
1908 | /* | 1916 | /* |
1909 | * Some devices does not support bulk read, for | 1917 | * Some devices does not support bulk read, for |
1910 | * them we have a series of single read operations. | 1918 | * them we have a series of single read operations. |
@@ -2173,6 +2181,10 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | |||
2173 | int i, ret; | 2181 | int i, ret; |
2174 | bool bypass; | 2182 | bool bypass; |
2175 | 2183 | ||
2184 | if (WARN_ONCE(num_regs <= 0, "invalid registers number (%d)\n", | ||
2185 | num_regs)) | ||
2186 | return 0; | ||
2187 | |||
2176 | map->lock(map->lock_arg); | 2188 | map->lock(map->lock_arg); |
2177 | 2189 | ||
2178 | bypass = map->cache_bypass; | 2190 | bypass = map->cache_bypass; |