From e65b5ddba84634f31d42dfd86013f4c6be5e9e32 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 27 Sep 2014 21:56:08 +0200 Subject: [PATCH 1/4] cpufreq: pcc-cpufreq: Fix wait_event() under spinlock Fix the following bug introduced by commit 8fec051eea73 (cpufreq: Convert existing drivers to use cpufreq_freq_transition_{begin|end}) that forgot to move the spin_lock() in pcc_cpufreq_target() past cpufreq_freq_transition_begin() which calls wait_event(): BUG: sleeping function called from invalid context at drivers/cpufreq/cpufreq.c:370 in_atomic(): 1, irqs_disabled(): 0, pid: 2636, name: modprobe Preemption disabled at:[] pcc_cpufreq_target+0x27/0x200 [pcc_cpufreq] [ 51.025044] CPU: 57 PID: 2636 Comm: modprobe Tainted: G E 3.17.0-default #7 Hardware name: Hewlett-Packard ProLiant DL980 G7, BIOS P66 07/07/2010 00000000ffffffff ffff88026c46b828 ffffffff81589dbd 0000000000000000 ffff880037978090 ffff88026c46b848 ffffffff8108e1df ffff880037978090 0000000000000000 ffff88026c46b878 ffffffff8108e298 ffff88026d73ec00 Call Trace: [] dump_stack+0x4d/0x90 [] ___might_sleep+0x10f/0x180 [] __might_sleep+0x48/0xd0 [] cpufreq_freq_transition_begin+0x75/0x140 drivers/cpufreq/cpufreq.c:370 wait_event(policy->transition_wait, !policy->transition_ongoing); [] ? preempt_count_add+0xb9/0xc0 [] pcc_cpufreq_target+0x63/0x200 [pcc_cpufreq] drivers/cpufreq/pcc-cpufreq.c:207 spin_lock(&pcc_lock); [] ? update_ts_time_stats+0x7f/0xb0 [] __cpufreq_driver_target+0x85/0x170 [] od_check_cpu+0xa8/0xb0 [] dbs_check_cpu+0x180/0x1d0 [] cpufreq_governor_dbs+0x3b0/0x720 [] od_cpufreq_governor_dbs+0x33/0xe0 [] __cpufreq_governor+0xa9/0x210 [] cpufreq_set_policy+0x1e2/0x2e0 [] cpufreq_init_policy+0x8c/0x110 [] ? cpufreq_update_policy+0x1b0/0x1b0 [] ? preempt_count_sub+0xb9/0x100 [] __cpufreq_add_dev+0x596/0x6b0 [] ? pcc_cpufreq_probe+0x4b4/0x4b4 [pcc_cpufreq] [] cpufreq_add_dev+0xe/0x10 [] subsys_interface_register+0xc1/0xf0 [] ? preempt_count_sub+0xb9/0x100 [] cpufreq_register_driver+0x117/0x2a0 [] pcc_cpufreq_init+0x55/0x9f8 [pcc_cpufreq] [] ? pcc_cpufreq_probe+0x4b4/0x4b4 [pcc_cpufreq] [] do_one_initcall+0xc8/0x1f0 [] ? __vunmap+0x9d/0x100 [] do_init_module+0x30/0x1b0 [] load_module+0x686/0x710 [] ? do_init_module+0x1b0/0x1b0 [] SyS_init_module+0x9b/0xc0 [] system_call_fastpath+0x16/0x1b Fixes: 8fec051eea73 (cpufreq: Convert existing drivers to use cpufreq_freq_transition_{begin|end}) Reported-and-tested-by: Mike Galbraith Cc: 3.15+ # 3.15+ Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/pcc-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 728a2d879499..4d2c8e861089 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -204,7 +204,6 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy, u32 input_buffer; int cpu; - spin_lock(&pcc_lock); cpu = policy->cpu; pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); @@ -216,6 +215,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy, freqs.old = policy->cur; freqs.new = target_freq; cpufreq_freq_transition_begin(policy, &freqs); + spin_lock(&pcc_lock); input_buffer = 0x1 | (((target_freq * 100) / (ioread32(&pcch_hdr->nominal) * 1000)) << 8); From d62dbf77f7dfaa6fb455b4b9828069a11965929c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 26 Sep 2014 22:19:12 +0200 Subject: [PATCH 2/4] cpufreq: integrator: fix integrator_cpufreq_remove return type When building this driver as a module, we get a helpful warning about the return type: drivers/cpufreq/integrator-cpufreq.c:232:2: warning: initialization from incompatible pointer type .remove = __exit_p(integrator_cpufreq_remove), If the remove callback returns void, the caller gets an undefined value as it expects an integer to be returned. This fixes the problem by passing down the value from cpufreq_unregister_driver. Signed-off-by: Arnd Bergmann Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/integrator-cpufreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index c1320528b9d0..6bd69adc3c5e 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c @@ -213,9 +213,9 @@ static int __init integrator_cpufreq_probe(struct platform_device *pdev) return cpufreq_register_driver(&integrator_driver); } -static void __exit integrator_cpufreq_remove(struct platform_device *pdev) +static int __exit integrator_cpufreq_remove(struct platform_device *pdev) { - cpufreq_unregister_driver(&integrator_driver); + return cpufreq_unregister_driver(&integrator_driver); } static const struct of_device_id integrator_cpufreq_match[] = { From 77076c7aac0184cae2d8a358cf6e6ed1f195fe3f Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Fri, 26 Sep 2014 10:30:08 +0800 Subject: [PATCH 3/4] ACPI / i915: Update the condition to ignore firmware backlight change request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of the Thinkpads' firmware will issue a backlight change request through i915 operation region unconditionally on AC plug/unplug, the backlight level used is arbitrary and thus should be ignored. This is handled by commit 0b9f7d93ca61 (ACPI / i915: ignore firmware requests for backlight change). Then there is a Dell laptop whose vendor backlight interface also makes use of operation region to change backlight level and with the above commit, that interface no long works. The condition used to ignore the backlight change request from firmware is thus changed to: if the vendor backlight interface is not in use and the ACPI backlight interface is broken, we ignore the requests; oterwise, we keep processing them. Fixes: 0b9f7d93ca61 (ACPI / i915: ignore firmware requests for backlight change) Link: https://lkml.org/lkml/2014/9/23/854 Reported-and-tested-by: Pali Rohár Cc: 3.16+ # 3.16+ Signed-off-by: Aaron Lu Acked-by: Daniel Vetter Signed-off-by: Rafael J. Wysocki --- drivers/gpu/drm/i915/intel_opregion.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index ca52ad2ae7d1..d8de1d5140a7 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -396,6 +396,16 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state) return -EINVAL; } +/* + * If the vendor backlight interface is not in use and ACPI backlight interface + * is broken, do not bother processing backlight change requests from firmware. + */ +static bool should_ignore_backlight_request(void) +{ + return acpi_video_backlight_support() && + !acpi_video_verify_backlight_support(); +} + static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -404,11 +414,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); - /* - * If the acpi_video interface is not supposed to be used, don't - * bother processing backlight level change requests from firmware. - */ - if (!acpi_video_verify_backlight_support()) { + if (should_ignore_backlight_request()) { DRM_DEBUG_KMS("opregion backlight request ignored\n"); return 0; } From b1b12babe3b72cfb08b875245e5a5d7c2747c772 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 30 Sep 2014 09:33:17 +0530 Subject: [PATCH 4/4] cpufreq: update 'cpufreq_suspended' after stopping governors Commit 8e30444e1530 ("cpufreq: fix cpufreq suspend/resume for intel_pstate") introduced a bug where the governors wouldn't be stopped anymore for ->target{_index}() drivers during suspend. This happens because 'cpufreq_suspended' is updated before stopping the governors during suspend and due to this __cpufreq_governor() would return early due to this check: /* Don't start any governor operations if we are entering suspend */ if (cpufreq_suspended) return 0; Fixes: 8e30444e1530 ("cpufreq: fix cpufreq suspend/resume for intel_pstate") Cc: 3.15+ # 3.15+: 8e30444e1530 "cpufreq: fix cpufreq suspend/resume for intel_pstate" Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 6e93e7f98358..61190f6b4829 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1658,10 +1658,8 @@ void cpufreq_suspend(void) if (!cpufreq_driver) return; - cpufreq_suspended = true; - if (!has_target()) - return; + goto suspend; pr_debug("%s: Suspending Governors\n", __func__); @@ -1674,6 +1672,9 @@ void cpufreq_suspend(void) pr_err("%s: Failed to suspend driver: %p\n", __func__, policy); } + +suspend: + cpufreq_suspended = true; } /**