From 266c13d767be61a17d8e6f2310b9b7c46278273b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 2 Jul 2013 16:36:28 +0530 Subject: cpufreq: Fix serialization of frequency transitions Commit 7c30ed ("cpufreq: make sure frequency transitions are serialized") interacts poorly with systems that have a single core freqency for all cores. On such systems we have a single policy for all cores with several CPUs. When we do a frequency transition the governor calls the pre and post change notifiers which causes cpufreq_notify_transition() per CPU. Since the policy is the same for all of them all CPUs after the first and the warnings added are generated by checking a per-policy flag the warnings will be triggered for all cores after the first. Fix this by allowing notifier to be called for n times. Where n is the number of cpus in policy->cpus. Reported-and-tested-by: Mark Brown Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 6a015ada5285..0937b8d6c2a4 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -312,11 +312,12 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, switch (state) { case CPUFREQ_PRECHANGE: - if (WARN(policy->transition_ongoing, + if (WARN(policy->transition_ongoing == + cpumask_weight(policy->cpus), "In middle of another frequency transition\n")) return; - policy->transition_ongoing = true; + policy->transition_ongoing++; /* detect if the driver reported a value as "old frequency" * which is not equal to what the cpufreq core thinks is @@ -341,7 +342,7 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, "No frequency transition in progress\n")) return; - policy->transition_ongoing = false; + policy->transition_ongoing--; adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, -- cgit v1.2.3-59-g8ed1b From 91bdad0b6237c25a7bf8fd4604d0cc64a2005a23 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 4 Jul 2013 13:22:11 +0200 Subject: ACPI / PM: Fix corner case in acpi_bus_update_power() The role of acpi_bus_update_power() is to update the given ACPI device object's power.state field to reflect the current physical state of the device (as inferred from the configuration of power resources and _PSC, if available). For this purpose it calls acpi_device_set_power() that should update the power resources' reference counters and set power.state as appropriate. However, that doesn't work if the "new" state is D1, D2 or D3hot and the the current value of power.state means D3cold, because in that case acpi_device_set_power() will refuse to transition the device from D3cold to non-D0. To address this problem, make acpi_bus_update_power() call acpi_power_transition() directly to update the power resources' reference counters and only use acpi_device_set_power() to put the device into D0 if the current physical state of it cannot be determined. Signed-off-by: Rafael J. Wysocki Cc: 3.9+ --- drivers/acpi/device_pm.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index e9e8bb24785b..4ab807dc8518 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -324,14 +324,27 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p) if (result) return result; - if (state == ACPI_STATE_UNKNOWN) + if (state == ACPI_STATE_UNKNOWN) { state = ACPI_STATE_D0; - - result = acpi_device_set_power(device, state); - if (!result && state_p) + result = acpi_device_set_power(device, state); + if (result) + return result; + } else { + if (device->power.flags.power_resources) { + /* + * We don't need to really switch the state, bu we need + * to update the power resources' reference counters. + */ + result = acpi_power_transition(device, state); + if (result) + return result; + } + device->power.state = state; + } + if (state_p) *state_p = state; - return result; + return 0; } EXPORT_SYMBOL_GPL(acpi_bus_update_power); -- cgit v1.2.3-59-g8ed1b From 2ce65fe89153b6091393541de7e211d505436ff7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 4 Jul 2013 13:25:04 +0200 Subject: ACPI / dock: Actually define acpi_dock_init() as void Commit 94add0f (ACPI / dock: Initialize ACPI dock subsystem upfront) changed the header of acpi_dock_init() in internal.h so that it is supposed to be a void function now, but it forgot to update its actual definition in dock.c according to which it still is supposed to return int. Although that didn't cause any visible breakage or even a compiler warning to be thrown, which is odd enough, fix it. Signed-off-by: Rafael J. Wysocki Cc: 3.10+ --- drivers/acpi/dock.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 14de9f46972e..826560753389 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1064,10 +1064,10 @@ find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -int __init acpi_dock_init(void) +void __init acpi_dock_init(void) { if (acpi_disabled) - return 0; + return; /* look for dock stations and bays */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, @@ -1075,11 +1075,10 @@ int __init acpi_dock_init(void) if (!dock_station_count) { pr_info(PREFIX "No dock devices found.\n"); - return 0; + return; } register_acpi_bus_notifier(&dock_acpi_notifier); pr_info(PREFIX "%s: %d docks/bays found\n", ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); - return 0; } -- cgit v1.2.3-59-g8ed1b From b67cf7c44c7e6b485f1c255ac3c1fe98cc99b677 Mon Sep 17 00:00:00 2001 From: Haicheng Li Date: Thu, 4 Jul 2013 12:07:11 +0800 Subject: ACPI / scan: remove unused LIST_HEAD(acpi_device_list) The acpi_device_list list is not used, so removed it. [rjw: Changelog] Signed-off-by: Haicheng Li Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index dfe76f17cfc4..10985573aaa7 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -35,7 +35,6 @@ bool acpi_force_hot_remove; static const char *dummy_hid = "device"; -static LIST_HEAD(acpi_device_list); static LIST_HEAD(acpi_bus_id_list); static DEFINE_MUTEX(acpi_scan_lock); static LIST_HEAD(acpi_scan_handlers_list); -- cgit v1.2.3-59-g8ed1b From 85eb98274fd81c44e721c275ced54661ee9d5b05 Mon Sep 17 00:00:00 2001 From: Naresh Bhat Date: Mon, 1 Jul 2013 19:51:00 +0530 Subject: ACPI / fan: Initialize acpi_state variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the following compiler warning go away: CC drivers/acpi/fan.o drivers/acpi/fan.c: In function ‘fan_get_cur_state’: drivers/acpi/fan.c:96:9: warning: ‘acpi_state’ may be used uninitialized in this function [-Wuninitialized] by initializing the local variable acpi_state in fan_get_cur_state(). [rjw: Changelog] Signed-off-by: Naresh Bhat Signed-off-by: Rafael J. Wysocki --- drivers/acpi/fan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 8d1c0105e113..5b02a0aa540c 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -84,7 +84,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long { struct acpi_device *device = cdev->devdata; int result; - int acpi_state; + int acpi_state = ACPI_STATE_D0; if (!device) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From 10a0b6176b9f8b026ce07acd8f755297653c443c Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 5 Jul 2013 12:15:56 +0300 Subject: ACPI / power: add missing newline to debug messages There are few places in power.c where debug messages have no newline at the end. Reading such debug messages from dmesg is not fun, so fix this by adding the missing newlines. Signed-off-by: Mika Westerberg Cc: All Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 288bb270f8ed..5c28c894c0fc 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -279,7 +279,7 @@ static int acpi_power_on_unlocked(struct acpi_power_resource *resource) if (resource->ref_count++) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Power resource [%s] already on", + "Power resource [%s] already on\n", resource->name)); } else { result = __acpi_power_on(resource); @@ -325,7 +325,7 @@ static int acpi_power_off_unlocked(struct acpi_power_resource *resource) if (!resource->ref_count) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Power resource [%s] already off", + "Power resource [%s] already off\n", resource->name)); return 0; } -- cgit v1.2.3-59-g8ed1b