diff options
Diffstat (limited to 'drivers/acpi/processor_idle.c')
| -rw-r--r-- | drivers/acpi/processor_idle.c | 52 |
1 files changed, 18 insertions, 34 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f1a5da44591d..fc95308e9a11 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -28,19 +28,12 @@ | |||
| 28 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 28 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/module.h> | 31 | #include <linux/module.h> |
| 33 | #include <linux/init.h> | ||
| 34 | #include <linux/cpufreq.h> | ||
| 35 | #include <linux/slab.h> | ||
| 36 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
| 37 | #include <linux/dmi.h> | 33 | #include <linux/dmi.h> |
| 38 | #include <linux/moduleparam.h> | 34 | #include <linux/sched.h> /* need_resched() */ |
| 39 | #include <linux/sched.h> /* need_resched() */ | ||
| 40 | #include <linux/pm_qos.h> | ||
| 41 | #include <linux/clockchips.h> | 35 | #include <linux/clockchips.h> |
| 42 | #include <linux/cpuidle.h> | 36 | #include <linux/cpuidle.h> |
| 43 | #include <linux/irqflags.h> | ||
| 44 | 37 | ||
| 45 | /* | 38 | /* |
| 46 | * Include the apic definitions for x86 to have the APIC timer related defines | 39 | * Include the apic definitions for x86 to have the APIC timer related defines |
| @@ -52,22 +45,14 @@ | |||
| 52 | #include <asm/apic.h> | 45 | #include <asm/apic.h> |
| 53 | #endif | 46 | #endif |
| 54 | 47 | ||
| 55 | #include <asm/io.h> | ||
| 56 | #include <asm/uaccess.h> | ||
| 57 | |||
| 58 | #include <acpi/acpi_bus.h> | 48 | #include <acpi/acpi_bus.h> |
| 59 | #include <acpi/processor.h> | 49 | #include <acpi/processor.h> |
| 60 | #include <asm/processor.h> | ||
| 61 | 50 | ||
| 62 | #define PREFIX "ACPI: " | 51 | #define PREFIX "ACPI: " |
| 63 | 52 | ||
| 64 | #define ACPI_PROCESSOR_CLASS "processor" | 53 | #define ACPI_PROCESSOR_CLASS "processor" |
| 65 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 54 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
| 66 | ACPI_MODULE_NAME("processor_idle"); | 55 | ACPI_MODULE_NAME("processor_idle"); |
| 67 | #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) | ||
| 68 | #define C2_OVERHEAD 1 /* 1us */ | ||
| 69 | #define C3_OVERHEAD 1 /* 1us */ | ||
| 70 | #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) | ||
| 71 | 56 | ||
| 72 | static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; | 57 | static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; |
| 73 | module_param(max_cstate, uint, 0000); | 58 | module_param(max_cstate, uint, 0000); |
| @@ -81,10 +66,11 @@ module_param(latency_factor, uint, 0644); | |||
| 81 | 66 | ||
| 82 | static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); | 67 | static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); |
| 83 | 68 | ||
| 69 | static struct acpi_processor_cx *acpi_cstate[CPUIDLE_STATE_MAX]; | ||
| 70 | |||
| 84 | static int disabled_by_idle_boot_param(void) | 71 | static int disabled_by_idle_boot_param(void) |
| 85 | { | 72 | { |
| 86 | return boot_option_idle_override == IDLE_POLL || | 73 | return boot_option_idle_override == IDLE_POLL || |
| 87 | boot_option_idle_override == IDLE_FORCE_MWAIT || | ||
| 88 | boot_option_idle_override == IDLE_HALT; | 74 | boot_option_idle_override == IDLE_HALT; |
| 89 | } | 75 | } |
| 90 | 76 | ||
| @@ -736,8 +722,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
| 736 | struct cpuidle_driver *drv, int index) | 722 | struct cpuidle_driver *drv, int index) |
| 737 | { | 723 | { |
| 738 | struct acpi_processor *pr; | 724 | struct acpi_processor *pr; |
| 739 | struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; | 725 | struct acpi_processor_cx *cx = acpi_cstate[index]; |
| 740 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); | ||
| 741 | 726 | ||
| 742 | pr = __this_cpu_read(processors); | 727 | pr = __this_cpu_read(processors); |
| 743 | 728 | ||
| @@ -760,8 +745,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
| 760 | */ | 745 | */ |
| 761 | static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) | 746 | static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) |
| 762 | { | 747 | { |
| 763 | struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; | 748 | struct acpi_processor_cx *cx = acpi_cstate[index]; |
| 764 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); | ||
| 765 | 749 | ||
| 766 | ACPI_FLUSH_CPU_CACHE(); | 750 | ACPI_FLUSH_CPU_CACHE(); |
| 767 | 751 | ||
| @@ -791,8 +775,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
| 791 | struct cpuidle_driver *drv, int index) | 775 | struct cpuidle_driver *drv, int index) |
| 792 | { | 776 | { |
| 793 | struct acpi_processor *pr; | 777 | struct acpi_processor *pr; |
| 794 | struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; | 778 | struct acpi_processor_cx *cx = acpi_cstate[index]; |
| 795 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); | ||
| 796 | 779 | ||
| 797 | pr = __this_cpu_read(processors); | 780 | pr = __this_cpu_read(processors); |
| 798 | 781 | ||
| @@ -850,8 +833,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
| 850 | struct cpuidle_driver *drv, int index) | 833 | struct cpuidle_driver *drv, int index) |
| 851 | { | 834 | { |
| 852 | struct acpi_processor *pr; | 835 | struct acpi_processor *pr; |
| 853 | struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; | 836 | struct acpi_processor_cx *cx = acpi_cstate[index]; |
| 854 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); | ||
| 855 | 837 | ||
| 856 | pr = __this_cpu_read(processors); | 838 | pr = __this_cpu_read(processors); |
| 857 | 839 | ||
| @@ -943,13 +925,13 @@ struct cpuidle_driver acpi_idle_driver = { | |||
| 943 | * device i.e. per-cpu data | 925 | * device i.e. per-cpu data |
| 944 | * | 926 | * |
| 945 | * @pr: the ACPI processor | 927 | * @pr: the ACPI processor |
| 928 | * @dev : the cpuidle device | ||
| 946 | */ | 929 | */ |
| 947 | static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) | 930 | static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, |
| 931 | struct cpuidle_device *dev) | ||
| 948 | { | 932 | { |
| 949 | int i, count = CPUIDLE_DRIVER_STATE_START; | 933 | int i, count = CPUIDLE_DRIVER_STATE_START; |
| 950 | struct acpi_processor_cx *cx; | 934 | struct acpi_processor_cx *cx; |
| 951 | struct cpuidle_state_usage *state_usage; | ||
| 952 | struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id); | ||
| 953 | 935 | ||
| 954 | if (!pr->flags.power_setup_done) | 936 | if (!pr->flags.power_setup_done) |
| 955 | return -EINVAL; | 937 | return -EINVAL; |
| @@ -958,6 +940,9 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) | |||
| 958 | return -EINVAL; | 940 | return -EINVAL; |
| 959 | } | 941 | } |
| 960 | 942 | ||
| 943 | if (!dev) | ||
| 944 | return -EINVAL; | ||
| 945 | |||
| 961 | dev->cpu = pr->id; | 946 | dev->cpu = pr->id; |
| 962 | 947 | ||
| 963 | if (max_cstate == 0) | 948 | if (max_cstate == 0) |
| @@ -965,7 +950,6 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) | |||
| 965 | 950 | ||
| 966 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { | 951 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { |
| 967 | cx = &pr->power.states[i]; | 952 | cx = &pr->power.states[i]; |
| 968 | state_usage = &dev->states_usage[count]; | ||
| 969 | 953 | ||
| 970 | if (!cx->valid) | 954 | if (!cx->valid) |
| 971 | continue; | 955 | continue; |
| @@ -976,8 +960,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) | |||
| 976 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | 960 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) |
| 977 | continue; | 961 | continue; |
| 978 | #endif | 962 | #endif |
| 979 | 963 | acpi_cstate[count] = cx; | |
| 980 | cpuidle_set_statedata(state_usage, cx); | ||
| 981 | 964 | ||
| 982 | count++; | 965 | count++; |
| 983 | if (count == CPUIDLE_STATE_MAX) | 966 | if (count == CPUIDLE_STATE_MAX) |
| @@ -1101,7 +1084,7 @@ int acpi_processor_hotplug(struct acpi_processor *pr) | |||
| 1101 | cpuidle_disable_device(dev); | 1084 | cpuidle_disable_device(dev); |
| 1102 | acpi_processor_get_power_info(pr); | 1085 | acpi_processor_get_power_info(pr); |
| 1103 | if (pr->flags.power) { | 1086 | if (pr->flags.power) { |
| 1104 | acpi_processor_setup_cpuidle_cx(pr); | 1087 | acpi_processor_setup_cpuidle_cx(pr, dev); |
| 1105 | ret = cpuidle_enable_device(dev); | 1088 | ret = cpuidle_enable_device(dev); |
| 1106 | } | 1089 | } |
| 1107 | cpuidle_resume_and_unlock(); | 1090 | cpuidle_resume_and_unlock(); |
| @@ -1149,6 +1132,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
| 1149 | } | 1132 | } |
| 1150 | 1133 | ||
| 1151 | /* Populate Updated C-state information */ | 1134 | /* Populate Updated C-state information */ |
| 1135 | acpi_processor_get_power_info(pr); | ||
| 1152 | acpi_processor_setup_cpuidle_states(pr); | 1136 | acpi_processor_setup_cpuidle_states(pr); |
| 1153 | 1137 | ||
| 1154 | /* Enable all cpuidle devices */ | 1138 | /* Enable all cpuidle devices */ |
| @@ -1158,8 +1142,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
| 1158 | continue; | 1142 | continue; |
| 1159 | acpi_processor_get_power_info(_pr); | 1143 | acpi_processor_get_power_info(_pr); |
| 1160 | if (_pr->flags.power) { | 1144 | if (_pr->flags.power) { |
| 1161 | acpi_processor_setup_cpuidle_cx(_pr); | ||
| 1162 | dev = per_cpu(acpi_cpuidle_device, cpu); | 1145 | dev = per_cpu(acpi_cpuidle_device, cpu); |
| 1146 | acpi_processor_setup_cpuidle_cx(_pr, dev); | ||
| 1163 | cpuidle_enable_device(dev); | 1147 | cpuidle_enable_device(dev); |
| 1164 | } | 1148 | } |
| 1165 | } | 1149 | } |
| @@ -1228,7 +1212,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr) | |||
| 1228 | return -ENOMEM; | 1212 | return -ENOMEM; |
| 1229 | per_cpu(acpi_cpuidle_device, pr->id) = dev; | 1213 | per_cpu(acpi_cpuidle_device, pr->id) = dev; |
| 1230 | 1214 | ||
| 1231 | acpi_processor_setup_cpuidle_cx(pr); | 1215 | acpi_processor_setup_cpuidle_cx(pr, dev); |
| 1232 | 1216 | ||
| 1233 | /* Register per-cpu cpuidle_device. Cpuidle driver | 1217 | /* Register per-cpu cpuidle_device. Cpuidle driver |
| 1234 | * must already be registered before registering device | 1218 | * must already be registered before registering device |
