diff options
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 4976e5db2b3f..d592dbb1d12a 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pm_qos_params.h> | 41 | #include <linux/pm_qos_params.h> |
42 | #include <linux/clockchips.h> | 42 | #include <linux/clockchips.h> |
43 | #include <linux/cpuidle.h> | 43 | #include <linux/cpuidle.h> |
44 | #include <linux/cpuidle.h> | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Include the apic definitions for x86 to have the APIC timer related defines | 47 | * Include the apic definitions for x86 to have the APIC timer related defines |
@@ -57,6 +58,7 @@ | |||
57 | 58 | ||
58 | #include <acpi/acpi_bus.h> | 59 | #include <acpi/acpi_bus.h> |
59 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | #include <asm/processor.h> | ||
60 | 62 | ||
61 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | 63 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 |
62 | #define ACPI_PROCESSOR_CLASS "processor" | 64 | #define ACPI_PROCESSOR_CLASS "processor" |
@@ -401,7 +403,7 @@ static void acpi_processor_idle(void) | |||
401 | */ | 403 | */ |
402 | local_irq_disable(); | 404 | local_irq_disable(); |
403 | 405 | ||
404 | pr = processors[smp_processor_id()]; | 406 | pr = __get_cpu_var(processors); |
405 | if (!pr) { | 407 | if (!pr) { |
406 | local_irq_enable(); | 408 | local_irq_enable(); |
407 | return; | 409 | return; |
@@ -955,6 +957,21 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
955 | } else { | 957 | } else { |
956 | continue; | 958 | continue; |
957 | } | 959 | } |
960 | if (cx.type == ACPI_STATE_C1 && | ||
961 | (idle_halt || idle_nomwait)) { | ||
962 | /* | ||
963 | * In most cases the C1 space_id obtained from | ||
964 | * _CST object is FIXED_HARDWARE access mode. | ||
965 | * But when the option of idle=halt is added, | ||
966 | * the entry_method type should be changed from | ||
967 | * CSTATE_FFH to CSTATE_HALT. | ||
968 | * When the option of idle=nomwait is added, | ||
969 | * the C1 entry_method type should be | ||
970 | * CSTATE_HALT. | ||
971 | */ | ||
972 | cx.entry_method = ACPI_CSTATE_HALT; | ||
973 | snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); | ||
974 | } | ||
958 | } else { | 975 | } else { |
959 | snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", | 976 | snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", |
960 | cx.address); | 977 | cx.address); |
@@ -1431,7 +1448,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
1431 | struct acpi_processor *pr; | 1448 | struct acpi_processor *pr; |
1432 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 1449 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
1433 | 1450 | ||
1434 | pr = processors[smp_processor_id()]; | 1451 | pr = __get_cpu_var(processors); |
1435 | 1452 | ||
1436 | if (unlikely(!pr)) | 1453 | if (unlikely(!pr)) |
1437 | return 0; | 1454 | return 0; |
@@ -1471,7 +1488,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1471 | u32 t1, t2; | 1488 | u32 t1, t2; |
1472 | int sleep_ticks = 0; | 1489 | int sleep_ticks = 0; |
1473 | 1490 | ||
1474 | pr = processors[smp_processor_id()]; | 1491 | pr = __get_cpu_var(processors); |
1475 | 1492 | ||
1476 | if (unlikely(!pr)) | 1493 | if (unlikely(!pr)) |
1477 | return 0; | 1494 | return 0; |
@@ -1549,7 +1566,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1549 | u32 t1, t2; | 1566 | u32 t1, t2; |
1550 | int sleep_ticks = 0; | 1567 | int sleep_ticks = 0; |
1551 | 1568 | ||
1552 | pr = processors[smp_processor_id()]; | 1569 | pr = __get_cpu_var(processors); |
1553 | 1570 | ||
1554 | if (unlikely(!pr)) | 1571 | if (unlikely(!pr)) |
1555 | return 0; | 1572 | return 0; |
@@ -1780,6 +1797,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1780 | return 0; | 1797 | return 0; |
1781 | 1798 | ||
1782 | if (!first_run) { | 1799 | if (!first_run) { |
1800 | if (idle_halt) { | ||
1801 | /* | ||
1802 | * When the boot option of "idle=halt" is added, halt | ||
1803 | * is used for CPU IDLE. | ||
1804 | * In such case C2/C3 is meaningless. So the max_cstate | ||
1805 | * is set to one. | ||
1806 | */ | ||
1807 | max_cstate = 1; | ||
1808 | } | ||
1783 | dmi_check_system(processor_power_dmi_table); | 1809 | dmi_check_system(processor_power_dmi_table); |
1784 | max_cstate = acpi_processor_cstate_check(max_cstate); | 1810 | max_cstate = acpi_processor_cstate_check(max_cstate); |
1785 | if (max_cstate < ACPI_C_STATES_MAX) | 1811 | if (max_cstate < ACPI_C_STATES_MAX) |