aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/i2c_ec.c2
-rw-r--r--drivers/acpi/namespace/nsinit.c9
-rw-r--r--drivers/acpi/processor_idle.c114
-rw-r--r--drivers/acpi/sleep/poweroff.c1
-rw-r--r--drivers/acpi/tables.c1
-rw-r--r--drivers/acpi/thermal.c3
6 files changed, 107 insertions, 23 deletions
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
index 8338be0990bc..76ec8b63e69f 100644
--- a/drivers/acpi/i2c_ec.c
+++ b/drivers/acpi/i2c_ec.c
@@ -14,7 +14,6 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/stddef.h> 16#include <linux/stddef.h>
17#include <linux/sched.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/i2c.h> 18#include <linux/i2c.h>
20#include <linux/acpi.h> 19#include <linux/acpi.h>
@@ -340,6 +339,7 @@ static int acpi_ec_hc_add(struct acpi_device *device)
340 smbus->adapter.owner = THIS_MODULE; 339 smbus->adapter.owner = THIS_MODULE;
341 smbus->adapter.algo = &acpi_ec_smbus_algorithm; 340 smbus->adapter.algo = &acpi_ec_smbus_algorithm;
342 smbus->adapter.algo_data = smbus; 341 smbus->adapter.algo_data = smbus;
342 smbus->adapter.dev.parent = &device->dev;
343 343
344 if (i2c_add_adapter(&smbus->adapter)) { 344 if (i2c_add_adapter(&smbus->adapter)) {
345 ACPI_DEBUG_PRINT((ACPI_DB_WARN, 345 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 326af8fc0ce7..33db2241044e 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -45,6 +45,7 @@
45#include <acpi/acnamesp.h> 45#include <acpi/acnamesp.h>
46#include <acpi/acdispat.h> 46#include <acpi/acdispat.h>
47#include <acpi/acinterp.h> 47#include <acpi/acinterp.h>
48#include <linux/nmi.h>
48 49
49#define _COMPONENT ACPI_NAMESPACE 50#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsinit") 51ACPI_MODULE_NAME("nsinit")
@@ -534,7 +535,15 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
534 info->parameter_type = ACPI_PARAM_ARGS; 535 info->parameter_type = ACPI_PARAM_ARGS;
535 info->flags = ACPI_IGNORE_RETURN_VALUE; 536 info->flags = ACPI_IGNORE_RETURN_VALUE;
536 537
538 /*
539 * Some hardware relies on this being executed as atomically
540 * as possible (without an NMI being received in the middle of
541 * this) - so disable NMIs and initialize the device:
542 */
543 acpi_nmi_disable();
537 status = acpi_ns_evaluate(info); 544 status = acpi_ns_evaluate(info);
545 acpi_nmi_enable();
546
538 if (ACPI_SUCCESS(status)) { 547 if (ACPI_SUCCESS(status)) {
539 walk_info->num_INI++; 548 walk_info->num_INI++;
540 549
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 59fac8d79412..835595ae06b3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -39,6 +39,17 @@
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/sched.h> /* need_resched() */ 40#include <linux/sched.h> /* need_resched() */
41#include <linux/latency.h> 41#include <linux/latency.h>
42#include <linux/clockchips.h>
43
44/*
45 * Include the apic definitions for x86 to have the APIC timer related defines
46 * available also for UP (on SMP it gets magically included via linux/smp.h).
47 * asm/acpi.h is not an option, as it would require more include magic. Also
48 * creating an empty asm-ia64/apic.h would just trade pest vs. cholera.
49 */
50#ifdef CONFIG_X86
51#include <asm/apic.h>
52#endif
42 53
43/* 54/*
44 * Include the apic definitions for x86 to have the APIC timer related defines 55 * Include the apic definitions for x86 to have the APIC timer related defines
@@ -246,6 +257,81 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
246 } 257 }
247} 258}
248 259
260#ifdef ARCH_APICTIMER_STOPS_ON_C3
261
262/*
263 * Some BIOS implementations switch to C3 in the published C2 state.
264 * This seems to be a common problem on AMD boxen, but other vendors
265 * are affected too. We pick the most conservative approach: we assume
266 * that the local APIC stops in both C2 and C3.
267 */
268static void acpi_timer_check_state(int state, struct acpi_processor *pr,
269 struct acpi_processor_cx *cx)
270{
271 struct acpi_processor_power *pwr = &pr->power;
272
273 /*
274 * Check, if one of the previous states already marked the lapic
275 * unstable
276 */
277 if (pwr->timer_broadcast_on_state < state)
278 return;
279
280 if (cx->type >= ACPI_STATE_C2)
281 pr->power.timer_broadcast_on_state = state;
282}
283
284static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
285{
286#ifdef CONFIG_GENERIC_CLOCKEVENTS
287 unsigned long reason;
288
289 reason = pr->power.timer_broadcast_on_state < INT_MAX ?
290 CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
291
292 clockevents_notify(reason, &pr->id);
293#else
294 cpumask_t mask = cpumask_of_cpu(pr->id);
295
296 if (pr->power.timer_broadcast_on_state < INT_MAX)
297 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
298 else
299 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
300#endif
301}
302
303/* Power(C) State timer broadcast control */
304static void acpi_state_timer_broadcast(struct acpi_processor *pr,
305 struct acpi_processor_cx *cx,
306 int broadcast)
307{
308#ifdef CONFIG_GENERIC_CLOCKEVENTS
309
310 int state = cx - pr->power.states;
311
312 if (state >= pr->power.timer_broadcast_on_state) {
313 unsigned long reason;
314
315 reason = broadcast ? CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
316 CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
317 clockevents_notify(reason, &pr->id);
318 }
319#endif
320}
321
322#else
323
324static void acpi_timer_check_state(int state, struct acpi_processor *pr,
325 struct acpi_processor_cx *cstate) { }
326static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { }
327static void acpi_state_timer_broadcast(struct acpi_processor *pr,
328 struct acpi_processor_cx *cx,
329 int broadcast)
330{
331}
332
333#endif
334
249static void acpi_processor_idle(void) 335static void acpi_processor_idle(void)
250{ 336{
251 struct acpi_processor *pr = NULL; 337 struct acpi_processor *pr = NULL;
@@ -390,6 +476,7 @@ static void acpi_processor_idle(void)
390 /* Get start time (ticks) */ 476 /* Get start time (ticks) */
391 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 477 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
392 /* Invoke C2 */ 478 /* Invoke C2 */
479 acpi_state_timer_broadcast(pr, cx, 1);
393 acpi_cstate_enter(cx); 480 acpi_cstate_enter(cx);
394 /* Get end time (ticks) */ 481 /* Get end time (ticks) */
395 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 482 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -404,6 +491,7 @@ static void acpi_processor_idle(void)
404 /* Compute time (ticks) that we were actually asleep */ 491 /* Compute time (ticks) that we were actually asleep */
405 sleep_ticks = 492 sleep_ticks =
406 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; 493 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
494 acpi_state_timer_broadcast(pr, cx, 0);
407 break; 495 break;
408 496
409 case ACPI_STATE_C3: 497 case ACPI_STATE_C3:
@@ -425,6 +513,7 @@ static void acpi_processor_idle(void)
425 /* Get start time (ticks) */ 513 /* Get start time (ticks) */
426 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 514 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
427 /* Invoke C3 */ 515 /* Invoke C3 */
516 acpi_state_timer_broadcast(pr, cx, 1);
428 acpi_cstate_enter(cx); 517 acpi_cstate_enter(cx);
429 /* Get end time (ticks) */ 518 /* Get end time (ticks) */
430 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 519 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -444,6 +533,7 @@ static void acpi_processor_idle(void)
444 /* Compute time (ticks) that we were actually asleep */ 533 /* Compute time (ticks) that we were actually asleep */
445 sleep_ticks = 534 sleep_ticks =
446 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; 535 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
536 acpi_state_timer_broadcast(pr, cx, 0);
447 break; 537 break;
448 538
449 default: 539 default:
@@ -912,11 +1002,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
912 unsigned int i; 1002 unsigned int i;
913 unsigned int working = 0; 1003 unsigned int working = 0;
914 1004
915#ifdef ARCH_APICTIMER_STOPS_ON_C3 1005 pr->power.timer_broadcast_on_state = INT_MAX;
916 int timer_broadcast = 0;
917 cpumask_t mask = cpumask_of_cpu(pr->id);
918 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
919#endif
920 1006
921 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { 1007 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
922 struct acpi_processor_cx *cx = &pr->power.states[i]; 1008 struct acpi_processor_cx *cx = &pr->power.states[i];
@@ -928,21 +1014,14 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
928 1014
929 case ACPI_STATE_C2: 1015 case ACPI_STATE_C2:
930 acpi_processor_power_verify_c2(cx); 1016 acpi_processor_power_verify_c2(cx);
931#ifdef ARCH_APICTIMER_STOPS_ON_C3 1017 if (cx->valid)
932 /* Some AMD systems fake C3 as C2, but still 1018 acpi_timer_check_state(i, pr, cx);
933 have timer troubles */
934 if (cx->valid &&
935 boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
936 timer_broadcast++;
937#endif
938 break; 1019 break;
939 1020
940 case ACPI_STATE_C3: 1021 case ACPI_STATE_C3:
941 acpi_processor_power_verify_c3(pr, cx); 1022 acpi_processor_power_verify_c3(pr, cx);
942#ifdef ARCH_APICTIMER_STOPS_ON_C3
943 if (cx->valid) 1023 if (cx->valid)
944 timer_broadcast++; 1024 acpi_timer_check_state(i, pr, cx);
945#endif
946 break; 1025 break;
947 } 1026 }
948 1027
@@ -950,10 +1029,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
950 working++; 1029 working++;
951 } 1030 }
952 1031
953#ifdef ARCH_APICTIMER_STOPS_ON_C3 1032 acpi_propagate_timer_broadcast(pr);
954 if (timer_broadcast)
955 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
956#endif
957 1033
958 return (working); 1034 return (working);
959} 1035}
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index 47fb4b394eec..d9801eff6489 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -12,7 +12,6 @@
12#include <linux/pm.h> 12#include <linux/pm.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <acpi/acpi_bus.h> 14#include <acpi/acpi_bus.h>
15#include <linux/sched.h>
16#include <linux/sysdev.h> 15#include <linux/sysdev.h>
17#include <asm/io.h> 16#include <asm/io.h>
18#include "sleep.h" 17#include "sleep.h"
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index ba4cb200314a..45bd17313c4a 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -25,7 +25,6 @@
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/sched.h>
29#include <linux/smp.h> 28#include <linux/smp.h>
30#include <linux/string.h> 29#include <linux/string.h>
31#include <linux/types.h> 30#include <linux/types.h>
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index ff078d9b52f6..442bfd50dc3d 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -36,7 +36,8 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/types.h> 37#include <linux/types.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/sched.h> 39#include <linux/timer.h>
40#include <linux/jiffies.h>
40#include <linux/kmod.h> 41#include <linux/kmod.h>
41#include <linux/seq_file.h> 42#include <linux/seq_file.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>