diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-06-17 19:55:13 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-06-17 19:55:13 -0400 |
commit | 9d066a252786e1a18484a6283f82614d42a9f4ac (patch) | |
tree | 72188d2f86b3d0c4100257c8d5734f2c648a8bc7 /drivers/base | |
parent | 79ee2e8f730411a30b271d5f9cdeae189fa66174 (diff) | |
parent | b00345d1994d588fa2687e1238fcd542f0320cba (diff) |
Merge branches 'pm-opp' and 'pm-cpufreq-fixes'
* pm-opp:
PM / OPP: Add 'UNKNOWN' status for shared_opp in struct opp_table
* pm-cpufreq-fixes:
cpufreq: intel_pstate: Adjust _PSS[0] freqeuency if needed
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/devcoredump.c | 83 | ||||
-rw-r--r-- | drivers/base/platform.c | 19 | ||||
-rw-r--r-- | drivers/base/power/clock_ops.c | 2 | ||||
-rw-r--r-- | drivers/base/power/domain.c | 145 | ||||
-rw-r--r-- | drivers/base/power/domain_governor.c | 20 | ||||
-rw-r--r-- | drivers/base/power/main.c | 23 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 9 | ||||
-rw-r--r-- | drivers/base/property.c | 36 | ||||
-rw-r--r-- | drivers/base/regmap/internal.h | 1 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-flat.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-mmio.c | 5 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-spmi.c | 2 |
13 files changed, 199 insertions, 150 deletions
diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index 1bd120a0b084..240374fd1838 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * GPL LICENSE SUMMARY | 4 | * GPL LICENSE SUMMARY |
5 | * | 5 | * |
6 | * Copyright(c) 2014 Intel Mobile Communications GmbH | 6 | * Copyright(c) 2014 Intel Mobile Communications GmbH |
7 | * Copyright(c) 2015 Intel Deutschland GmbH | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of version 2 of the GNU General Public License as | 10 | * it under the terms of version 2 of the GNU General Public License as |
@@ -41,12 +42,12 @@ static bool devcd_disabled; | |||
41 | 42 | ||
42 | struct devcd_entry { | 43 | struct devcd_entry { |
43 | struct device devcd_dev; | 44 | struct device devcd_dev; |
44 | const void *data; | 45 | void *data; |
45 | size_t datalen; | 46 | size_t datalen; |
46 | struct module *owner; | 47 | struct module *owner; |
47 | ssize_t (*read)(char *buffer, loff_t offset, size_t count, | 48 | ssize_t (*read)(char *buffer, loff_t offset, size_t count, |
48 | const void *data, size_t datalen); | 49 | void *data, size_t datalen); |
49 | void (*free)(const void *data); | 50 | void (*free)(void *data); |
50 | struct delayed_work del_wk; | 51 | struct delayed_work del_wk; |
51 | struct device *failing_dev; | 52 | struct device *failing_dev; |
52 | }; | 53 | }; |
@@ -174,7 +175,7 @@ static struct class devcd_class = { | |||
174 | }; | 175 | }; |
175 | 176 | ||
176 | static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count, | 177 | static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count, |
177 | const void *data, size_t datalen) | 178 | void *data, size_t datalen) |
178 | { | 179 | { |
179 | if (offset > datalen) | 180 | if (offset > datalen) |
180 | return -EINVAL; | 181 | return -EINVAL; |
@@ -188,6 +189,11 @@ static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count, | |||
188 | return count; | 189 | return count; |
189 | } | 190 | } |
190 | 191 | ||
192 | static void devcd_freev(void *data) | ||
193 | { | ||
194 | vfree(data); | ||
195 | } | ||
196 | |||
191 | /** | 197 | /** |
192 | * dev_coredumpv - create device coredump with vmalloc data | 198 | * dev_coredumpv - create device coredump with vmalloc data |
193 | * @dev: the struct device for the crashed device | 199 | * @dev: the struct device for the crashed device |
@@ -198,10 +204,10 @@ static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count, | |||
198 | * This function takes ownership of the vmalloc'ed data and will free | 204 | * This function takes ownership of the vmalloc'ed data and will free |
199 | * it when it is no longer used. See dev_coredumpm() for more information. | 205 | * it when it is no longer used. See dev_coredumpm() for more information. |
200 | */ | 206 | */ |
201 | void dev_coredumpv(struct device *dev, const void *data, size_t datalen, | 207 | void dev_coredumpv(struct device *dev, void *data, size_t datalen, |
202 | gfp_t gfp) | 208 | gfp_t gfp) |
203 | { | 209 | { |
204 | dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, vfree); | 210 | dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, devcd_freev); |
205 | } | 211 | } |
206 | EXPORT_SYMBOL_GPL(dev_coredumpv); | 212 | EXPORT_SYMBOL_GPL(dev_coredumpv); |
207 | 213 | ||
@@ -213,6 +219,44 @@ static int devcd_match_failing(struct device *dev, const void *failing) | |||
213 | } | 219 | } |
214 | 220 | ||
215 | /** | 221 | /** |
222 | * devcd_free_sgtable - free all the memory of the given scatterlist table | ||
223 | * (i.e. both pages and scatterlist instances) | ||
224 | * NOTE: if two tables allocated with devcd_alloc_sgtable and then chained | ||
225 | * using the sg_chain function then that function should be called only once | ||
226 | * on the chained table | ||
227 | * @table: pointer to sg_table to free | ||
228 | */ | ||
229 | static void devcd_free_sgtable(void *data) | ||
230 | { | ||
231 | _devcd_free_sgtable(data); | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * devcd_read_from_table - copy data from sg_table to a given buffer | ||
236 | * and return the number of bytes read | ||
237 | * @buffer: the buffer to copy the data to it | ||
238 | * @buf_len: the length of the buffer | ||
239 | * @data: the scatterlist table to copy from | ||
240 | * @offset: start copy from @offset@ bytes from the head of the data | ||
241 | * in the given scatterlist | ||
242 | * @data_len: the length of the data in the sg_table | ||
243 | */ | ||
244 | static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset, | ||
245 | size_t buf_len, void *data, | ||
246 | size_t data_len) | ||
247 | { | ||
248 | struct scatterlist *table = data; | ||
249 | |||
250 | if (offset > data_len) | ||
251 | return -EINVAL; | ||
252 | |||
253 | if (offset + buf_len > data_len) | ||
254 | buf_len = data_len - offset; | ||
255 | return sg_pcopy_to_buffer(table, sg_nents(table), buffer, buf_len, | ||
256 | offset); | ||
257 | } | ||
258 | |||
259 | /** | ||
216 | * dev_coredumpm - create device coredump with read/free methods | 260 | * dev_coredumpm - create device coredump with read/free methods |
217 | * @dev: the struct device for the crashed device | 261 | * @dev: the struct device for the crashed device |
218 | * @owner: the module that contains the read/free functions, use %THIS_MODULE | 262 | * @owner: the module that contains the read/free functions, use %THIS_MODULE |
@@ -228,10 +272,10 @@ static int devcd_match_failing(struct device *dev, const void *failing) | |||
228 | * function will be called to free the data. | 272 | * function will be called to free the data. |
229 | */ | 273 | */ |
230 | void dev_coredumpm(struct device *dev, struct module *owner, | 274 | void dev_coredumpm(struct device *dev, struct module *owner, |
231 | const void *data, size_t datalen, gfp_t gfp, | 275 | void *data, size_t datalen, gfp_t gfp, |
232 | ssize_t (*read)(char *buffer, loff_t offset, size_t count, | 276 | ssize_t (*read)(char *buffer, loff_t offset, size_t count, |
233 | const void *data, size_t datalen), | 277 | void *data, size_t datalen), |
234 | void (*free)(const void *data)) | 278 | void (*free)(void *data)) |
235 | { | 279 | { |
236 | static atomic_t devcd_count = ATOMIC_INIT(0); | 280 | static atomic_t devcd_count = ATOMIC_INIT(0); |
237 | struct devcd_entry *devcd; | 281 | struct devcd_entry *devcd; |
@@ -291,6 +335,27 @@ void dev_coredumpm(struct device *dev, struct module *owner, | |||
291 | } | 335 | } |
292 | EXPORT_SYMBOL_GPL(dev_coredumpm); | 336 | EXPORT_SYMBOL_GPL(dev_coredumpm); |
293 | 337 | ||
338 | /** | ||
339 | * dev_coredumpmsg - create device coredump that uses scatterlist as data | ||
340 | * parameter | ||
341 | * @dev: the struct device for the crashed device | ||
342 | * @table: the dump data | ||
343 | * @datalen: length of the data | ||
344 | * @gfp: allocation flags | ||
345 | * | ||
346 | * Creates a new device coredump for the given device. If a previous one hasn't | ||
347 | * been read yet, the new coredump is discarded. The data lifetime is determined | ||
348 | * by the device coredump framework and when it is no longer needed | ||
349 | * it will free the data. | ||
350 | */ | ||
351 | void dev_coredumpsg(struct device *dev, struct scatterlist *table, | ||
352 | size_t datalen, gfp_t gfp) | ||
353 | { | ||
354 | dev_coredumpm(dev, NULL, table, datalen, gfp, devcd_read_from_sgtable, | ||
355 | devcd_free_sgtable); | ||
356 | } | ||
357 | EXPORT_SYMBOL_GPL(dev_coredumpsg); | ||
358 | |||
294 | static int __init devcoredump_init(void) | 359 | static int __init devcoredump_init(void) |
295 | { | 360 | { |
296 | return class_register(&devcd_class); | 361 | return class_register(&devcd_class); |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f437afa17f2b..6482d47deb50 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -322,16 +322,16 @@ EXPORT_SYMBOL_GPL(platform_device_add_data); | |||
322 | /** | 322 | /** |
323 | * platform_device_add_properties - add built-in properties to a platform device | 323 | * platform_device_add_properties - add built-in properties to a platform device |
324 | * @pdev: platform device to add properties to | 324 | * @pdev: platform device to add properties to |
325 | * @pset: properties to add | 325 | * @properties: null terminated array of properties to add |
326 | * | 326 | * |
327 | * The function will take deep copy of the properties in @pset and attach | 327 | * The function will take deep copy of @properties and attach the copy to the |
328 | * the copy to the platform device. The memory associated with properties | 328 | * platform device. The memory associated with properties will be freed when the |
329 | * will be freed when the platform device is released. | 329 | * platform device is released. |
330 | */ | 330 | */ |
331 | int platform_device_add_properties(struct platform_device *pdev, | 331 | int platform_device_add_properties(struct platform_device *pdev, |
332 | const struct property_set *pset) | 332 | struct property_entry *properties) |
333 | { | 333 | { |
334 | return device_add_property_set(&pdev->dev, pset); | 334 | return device_add_properties(&pdev->dev, properties); |
335 | } | 335 | } |
336 | EXPORT_SYMBOL_GPL(platform_device_add_properties); | 336 | EXPORT_SYMBOL_GPL(platform_device_add_properties); |
337 | 337 | ||
@@ -447,7 +447,7 @@ void platform_device_del(struct platform_device *pdev) | |||
447 | release_resource(r); | 447 | release_resource(r); |
448 | } | 448 | } |
449 | 449 | ||
450 | device_remove_property_set(&pdev->dev); | 450 | device_remove_properties(&pdev->dev); |
451 | } | 451 | } |
452 | } | 452 | } |
453 | EXPORT_SYMBOL_GPL(platform_device_del); | 453 | EXPORT_SYMBOL_GPL(platform_device_del); |
@@ -526,8 +526,9 @@ struct platform_device *platform_device_register_full( | |||
526 | if (ret) | 526 | if (ret) |
527 | goto err; | 527 | goto err; |
528 | 528 | ||
529 | if (pdevinfo->pset) { | 529 | if (pdevinfo->properties) { |
530 | ret = platform_device_add_properties(pdev, pdevinfo->pset); | 530 | ret = platform_device_add_properties(pdev, |
531 | pdevinfo->properties); | ||
531 | if (ret) | 532 | if (ret) |
532 | goto err; | 533 | goto err; |
533 | } | 534 | } |
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 0e64a1b5e62a..3657ac1cb801 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
@@ -159,7 +159,7 @@ int of_pm_clk_add_clks(struct device *dev) | |||
159 | 159 | ||
160 | count = of_count_phandle_with_args(dev->of_node, "clocks", | 160 | count = of_count_phandle_with_args(dev->of_node, "clocks", |
161 | "#clock-cells"); | 161 | "#clock-cells"); |
162 | if (count == 0) | 162 | if (count <= 0) |
163 | return -ENODEV; | 163 | return -ENODEV; |
164 | 164 | ||
165 | clks = kcalloc(count, sizeof(*clks), GFP_KERNEL); | 165 | clks = kcalloc(count, sizeof(*clks), GFP_KERNEL); |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 56705b52758e..de23b648fce3 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -229,17 +229,6 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth) | |||
229 | return ret; | 229 | return ret; |
230 | } | 230 | } |
231 | 231 | ||
232 | static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) | ||
233 | { | ||
234 | return GENPD_DEV_CALLBACK(genpd, int, save_state, dev); | ||
235 | } | ||
236 | |||
237 | static int genpd_restore_dev(struct generic_pm_domain *genpd, | ||
238 | struct device *dev) | ||
239 | { | ||
240 | return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev); | ||
241 | } | ||
242 | |||
243 | static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, | 232 | static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, |
244 | unsigned long val, void *ptr) | 233 | unsigned long val, void *ptr) |
245 | { | 234 | { |
@@ -372,17 +361,63 @@ static void genpd_power_off_work_fn(struct work_struct *work) | |||
372 | } | 361 | } |
373 | 362 | ||
374 | /** | 363 | /** |
375 | * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain. | 364 | * __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks |
365 | * @dev: Device to handle. | ||
366 | */ | ||
367 | static int __genpd_runtime_suspend(struct device *dev) | ||
368 | { | ||
369 | int (*cb)(struct device *__dev); | ||
370 | |||
371 | if (dev->type && dev->type->pm) | ||
372 | cb = dev->type->pm->runtime_suspend; | ||
373 | else if (dev->class && dev->class->pm) | ||
374 | cb = dev->class->pm->runtime_suspend; | ||
375 | else if (dev->bus && dev->bus->pm) | ||
376 | cb = dev->bus->pm->runtime_suspend; | ||
377 | else | ||
378 | cb = NULL; | ||
379 | |||
380 | if (!cb && dev->driver && dev->driver->pm) | ||
381 | cb = dev->driver->pm->runtime_suspend; | ||
382 | |||
383 | return cb ? cb(dev) : 0; | ||
384 | } | ||
385 | |||
386 | /** | ||
387 | * __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks | ||
388 | * @dev: Device to handle. | ||
389 | */ | ||
390 | static int __genpd_runtime_resume(struct device *dev) | ||
391 | { | ||
392 | int (*cb)(struct device *__dev); | ||
393 | |||
394 | if (dev->type && dev->type->pm) | ||
395 | cb = dev->type->pm->runtime_resume; | ||
396 | else if (dev->class && dev->class->pm) | ||
397 | cb = dev->class->pm->runtime_resume; | ||
398 | else if (dev->bus && dev->bus->pm) | ||
399 | cb = dev->bus->pm->runtime_resume; | ||
400 | else | ||
401 | cb = NULL; | ||
402 | |||
403 | if (!cb && dev->driver && dev->driver->pm) | ||
404 | cb = dev->driver->pm->runtime_resume; | ||
405 | |||
406 | return cb ? cb(dev) : 0; | ||
407 | } | ||
408 | |||
409 | /** | ||
410 | * genpd_runtime_suspend - Suspend a device belonging to I/O PM domain. | ||
376 | * @dev: Device to suspend. | 411 | * @dev: Device to suspend. |
377 | * | 412 | * |
378 | * Carry out a runtime suspend of a device under the assumption that its | 413 | * Carry out a runtime suspend of a device under the assumption that its |
379 | * pm_domain field points to the domain member of an object of type | 414 | * pm_domain field points to the domain member of an object of type |
380 | * struct generic_pm_domain representing a PM domain consisting of I/O devices. | 415 | * struct generic_pm_domain representing a PM domain consisting of I/O devices. |
381 | */ | 416 | */ |
382 | static int pm_genpd_runtime_suspend(struct device *dev) | 417 | static int genpd_runtime_suspend(struct device *dev) |
383 | { | 418 | { |
384 | struct generic_pm_domain *genpd; | 419 | struct generic_pm_domain *genpd; |
385 | bool (*stop_ok)(struct device *__dev); | 420 | bool (*suspend_ok)(struct device *__dev); |
386 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; | 421 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; |
387 | bool runtime_pm = pm_runtime_enabled(dev); | 422 | bool runtime_pm = pm_runtime_enabled(dev); |
388 | ktime_t time_start; | 423 | ktime_t time_start; |
@@ -401,21 +436,21 @@ static int pm_genpd_runtime_suspend(struct device *dev) | |||
401 | * runtime PM is disabled. Under these circumstances, we shall skip | 436 | * runtime PM is disabled. Under these circumstances, we shall skip |
402 | * validating/measuring the PM QoS latency. | 437 | * validating/measuring the PM QoS latency. |
403 | */ | 438 | */ |
404 | stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; | 439 | suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL; |
405 | if (runtime_pm && stop_ok && !stop_ok(dev)) | 440 | if (runtime_pm && suspend_ok && !suspend_ok(dev)) |
406 | return -EBUSY; | 441 | return -EBUSY; |
407 | 442 | ||
408 | /* Measure suspend latency. */ | 443 | /* Measure suspend latency. */ |
409 | if (runtime_pm) | 444 | if (runtime_pm) |
410 | time_start = ktime_get(); | 445 | time_start = ktime_get(); |
411 | 446 | ||
412 | ret = genpd_save_dev(genpd, dev); | 447 | ret = __genpd_runtime_suspend(dev); |
413 | if (ret) | 448 | if (ret) |
414 | return ret; | 449 | return ret; |
415 | 450 | ||
416 | ret = genpd_stop_dev(genpd, dev); | 451 | ret = genpd_stop_dev(genpd, dev); |
417 | if (ret) { | 452 | if (ret) { |
418 | genpd_restore_dev(genpd, dev); | 453 | __genpd_runtime_resume(dev); |
419 | return ret; | 454 | return ret; |
420 | } | 455 | } |
421 | 456 | ||
@@ -446,14 +481,14 @@ static int pm_genpd_runtime_suspend(struct device *dev) | |||
446 | } | 481 | } |
447 | 482 | ||
448 | /** | 483 | /** |
449 | * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain. | 484 | * genpd_runtime_resume - Resume a device belonging to I/O PM domain. |
450 | * @dev: Device to resume. | 485 | * @dev: Device to resume. |
451 | * | 486 | * |
452 | * Carry out a runtime resume of a device under the assumption that its | 487 | * Carry out a runtime resume of a device under the assumption that its |
453 | * pm_domain field points to the domain member of an object of type | 488 | * pm_domain field points to the domain member of an object of type |
454 | * struct generic_pm_domain representing a PM domain consisting of I/O devices. | 489 | * struct generic_pm_domain representing a PM domain consisting of I/O devices. |
455 | */ | 490 | */ |
456 | static int pm_genpd_runtime_resume(struct device *dev) | 491 | static int genpd_runtime_resume(struct device *dev) |
457 | { | 492 | { |
458 | struct generic_pm_domain *genpd; | 493 | struct generic_pm_domain *genpd; |
459 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; | 494 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; |
@@ -491,7 +526,7 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
491 | if (ret) | 526 | if (ret) |
492 | goto err_poweroff; | 527 | goto err_poweroff; |
493 | 528 | ||
494 | ret = genpd_restore_dev(genpd, dev); | 529 | ret = __genpd_runtime_resume(dev); |
495 | if (ret) | 530 | if (ret) |
496 | goto err_stop; | 531 | goto err_stop; |
497 | 532 | ||
@@ -695,15 +730,6 @@ static int pm_genpd_prepare(struct device *dev) | |||
695 | * at this point and a system wakeup event should be reported if it's | 730 | * at this point and a system wakeup event should be reported if it's |
696 | * set up to wake up the system from sleep states. | 731 | * set up to wake up the system from sleep states. |
697 | */ | 732 | */ |
698 | pm_runtime_get_noresume(dev); | ||
699 | if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) | ||
700 | pm_wakeup_event(dev, 0); | ||
701 | |||
702 | if (pm_wakeup_pending()) { | ||
703 | pm_runtime_put(dev); | ||
704 | return -EBUSY; | ||
705 | } | ||
706 | |||
707 | if (resume_needed(dev, genpd)) | 733 | if (resume_needed(dev, genpd)) |
708 | pm_runtime_resume(dev); | 734 | pm_runtime_resume(dev); |
709 | 735 | ||
@@ -716,10 +742,8 @@ static int pm_genpd_prepare(struct device *dev) | |||
716 | 742 | ||
717 | mutex_unlock(&genpd->lock); | 743 | mutex_unlock(&genpd->lock); |
718 | 744 | ||
719 | if (genpd->suspend_power_off) { | 745 | if (genpd->suspend_power_off) |
720 | pm_runtime_put_noidle(dev); | ||
721 | return 0; | 746 | return 0; |
722 | } | ||
723 | 747 | ||
724 | /* | 748 | /* |
725 | * The PM domain must be in the GPD_STATE_ACTIVE state at this point, | 749 | * The PM domain must be in the GPD_STATE_ACTIVE state at this point, |
@@ -741,7 +765,6 @@ static int pm_genpd_prepare(struct device *dev) | |||
741 | pm_runtime_enable(dev); | 765 | pm_runtime_enable(dev); |
742 | } | 766 | } |
743 | 767 | ||
744 | pm_runtime_put(dev); | ||
745 | return ret; | 768 | return ret; |
746 | } | 769 | } |
747 | 770 | ||
@@ -1427,54 +1450,6 @@ out: | |||
1427 | } | 1450 | } |
1428 | EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain); | 1451 | EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain); |
1429 | 1452 | ||
1430 | /* Default device callbacks for generic PM domains. */ | ||
1431 | |||
1432 | /** | ||
1433 | * pm_genpd_default_save_state - Default "save device state" for PM domains. | ||
1434 | * @dev: Device to handle. | ||
1435 | */ | ||
1436 | static int pm_genpd_default_save_state(struct device *dev) | ||
1437 | { | ||
1438 | int (*cb)(struct device *__dev); | ||
1439 | |||
1440 | if (dev->type && dev->type->pm) | ||
1441 | cb = dev->type->pm->runtime_suspend; | ||
1442 | else if (dev->class && dev->class->pm) | ||
1443 | cb = dev->class->pm->runtime_suspend; | ||
1444 | else if (dev->bus && dev->bus->pm) | ||
1445 | cb = dev->bus->pm->runtime_suspend; | ||
1446 | else | ||
1447 | cb = NULL; | ||
1448 | |||
1449 | if (!cb && dev->driver && dev->driver->pm) | ||
1450 | cb = dev->driver->pm->runtime_suspend; | ||
1451 | |||
1452 | return cb ? cb(dev) : 0; | ||
1453 | } | ||
1454 | |||
1455 | /** | ||
1456 | * pm_genpd_default_restore_state - Default PM domains "restore device state". | ||
1457 | * @dev: Device to handle. | ||
1458 | */ | ||
1459 | static int pm_genpd_default_restore_state(struct device *dev) | ||
1460 | { | ||
1461 | int (*cb)(struct device *__dev); | ||
1462 | |||
1463 | if (dev->type && dev->type->pm) | ||
1464 | cb = dev->type->pm->runtime_resume; | ||
1465 | else if (dev->class && dev->class->pm) | ||
1466 | cb = dev->class->pm->runtime_resume; | ||
1467 | else if (dev->bus && dev->bus->pm) | ||
1468 | cb = dev->bus->pm->runtime_resume; | ||
1469 | else | ||
1470 | cb = NULL; | ||
1471 | |||
1472 | if (!cb && dev->driver && dev->driver->pm) | ||
1473 | cb = dev->driver->pm->runtime_resume; | ||
1474 | |||
1475 | return cb ? cb(dev) : 0; | ||
1476 | } | ||
1477 | |||
1478 | /** | 1453 | /** |
1479 | * pm_genpd_init - Initialize a generic I/O PM domain object. | 1454 | * pm_genpd_init - Initialize a generic I/O PM domain object. |
1480 | * @genpd: PM domain object to initialize. | 1455 | * @genpd: PM domain object to initialize. |
@@ -1498,8 +1473,8 @@ void pm_genpd_init(struct generic_pm_domain *genpd, | |||
1498 | genpd->device_count = 0; | 1473 | genpd->device_count = 0; |
1499 | genpd->max_off_time_ns = -1; | 1474 | genpd->max_off_time_ns = -1; |
1500 | genpd->max_off_time_changed = true; | 1475 | genpd->max_off_time_changed = true; |
1501 | genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend; | 1476 | genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; |
1502 | genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume; | 1477 | genpd->domain.ops.runtime_resume = genpd_runtime_resume; |
1503 | genpd->domain.ops.prepare = pm_genpd_prepare; | 1478 | genpd->domain.ops.prepare = pm_genpd_prepare; |
1504 | genpd->domain.ops.suspend = pm_genpd_suspend; | 1479 | genpd->domain.ops.suspend = pm_genpd_suspend; |
1505 | genpd->domain.ops.suspend_late = pm_genpd_suspend_late; | 1480 | genpd->domain.ops.suspend_late = pm_genpd_suspend_late; |
@@ -1520,8 +1495,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd, | |||
1520 | genpd->domain.ops.restore_early = pm_genpd_resume_early; | 1495 | genpd->domain.ops.restore_early = pm_genpd_resume_early; |
1521 | genpd->domain.ops.restore = pm_genpd_resume; | 1496 | genpd->domain.ops.restore = pm_genpd_resume; |
1522 | genpd->domain.ops.complete = pm_genpd_complete; | 1497 | genpd->domain.ops.complete = pm_genpd_complete; |
1523 | genpd->dev_ops.save_state = pm_genpd_default_save_state; | ||
1524 | genpd->dev_ops.restore_state = pm_genpd_default_restore_state; | ||
1525 | 1498 | ||
1526 | if (genpd->flags & GENPD_FLAG_PM_CLK) { | 1499 | if (genpd->flags & GENPD_FLAG_PM_CLK) { |
1527 | genpd->dev_ops.stop = pm_clk_suspend; | 1500 | genpd->dev_ops.stop = pm_clk_suspend; |
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 00a5436dd44b..2e0fce711135 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c | |||
@@ -37,10 +37,10 @@ static int dev_update_qos_constraint(struct device *dev, void *data) | |||
37 | } | 37 | } |
38 | 38 | ||
39 | /** | 39 | /** |
40 | * default_stop_ok - Default PM domain governor routine for stopping devices. | 40 | * default_suspend_ok - Default PM domain governor routine to suspend devices. |
41 | * @dev: Device to check. | 41 | * @dev: Device to check. |
42 | */ | 42 | */ |
43 | static bool default_stop_ok(struct device *dev) | 43 | static bool default_suspend_ok(struct device *dev) |
44 | { | 44 | { |
45 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; | 45 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; |
46 | unsigned long flags; | 46 | unsigned long flags; |
@@ -51,13 +51,13 @@ static bool default_stop_ok(struct device *dev) | |||
51 | spin_lock_irqsave(&dev->power.lock, flags); | 51 | spin_lock_irqsave(&dev->power.lock, flags); |
52 | 52 | ||
53 | if (!td->constraint_changed) { | 53 | if (!td->constraint_changed) { |
54 | bool ret = td->cached_stop_ok; | 54 | bool ret = td->cached_suspend_ok; |
55 | 55 | ||
56 | spin_unlock_irqrestore(&dev->power.lock, flags); | 56 | spin_unlock_irqrestore(&dev->power.lock, flags); |
57 | return ret; | 57 | return ret; |
58 | } | 58 | } |
59 | td->constraint_changed = false; | 59 | td->constraint_changed = false; |
60 | td->cached_stop_ok = false; | 60 | td->cached_suspend_ok = false; |
61 | td->effective_constraint_ns = -1; | 61 | td->effective_constraint_ns = -1; |
62 | constraint_ns = __dev_pm_qos_read_value(dev); | 62 | constraint_ns = __dev_pm_qos_read_value(dev); |
63 | 63 | ||
@@ -83,13 +83,13 @@ static bool default_stop_ok(struct device *dev) | |||
83 | return false; | 83 | return false; |
84 | } | 84 | } |
85 | td->effective_constraint_ns = constraint_ns; | 85 | td->effective_constraint_ns = constraint_ns; |
86 | td->cached_stop_ok = constraint_ns >= 0; | 86 | td->cached_suspend_ok = constraint_ns >= 0; |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * The children have been suspended already, so we don't need to take | 89 | * The children have been suspended already, so we don't need to take |
90 | * their stop latencies into account here. | 90 | * their suspend latencies into account here. |
91 | */ | 91 | */ |
92 | return td->cached_stop_ok; | 92 | return td->cached_suspend_ok; |
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
@@ -150,7 +150,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, | |||
150 | */ | 150 | */ |
151 | td = &to_gpd_data(pdd)->td; | 151 | td = &to_gpd_data(pdd)->td; |
152 | constraint_ns = td->effective_constraint_ns; | 152 | constraint_ns = td->effective_constraint_ns; |
153 | /* default_stop_ok() need not be called before us. */ | 153 | /* default_suspend_ok() need not be called before us. */ |
154 | if (constraint_ns < 0) { | 154 | if (constraint_ns < 0) { |
155 | constraint_ns = dev_pm_qos_read_value(pdd->dev); | 155 | constraint_ns = dev_pm_qos_read_value(pdd->dev); |
156 | constraint_ns *= NSEC_PER_USEC; | 156 | constraint_ns *= NSEC_PER_USEC; |
@@ -227,7 +227,7 @@ static bool always_on_power_down_ok(struct dev_pm_domain *domain) | |||
227 | } | 227 | } |
228 | 228 | ||
229 | struct dev_power_governor simple_qos_governor = { | 229 | struct dev_power_governor simple_qos_governor = { |
230 | .stop_ok = default_stop_ok, | 230 | .suspend_ok = default_suspend_ok, |
231 | .power_down_ok = default_power_down_ok, | 231 | .power_down_ok = default_power_down_ok, |
232 | }; | 232 | }; |
233 | 233 | ||
@@ -236,5 +236,5 @@ struct dev_power_governor simple_qos_governor = { | |||
236 | */ | 236 | */ |
237 | struct dev_power_governor pm_domain_always_on_gov = { | 237 | struct dev_power_governor pm_domain_always_on_gov = { |
238 | .power_down_ok = always_on_power_down_ok, | 238 | .power_down_ok = always_on_power_down_ok, |
239 | .stop_ok = default_stop_ok, | 239 | .suspend_ok = default_suspend_ok, |
240 | }; | 240 | }; |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 6e7c3ccea24b..e44944f4be77 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -1267,14 +1267,15 @@ int dpm_suspend_late(pm_message_t state) | |||
1267 | error = device_suspend_late(dev); | 1267 | error = device_suspend_late(dev); |
1268 | 1268 | ||
1269 | mutex_lock(&dpm_list_mtx); | 1269 | mutex_lock(&dpm_list_mtx); |
1270 | if (!list_empty(&dev->power.entry)) | ||
1271 | list_move(&dev->power.entry, &dpm_late_early_list); | ||
1272 | |||
1270 | if (error) { | 1273 | if (error) { |
1271 | pm_dev_err(dev, state, " late", error); | 1274 | pm_dev_err(dev, state, " late", error); |
1272 | dpm_save_failed_dev(dev_name(dev)); | 1275 | dpm_save_failed_dev(dev_name(dev)); |
1273 | put_device(dev); | 1276 | put_device(dev); |
1274 | break; | 1277 | break; |
1275 | } | 1278 | } |
1276 | if (!list_empty(&dev->power.entry)) | ||
1277 | list_move(&dev->power.entry, &dpm_late_early_list); | ||
1278 | put_device(dev); | 1279 | put_device(dev); |
1279 | 1280 | ||
1280 | if (async_error) | 1281 | if (async_error) |
@@ -1556,7 +1557,6 @@ int dpm_suspend(pm_message_t state) | |||
1556 | static int device_prepare(struct device *dev, pm_message_t state) | 1557 | static int device_prepare(struct device *dev, pm_message_t state) |
1557 | { | 1558 | { |
1558 | int (*callback)(struct device *) = NULL; | 1559 | int (*callback)(struct device *) = NULL; |
1559 | char *info = NULL; | ||
1560 | int ret = 0; | 1560 | int ret = 0; |
1561 | 1561 | ||
1562 | if (dev->power.syscore) | 1562 | if (dev->power.syscore) |
@@ -1579,24 +1579,17 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
1579 | goto unlock; | 1579 | goto unlock; |
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | if (dev->pm_domain) { | 1582 | if (dev->pm_domain) |
1583 | info = "preparing power domain "; | ||
1584 | callback = dev->pm_domain->ops.prepare; | 1583 | callback = dev->pm_domain->ops.prepare; |
1585 | } else if (dev->type && dev->type->pm) { | 1584 | else if (dev->type && dev->type->pm) |
1586 | info = "preparing type "; | ||
1587 | callback = dev->type->pm->prepare; | 1585 | callback = dev->type->pm->prepare; |
1588 | } else if (dev->class && dev->class->pm) { | 1586 | else if (dev->class && dev->class->pm) |
1589 | info = "preparing class "; | ||
1590 | callback = dev->class->pm->prepare; | 1587 | callback = dev->class->pm->prepare; |
1591 | } else if (dev->bus && dev->bus->pm) { | 1588 | else if (dev->bus && dev->bus->pm) |
1592 | info = "preparing bus "; | ||
1593 | callback = dev->bus->pm->prepare; | 1589 | callback = dev->bus->pm->prepare; |
1594 | } | ||
1595 | 1590 | ||
1596 | if (!callback && dev->driver && dev->driver->pm) { | 1591 | if (!callback && dev->driver && dev->driver->pm) |
1597 | info = "preparing driver "; | ||
1598 | callback = dev->driver->pm->prepare; | 1592 | callback = dev->driver->pm->prepare; |
1599 | } | ||
1600 | 1593 | ||
1601 | if (callback) | 1594 | if (callback) |
1602 | ret = callback(dev); | 1595 | ret = callback(dev); |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 4c7055009bd6..b74690418504 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -1506,11 +1506,16 @@ int pm_runtime_force_resume(struct device *dev) | |||
1506 | goto out; | 1506 | goto out; |
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | ret = callback(dev); | 1509 | ret = pm_runtime_set_active(dev); |
1510 | if (ret) | 1510 | if (ret) |
1511 | goto out; | 1511 | goto out; |
1512 | 1512 | ||
1513 | pm_runtime_set_active(dev); | 1513 | ret = callback(dev); |
1514 | if (ret) { | ||
1515 | pm_runtime_set_suspended(dev); | ||
1516 | goto out; | ||
1517 | } | ||
1518 | |||
1514 | pm_runtime_mark_last_busy(dev); | 1519 | pm_runtime_mark_last_busy(dev); |
1515 | out: | 1520 | out: |
1516 | pm_runtime_enable(dev); | 1521 | pm_runtime_enable(dev); |
diff --git a/drivers/base/property.c b/drivers/base/property.c index 9b1a65debd49..f38c21de29b7 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c | |||
@@ -19,9 +19,14 @@ | |||
19 | #include <linux/etherdevice.h> | 19 | #include <linux/etherdevice.h> |
20 | #include <linux/phy.h> | 20 | #include <linux/phy.h> |
21 | 21 | ||
22 | struct property_set { | ||
23 | struct fwnode_handle fwnode; | ||
24 | struct property_entry *properties; | ||
25 | }; | ||
26 | |||
22 | static inline bool is_pset_node(struct fwnode_handle *fwnode) | 27 | static inline bool is_pset_node(struct fwnode_handle *fwnode) |
23 | { | 28 | { |
24 | return fwnode && fwnode->type == FWNODE_PDATA; | 29 | return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA; |
25 | } | 30 | } |
26 | 31 | ||
27 | static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode) | 32 | static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode) |
@@ -801,14 +806,14 @@ static struct property_set *pset_copy_set(const struct property_set *pset) | |||
801 | } | 806 | } |
802 | 807 | ||
803 | /** | 808 | /** |
804 | * device_remove_property_set - Remove properties from a device object. | 809 | * device_remove_properties - Remove properties from a device object. |
805 | * @dev: Device whose properties to remove. | 810 | * @dev: Device whose properties to remove. |
806 | * | 811 | * |
807 | * The function removes properties previously associated to the device | 812 | * The function removes properties previously associated to the device |
808 | * secondary firmware node with device_add_property_set(). Memory allocated | 813 | * secondary firmware node with device_add_properties(). Memory allocated |
809 | * to the properties will also be released. | 814 | * to the properties will also be released. |
810 | */ | 815 | */ |
811 | void device_remove_property_set(struct device *dev) | 816 | void device_remove_properties(struct device *dev) |
812 | { | 817 | { |
813 | struct fwnode_handle *fwnode; | 818 | struct fwnode_handle *fwnode; |
814 | 819 | ||
@@ -831,24 +836,27 @@ void device_remove_property_set(struct device *dev) | |||
831 | } | 836 | } |
832 | } | 837 | } |
833 | } | 838 | } |
834 | EXPORT_SYMBOL_GPL(device_remove_property_set); | 839 | EXPORT_SYMBOL_GPL(device_remove_properties); |
835 | 840 | ||
836 | /** | 841 | /** |
837 | * device_add_property_set - Add a collection of properties to a device object. | 842 | * device_add_properties - Add a collection of properties to a device object. |
838 | * @dev: Device to add properties to. | 843 | * @dev: Device to add properties to. |
839 | * @pset: Collection of properties to add. | 844 | * @properties: Collection of properties to add. |
840 | * | 845 | * |
841 | * Associate a collection of device properties represented by @pset with @dev | 846 | * Associate a collection of device properties represented by @properties with |
842 | * as its secondary firmware node. The function takes a copy of @pset. | 847 | * @dev as its secondary firmware node. The function takes a copy of |
848 | * @properties. | ||
843 | */ | 849 | */ |
844 | int device_add_property_set(struct device *dev, const struct property_set *pset) | 850 | int device_add_properties(struct device *dev, struct property_entry *properties) |
845 | { | 851 | { |
846 | struct property_set *p; | 852 | struct property_set *p, pset; |
847 | 853 | ||
848 | if (!pset) | 854 | if (!properties) |
849 | return -EINVAL; | 855 | return -EINVAL; |
850 | 856 | ||
851 | p = pset_copy_set(pset); | 857 | pset.properties = properties; |
858 | |||
859 | p = pset_copy_set(&pset); | ||
852 | if (IS_ERR(p)) | 860 | if (IS_ERR(p)) |
853 | return PTR_ERR(p); | 861 | return PTR_ERR(p); |
854 | 862 | ||
@@ -856,7 +864,7 @@ int device_add_property_set(struct device *dev, const struct property_set *pset) | |||
856 | set_secondary_fwnode(dev, &p->fwnode); | 864 | set_secondary_fwnode(dev, &p->fwnode); |
857 | return 0; | 865 | return 0; |
858 | } | 866 | } |
859 | EXPORT_SYMBOL_GPL(device_add_property_set); | 867 | EXPORT_SYMBOL_GPL(device_add_properties); |
860 | 868 | ||
861 | /** | 869 | /** |
862 | * device_get_next_child_node - Return the next child node handle for a device | 870 | * device_get_next_child_node - Return the next child node handle for a device |
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 5c79526245c2..a0380338946a 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #ifndef _REGMAP_INTERNAL_H | 13 | #ifndef _REGMAP_INTERNAL_H |
14 | #define _REGMAP_INTERNAL_H | 14 | #define _REGMAP_INTERNAL_H |
15 | 15 | ||
16 | #include <linux/device.h> | ||
16 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
17 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
18 | #include <linux/list.h> | 19 | #include <linux/list.h> |
diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c index 3ee72550b1e3..4d2e50bfc726 100644 --- a/drivers/base/regmap/regcache-flat.c +++ b/drivers/base/regmap/regcache-flat.c | |||
@@ -27,7 +27,7 @@ static int regcache_flat_init(struct regmap *map) | |||
27 | int i; | 27 | int i; |
28 | unsigned int *cache; | 28 | unsigned int *cache; |
29 | 29 | ||
30 | if (!map || map->reg_stride_order < 0) | 30 | if (!map || map->reg_stride_order < 0 || !map->max_register) |
31 | return -EINVAL; | 31 | return -EINVAL; |
32 | 32 | ||
33 | map->cache = kcalloc(regcache_flat_get_index(map, map->max_register) | 33 | map->cache = kcalloc(regcache_flat_get_index(map, map->max_register) |
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 4170b7d95276..df7ff7290821 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -529,7 +529,7 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty); | |||
529 | * regcache_cache_bypass: Put a register map into cache bypass mode | 529 | * regcache_cache_bypass: Put a register map into cache bypass mode |
530 | * | 530 | * |
531 | * @map: map to configure | 531 | * @map: map to configure |
532 | * @cache_bypass: flag if changes should not be written to the hardware | 532 | * @cache_bypass: flag if changes should not be written to the cache |
533 | * | 533 | * |
534 | * When a register map is marked with the cache bypass option, writes | 534 | * When a register map is marked with the cache bypass option, writes |
535 | * to the register map API will only update the hardware and not the | 535 | * to the register map API will only update the hardware and not the |
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index 7526906ca080..5189fd6182f6 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | #include "internal.h" | ||
27 | |||
26 | struct regmap_mmio_context { | 28 | struct regmap_mmio_context { |
27 | void __iomem *regs; | 29 | void __iomem *regs; |
28 | unsigned val_bytes; | 30 | unsigned val_bytes; |
@@ -212,6 +214,7 @@ static const struct regmap_bus regmap_mmio = { | |||
212 | .reg_write = regmap_mmio_write, | 214 | .reg_write = regmap_mmio_write, |
213 | .reg_read = regmap_mmio_read, | 215 | .reg_read = regmap_mmio_read, |
214 | .free_context = regmap_mmio_free_context, | 216 | .free_context = regmap_mmio_free_context, |
217 | .val_format_endian_default = REGMAP_ENDIAN_LITTLE, | ||
215 | }; | 218 | }; |
216 | 219 | ||
217 | static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, | 220 | static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, |
@@ -245,7 +248,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, | |||
245 | ctx->val_bytes = config->val_bits / 8; | 248 | ctx->val_bytes = config->val_bits / 8; |
246 | ctx->clk = ERR_PTR(-ENODEV); | 249 | ctx->clk = ERR_PTR(-ENODEV); |
247 | 250 | ||
248 | switch (config->reg_format_endian) { | 251 | switch (regmap_get_val_endian(dev, ®map_mmio, config)) { |
249 | case REGMAP_ENDIAN_DEFAULT: | 252 | case REGMAP_ENDIAN_DEFAULT: |
250 | case REGMAP_ENDIAN_LITTLE: | 253 | case REGMAP_ENDIAN_LITTLE: |
251 | #ifdef __LITTLE_ENDIAN | 254 | #ifdef __LITTLE_ENDIAN |
diff --git a/drivers/base/regmap/regmap-spmi.c b/drivers/base/regmap/regmap-spmi.c index 7e58f6560399..4a36e415e938 100644 --- a/drivers/base/regmap/regmap-spmi.c +++ b/drivers/base/regmap/regmap-spmi.c | |||
@@ -142,7 +142,7 @@ static int regmap_spmi_ext_read(void *context, | |||
142 | while (val_size) { | 142 | while (val_size) { |
143 | len = min_t(size_t, val_size, 8); | 143 | len = min_t(size_t, val_size, 8); |
144 | 144 | ||
145 | err = spmi_ext_register_readl(context, addr, val, val_size); | 145 | err = spmi_ext_register_readl(context, addr, val, len); |
146 | if (err) | 146 | if (err) |
147 | goto err_out; | 147 | goto err_out; |
148 | 148 | ||