diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /drivers/base | |
parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/memory.c | 4 | ||||
-rw-r--r-- | drivers/base/power/domain.c | 36 | ||||
-rw-r--r-- | drivers/base/power/domain_governor.c | 3 |
3 files changed, 27 insertions, 16 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 2804aed3f416..25425d3f2575 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -303,6 +303,10 @@ static int memory_subsys_offline(struct device *dev) | |||
303 | if (mem->state == MEM_OFFLINE) | 303 | if (mem->state == MEM_OFFLINE) |
304 | return 0; | 304 | return 0; |
305 | 305 | ||
306 | /* Can't offline block with non-present sections */ | ||
307 | if (mem->section_count != sections_per_block) | ||
308 | return -EINVAL; | ||
309 | |||
306 | return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); | 310 | return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); |
307 | } | 311 | } |
308 | 312 | ||
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index e03b1ad25a90..65f50eccd49b 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -390,6 +390,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) | |||
390 | struct generic_pm_domain *genpd; | 390 | struct generic_pm_domain *genpd; |
391 | bool (*stop_ok)(struct device *__dev); | 391 | bool (*stop_ok)(struct device *__dev); |
392 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; | 392 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; |
393 | bool runtime_pm = pm_runtime_enabled(dev); | ||
393 | ktime_t time_start; | 394 | ktime_t time_start; |
394 | s64 elapsed_ns; | 395 | s64 elapsed_ns; |
395 | int ret; | 396 | int ret; |
@@ -400,12 +401,19 @@ static int pm_genpd_runtime_suspend(struct device *dev) | |||
400 | if (IS_ERR(genpd)) | 401 | if (IS_ERR(genpd)) |
401 | return -EINVAL; | 402 | return -EINVAL; |
402 | 403 | ||
404 | /* | ||
405 | * A runtime PM centric subsystem/driver may re-use the runtime PM | ||
406 | * callbacks for other purposes than runtime PM. In those scenarios | ||
407 | * runtime PM is disabled. Under these circumstances, we shall skip | ||
408 | * validating/measuring the PM QoS latency. | ||
409 | */ | ||
403 | stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; | 410 | stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; |
404 | if (stop_ok && !stop_ok(dev)) | 411 | if (runtime_pm && stop_ok && !stop_ok(dev)) |
405 | return -EBUSY; | 412 | return -EBUSY; |
406 | 413 | ||
407 | /* Measure suspend latency. */ | 414 | /* Measure suspend latency. */ |
408 | time_start = ktime_get(); | 415 | if (runtime_pm) |
416 | time_start = ktime_get(); | ||
409 | 417 | ||
410 | ret = genpd_save_dev(genpd, dev); | 418 | ret = genpd_save_dev(genpd, dev); |
411 | if (ret) | 419 | if (ret) |
@@ -418,13 +426,15 @@ static int pm_genpd_runtime_suspend(struct device *dev) | |||
418 | } | 426 | } |
419 | 427 | ||
420 | /* Update suspend latency value if the measured time exceeds it. */ | 428 | /* Update suspend latency value if the measured time exceeds it. */ |
421 | elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); | 429 | if (runtime_pm) { |
422 | if (elapsed_ns > td->suspend_latency_ns) { | 430 | elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); |
423 | td->suspend_latency_ns = elapsed_ns; | 431 | if (elapsed_ns > td->suspend_latency_ns) { |
424 | dev_dbg(dev, "suspend latency exceeded, %lld ns\n", | 432 | td->suspend_latency_ns = elapsed_ns; |
425 | elapsed_ns); | 433 | dev_dbg(dev, "suspend latency exceeded, %lld ns\n", |
426 | genpd->max_off_time_changed = true; | 434 | elapsed_ns); |
427 | td->constraint_changed = true; | 435 | genpd->max_off_time_changed = true; |
436 | td->constraint_changed = true; | ||
437 | } | ||
428 | } | 438 | } |
429 | 439 | ||
430 | /* | 440 | /* |
@@ -453,6 +463,7 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
453 | { | 463 | { |
454 | struct generic_pm_domain *genpd; | 464 | struct generic_pm_domain *genpd; |
455 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; | 465 | struct gpd_timing_data *td = &dev_gpd_data(dev)->td; |
466 | bool runtime_pm = pm_runtime_enabled(dev); | ||
456 | ktime_t time_start; | 467 | ktime_t time_start; |
457 | s64 elapsed_ns; | 468 | s64 elapsed_ns; |
458 | int ret; | 469 | int ret; |
@@ -479,14 +490,14 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
479 | 490 | ||
480 | out: | 491 | out: |
481 | /* Measure resume latency. */ | 492 | /* Measure resume latency. */ |
482 | if (timed) | 493 | if (timed && runtime_pm) |
483 | time_start = ktime_get(); | 494 | time_start = ktime_get(); |
484 | 495 | ||
485 | genpd_start_dev(genpd, dev); | 496 | genpd_start_dev(genpd, dev); |
486 | genpd_restore_dev(genpd, dev); | 497 | genpd_restore_dev(genpd, dev); |
487 | 498 | ||
488 | /* Update resume latency value if the measured time exceeds it. */ | 499 | /* Update resume latency value if the measured time exceeds it. */ |
489 | if (timed) { | 500 | if (timed && runtime_pm) { |
490 | elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); | 501 | elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); |
491 | if (elapsed_ns > td->resume_latency_ns) { | 502 | if (elapsed_ns > td->resume_latency_ns) { |
492 | td->resume_latency_ns = elapsed_ns; | 503 | td->resume_latency_ns = elapsed_ns; |
@@ -1775,10 +1786,10 @@ int genpd_dev_pm_attach(struct device *dev) | |||
1775 | } | 1786 | } |
1776 | 1787 | ||
1777 | pd = of_genpd_get_from_provider(&pd_args); | 1788 | pd = of_genpd_get_from_provider(&pd_args); |
1789 | of_node_put(pd_args.np); | ||
1778 | if (IS_ERR(pd)) { | 1790 | if (IS_ERR(pd)) { |
1779 | dev_dbg(dev, "%s() failed to find PM domain: %ld\n", | 1791 | dev_dbg(dev, "%s() failed to find PM domain: %ld\n", |
1780 | __func__, PTR_ERR(pd)); | 1792 | __func__, PTR_ERR(pd)); |
1781 | of_node_put(dev->of_node); | ||
1782 | return -EPROBE_DEFER; | 1793 | return -EPROBE_DEFER; |
1783 | } | 1794 | } |
1784 | 1795 | ||
@@ -1796,7 +1807,6 @@ int genpd_dev_pm_attach(struct device *dev) | |||
1796 | if (ret < 0) { | 1807 | if (ret < 0) { |
1797 | dev_err(dev, "failed to add to PM domain %s: %d", | 1808 | dev_err(dev, "failed to add to PM domain %s: %d", |
1798 | pd->name, ret); | 1809 | pd->name, ret); |
1799 | of_node_put(dev->of_node); | ||
1800 | goto out; | 1810 | goto out; |
1801 | } | 1811 | } |
1802 | 1812 | ||
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index e60dd12e23aa..1e937ac5f456 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c | |||
@@ -160,9 +160,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) | |||
160 | struct gpd_timing_data *td; | 160 | struct gpd_timing_data *td; |
161 | s64 constraint_ns; | 161 | s64 constraint_ns; |
162 | 162 | ||
163 | if (!pdd->dev->driver) | ||
164 | continue; | ||
165 | |||
166 | /* | 163 | /* |
167 | * Check if the device is allowed to be off long enough for the | 164 | * Check if the device is allowed to be off long enough for the |
168 | * domain to turn off and on (that's how much time it will | 165 | * domain to turn off and on (that's how much time it will |