aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 18:59:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 18:59:39 -0400
commit40031da445fb4d269af9c7c445b2adf674f171e7 (patch)
tree021df7906708e939dee9978669a5461b12ff1296 /drivers/base
parentdcaaaeac871ff73043c616db3b2f91482637801d (diff)
parentf41b83126cba53849dd2353476a7715613af648f (diff)
Merge tag 'pm+acpi-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki: 1) ACPI-based PCI hotplug (ACPIPHP) subsystem rework and introduction of Intel Thunderbolt support on systems that use ACPI for signalling Thunderbolt hotplug events. This also should make ACPIPHP work in some cases in which it was known to have problems. From Rafael J Wysocki, Mika Westerberg and Kirill A Shutemov. 2) ACPI core code cleanups and dock station support cleanups from Jiang Liu and Rafael J Wysocki. 3) Fixes for locking problems related to ACPI device hotplug from Rafael J Wysocki. 4) ACPICA update to version 20130725 includig fixes, cleanups, support for more than 256 GPEs per GPE block and a change to make the ACPI PM Timer optional (we've seen systems without the PM Timer in the field already). One of the fixes, related to the DeRefOf operator, is necessary to prevent some Windows 8 oriented AML from causing problems to happen. From Bob Moore, Lv Zheng, and Jung-uk Kim. 5) Removal of the old and long deprecated /proc/acpi/event interface and related driver changes from Thomas Renninger. 6) ACPI and Xen changes to make the reduced hardware sleep work with the latter from Ben Guthro. 7) ACPI video driver cleanups and a blacklist of systems that should not tell the BIOS that they are compatible with Windows 8 (or ACPI backlight and possibly other things will not work on them). From Felipe Contreras. 8) Assorted ACPI fixes and cleanups from Aaron Lu, Hanjun Guo, Kuppuswamy Sathyanarayanan, Lan Tianyu, Sachin Kamat, Tang Chen, Toshi Kani, and Wei Yongjun. 9) cpufreq ondemand governor target frequency selection change to reduce oscillations between min and max frequencies (essentially, it causes the governor to choose target frequencies proportional to load) from Stratos Karafotis. 10) cpufreq fixes allowing sysfs attributes file permissions to be preserved over suspend/resume cycles Srivatsa S Bhat. 11) Removal of Device Tree parsing for CPU device nodes from multiple cpufreq drivers that required some changes related to of_get_cpu_node() to be made in a few architectures and in the driver core. From Sudeep KarkadaNagesha. 12) cpufreq core fixes and cleanups related to mutual exclusion and driver module references from Viresh Kumar, Lukasz Majewski and Rafael J Wysocki. 13) Assorted cpufreq fixes and cleanups from Amit Daniel Kachhap, Bartlomiej Zolnierkiewicz, Hanjun Guo, Jingoo Han, Joseph Lo, Julia Lawall, Li Zhong, Mark Brown, Sascha Hauer, Stephen Boyd, Stratos Karafotis, and Viresh Kumar. 14) Fixes to prevent race conditions in coupled cpuidle from happening from Colin Cross. 15) cpuidle core fixes and cleanups from Daniel Lezcano and Tuukka Tikkanen. 16) Assorted cpuidle fixes and cleanups from Daniel Lezcano, Geert Uytterhoeven, Jingoo Han, Julia Lawall, Linus Walleij, and Sahara. 17) System sleep tracing changes from Todd E Brandt and Shuah Khan. 18) PNP subsystem conversion to using struct dev_pm_ops for power management from Shuah Khan. * tag 'pm+acpi-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (217 commits) cpufreq: Don't use smp_processor_id() in preemptible context cpuidle: coupled: fix race condition between pokes and safe state cpuidle: coupled: abort idle if pokes are pending cpuidle: coupled: disable interrupts after entering safe state ACPI / hotplug: Remove containers synchronously driver core / ACPI: Avoid device hot remove locking issues cpufreq: governor: Fix typos in comments cpufreq: governors: Remove duplicate check of target freq in supported range cpufreq: Fix timer/workqueue corruption due to double queueing ACPI / EC: Add ASUSTEK L4R to quirk list in order to validate ECDT ACPI / thermal: Add check of "_TZD" availability and evaluating result cpufreq: imx6q: Fix clock enable balance ACPI: blacklist win8 OSI for buggy laptops cpufreq: tegra: fix the wrong clock name cpuidle: Change struct menu_device field types cpuidle: Add a comment warning about possible overflow cpuidle: Fix variable domains in get_typical_interval() cpuidle: Fix menu_device->intervals type cpuidle: CodingStyle: Break up multiple assignments on single line cpuidle: Check called function parameter in get_typical_interval() ...
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c43
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/memory.c4
-rw-r--r--drivers/base/power/main.c77
-rw-r--r--drivers/base/power/opp.c1
5 files changed, 77 insertions, 50 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index c7b0925f627a..c7cfadcf6752 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -50,6 +50,28 @@ static struct kobject *dev_kobj;
50struct kobject *sysfs_dev_char_kobj; 50struct kobject *sysfs_dev_char_kobj;
51struct kobject *sysfs_dev_block_kobj; 51struct kobject *sysfs_dev_block_kobj;
52 52
53static DEFINE_MUTEX(device_hotplug_lock);
54
55void lock_device_hotplug(void)
56{
57 mutex_lock(&device_hotplug_lock);
58}
59
60void unlock_device_hotplug(void)
61{
62 mutex_unlock(&device_hotplug_lock);
63}
64
65int lock_device_hotplug_sysfs(void)
66{
67 if (mutex_trylock(&device_hotplug_lock))
68 return 0;
69
70 /* Avoid busy looping (5 ms of sleep should do). */
71 msleep(5);
72 return restart_syscall();
73}
74
53#ifdef CONFIG_BLOCK 75#ifdef CONFIG_BLOCK
54static inline int device_is_not_partition(struct device *dev) 76static inline int device_is_not_partition(struct device *dev)
55{ 77{
@@ -407,9 +429,9 @@ static ssize_t online_show(struct device *dev, struct device_attribute *attr,
407{ 429{
408 bool val; 430 bool val;
409 431
410 lock_device_hotplug(); 432 device_lock(dev);
411 val = !dev->offline; 433 val = !dev->offline;
412 unlock_device_hotplug(); 434 device_unlock(dev);
413 return sprintf(buf, "%u\n", val); 435 return sprintf(buf, "%u\n", val);
414} 436}
415 437
@@ -423,7 +445,10 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr,
423 if (ret < 0) 445 if (ret < 0)
424 return ret; 446 return ret;
425 447
426 lock_device_hotplug(); 448 ret = lock_device_hotplug_sysfs();
449 if (ret)
450 return ret;
451
427 ret = val ? device_online(dev) : device_offline(dev); 452 ret = val ? device_online(dev) : device_offline(dev);
428 unlock_device_hotplug(); 453 unlock_device_hotplug();
429 return ret < 0 ? ret : count; 454 return ret < 0 ? ret : count;
@@ -1450,18 +1475,6 @@ int __init devices_init(void)
1450 return -ENOMEM; 1475 return -ENOMEM;
1451} 1476}
1452 1477
1453static DEFINE_MUTEX(device_hotplug_lock);
1454
1455void lock_device_hotplug(void)
1456{
1457 mutex_lock(&device_hotplug_lock);
1458}
1459
1460void unlock_device_hotplug(void)
1461{
1462 mutex_unlock(&device_hotplug_lock);
1463}
1464
1465static int device_check_offline(struct device *dev, void *not_used) 1478static int device_check_offline(struct device *dev, void *not_used)
1466{ 1479{
1467 int ret; 1480 int ret;
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 6bfaaca6955e..848ebbd25717 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/percpu.h> 15#include <linux/percpu.h>
16#include <linux/acpi.h> 16#include <linux/acpi.h>
17#include <linux/of.h>
17 18
18#include "base.h" 19#include "base.h"
19 20
@@ -293,6 +294,7 @@ int register_cpu(struct cpu *cpu, int num)
293 cpu->dev.release = cpu_device_release; 294 cpu->dev.release = cpu_device_release;
294 cpu->dev.offline_disabled = !cpu->hotpluggable; 295 cpu->dev.offline_disabled = !cpu->hotpluggable;
295 cpu->dev.offline = !cpu_online(num); 296 cpu->dev.offline = !cpu_online(num);
297 cpu->dev.of_node = of_get_cpu_node(num, NULL);
296#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE 298#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
297 cpu->dev.bus->uevent = arch_cpu_uevent; 299 cpu->dev.bus->uevent = arch_cpu_uevent;
298#endif 300#endif
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 1c617623c8ae..9e59f6535c44 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -321,7 +321,9 @@ store_mem_state(struct device *dev,
321 struct memory_block *mem = to_memory_block(dev); 321 struct memory_block *mem = to_memory_block(dev);
322 int ret, online_type; 322 int ret, online_type;
323 323
324 lock_device_hotplug(); 324 ret = lock_device_hotplug_sysfs();
325 if (ret)
326 return ret;
325 327
326 if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) 328 if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
327 online_type = ONLINE_KERNEL; 329 online_type = ONLINE_KERNEL;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 5a9b6569dd74..9f098a82cf04 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -28,6 +28,7 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/async.h> 29#include <linux/async.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31#include <trace/events/power.h>
31#include <linux/cpuidle.h> 32#include <linux/cpuidle.h>
32#include "../base.h" 33#include "../base.h"
33#include "power.h" 34#include "power.h"
@@ -56,6 +57,30 @@ static pm_message_t pm_transition;
56 57
57static int async_error; 58static int async_error;
58 59
60static char *pm_verb(int event)
61{
62 switch (event) {
63 case PM_EVENT_SUSPEND:
64 return "suspend";
65 case PM_EVENT_RESUME:
66 return "resume";
67 case PM_EVENT_FREEZE:
68 return "freeze";
69 case PM_EVENT_QUIESCE:
70 return "quiesce";
71 case PM_EVENT_HIBERNATE:
72 return "hibernate";
73 case PM_EVENT_THAW:
74 return "thaw";
75 case PM_EVENT_RESTORE:
76 return "restore";
77 case PM_EVENT_RECOVER:
78 return "recover";
79 default:
80 return "(unknown PM event)";
81 }
82}
83
59/** 84/**
60 * device_pm_sleep_init - Initialize system suspend-related device fields. 85 * device_pm_sleep_init - Initialize system suspend-related device fields.
61 * @dev: Device object being initialized. 86 * @dev: Device object being initialized.
@@ -172,16 +197,21 @@ static ktime_t initcall_debug_start(struct device *dev)
172} 197}
173 198
174static void initcall_debug_report(struct device *dev, ktime_t calltime, 199static void initcall_debug_report(struct device *dev, ktime_t calltime,
175 int error) 200 int error, pm_message_t state, char *info)
176{ 201{
177 ktime_t delta, rettime; 202 ktime_t rettime;
203 s64 nsecs;
204
205 rettime = ktime_get();
206 nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
178 207
179 if (pm_print_times_enabled) { 208 if (pm_print_times_enabled) {
180 rettime = ktime_get();
181 delta = ktime_sub(rettime, calltime);
182 pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), 209 pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
183 error, (unsigned long long)ktime_to_ns(delta) >> 10); 210 error, (unsigned long long)nsecs >> 10);
184 } 211 }
212
213 trace_device_pm_report_time(dev, info, nsecs, pm_verb(state.event),
214 error);
185} 215}
186 216
187/** 217/**
@@ -309,30 +339,6 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat
309 return NULL; 339 return NULL;
310} 340}
311 341
312static char *pm_verb(int event)
313{
314 switch (event) {
315 case PM_EVENT_SUSPEND:
316 return "suspend";
317 case PM_EVENT_RESUME:
318 return "resume";
319 case PM_EVENT_FREEZE:
320 return "freeze";
321 case PM_EVENT_QUIESCE:
322 return "quiesce";
323 case PM_EVENT_HIBERNATE:
324 return "hibernate";
325 case PM_EVENT_THAW:
326 return "thaw";
327 case PM_EVENT_RESTORE:
328 return "restore";
329 case PM_EVENT_RECOVER:
330 return "recover";
331 default:
332 return "(unknown PM event)";
333 }
334}
335
336static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) 342static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info)
337{ 343{
338 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), 344 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event),
@@ -379,7 +385,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
379 error = cb(dev); 385 error = cb(dev);
380 suspend_report_result(cb, error); 386 suspend_report_result(cb, error);
381 387
382 initcall_debug_report(dev, calltime, error); 388 initcall_debug_report(dev, calltime, error, state, info);
383 389
384 return error; 390 return error;
385} 391}
@@ -1027,7 +1033,8 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end);
1027 * @cb: Suspend callback to execute. 1033 * @cb: Suspend callback to execute.
1028 */ 1034 */
1029static int legacy_suspend(struct device *dev, pm_message_t state, 1035static int legacy_suspend(struct device *dev, pm_message_t state,
1030 int (*cb)(struct device *dev, pm_message_t state)) 1036 int (*cb)(struct device *dev, pm_message_t state),
1037 char *info)
1031{ 1038{
1032 int error; 1039 int error;
1033 ktime_t calltime; 1040 ktime_t calltime;
@@ -1037,7 +1044,7 @@ static int legacy_suspend(struct device *dev, pm_message_t state,
1037 error = cb(dev, state); 1044 error = cb(dev, state);
1038 suspend_report_result(cb, error); 1045 suspend_report_result(cb, error);
1039 1046
1040 initcall_debug_report(dev, calltime, error); 1047 initcall_debug_report(dev, calltime, error, state, info);
1041 1048
1042 return error; 1049 return error;
1043} 1050}
@@ -1097,7 +1104,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1097 goto Run; 1104 goto Run;
1098 } else if (dev->class->suspend) { 1105 } else if (dev->class->suspend) {
1099 pm_dev_dbg(dev, state, "legacy class "); 1106 pm_dev_dbg(dev, state, "legacy class ");
1100 error = legacy_suspend(dev, state, dev->class->suspend); 1107 error = legacy_suspend(dev, state, dev->class->suspend,
1108 "legacy class ");
1101 goto End; 1109 goto End;
1102 } 1110 }
1103 } 1111 }
@@ -1108,7 +1116,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1108 callback = pm_op(dev->bus->pm, state); 1116 callback = pm_op(dev->bus->pm, state);
1109 } else if (dev->bus->suspend) { 1117 } else if (dev->bus->suspend) {
1110 pm_dev_dbg(dev, state, "legacy bus "); 1118 pm_dev_dbg(dev, state, "legacy bus ");
1111 error = legacy_suspend(dev, state, dev->bus->suspend); 1119 error = legacy_suspend(dev, state, dev->bus->suspend,
1120 "legacy bus ");
1112 goto End; 1121 goto End;
1113 } 1122 }
1114 } 1123 }
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index c8ec186303db..ef89897c6043 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -460,6 +460,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
460 srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp); 460 srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp);
461 return 0; 461 return 0;
462} 462}
463EXPORT_SYMBOL_GPL(opp_add);
463 464
464/** 465/**
465 * opp_set_availability() - helper to set the availability of an opp 466 * opp_set_availability() - helper to set the availability of an opp