diff options
| -rw-r--r-- | drivers/acpi/processor_thermal.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 3b599abf2b40..641b5450a0db 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
| @@ -57,6 +57,27 @@ ACPI_MODULE_NAME("processor_thermal"); | |||
| 57 | static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); | 57 | static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); |
| 58 | static unsigned int acpi_thermal_cpufreq_is_init = 0; | 58 | static unsigned int acpi_thermal_cpufreq_is_init = 0; |
| 59 | 59 | ||
| 60 | #define reduction_pctg(cpu) \ | ||
| 61 | per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) | ||
| 62 | |||
| 63 | /* | ||
| 64 | * Emulate "per package data" using per cpu data (which should really be | ||
| 65 | * provided elsewhere) | ||
| 66 | * | ||
| 67 | * Note we can lose a CPU on cpu hotunplug, in this case we forget the state | ||
| 68 | * temporarily. Fortunately that's not a big issue here (I hope) | ||
| 69 | */ | ||
| 70 | static int phys_package_first_cpu(int cpu) | ||
| 71 | { | ||
| 72 | int i; | ||
| 73 | int id = topology_physical_package_id(cpu); | ||
| 74 | |||
| 75 | for_each_online_cpu(i) | ||
| 76 | if (topology_physical_package_id(i) == id) | ||
| 77 | return i; | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 60 | static int cpu_has_cpufreq(unsigned int cpu) | 81 | static int cpu_has_cpufreq(unsigned int cpu) |
| 61 | { | 82 | { |
| 62 | struct cpufreq_policy policy; | 83 | struct cpufreq_policy policy; |
| @@ -76,7 +97,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, | |||
| 76 | 97 | ||
| 77 | max_freq = ( | 98 | max_freq = ( |
| 78 | policy->cpuinfo.max_freq * | 99 | policy->cpuinfo.max_freq * |
| 79 | (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) | 100 | (100 - reduction_pctg(policy->cpu) * 20) |
| 80 | ) / 100; | 101 | ) / 100; |
| 81 | 102 | ||
| 82 | cpufreq_verify_within_limits(policy, 0, max_freq); | 103 | cpufreq_verify_within_limits(policy, 0, max_freq); |
| @@ -102,16 +123,28 @@ static int cpufreq_get_cur_state(unsigned int cpu) | |||
| 102 | if (!cpu_has_cpufreq(cpu)) | 123 | if (!cpu_has_cpufreq(cpu)) |
| 103 | return 0; | 124 | return 0; |
| 104 | 125 | ||
| 105 | return per_cpu(cpufreq_thermal_reduction_pctg, cpu); | 126 | return reduction_pctg(cpu); |
| 106 | } | 127 | } |
| 107 | 128 | ||
| 108 | static int cpufreq_set_cur_state(unsigned int cpu, int state) | 129 | static int cpufreq_set_cur_state(unsigned int cpu, int state) |
| 109 | { | 130 | { |
| 131 | int i; | ||
| 132 | |||
| 110 | if (!cpu_has_cpufreq(cpu)) | 133 | if (!cpu_has_cpufreq(cpu)) |
| 111 | return 0; | 134 | return 0; |
| 112 | 135 | ||
| 113 | per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; | 136 | reduction_pctg(cpu) = state; |
| 114 | cpufreq_update_policy(cpu); | 137 | |
| 138 | /* | ||
| 139 | * Update all the CPUs in the same package because they all | ||
| 140 | * contribute to the temperature and often share the same | ||
| 141 | * frequency. | ||
| 142 | */ | ||
| 143 | for_each_online_cpu(i) { | ||
| 144 | if (topology_physical_package_id(i) == | ||
| 145 | topology_physical_package_id(cpu)) | ||
| 146 | cpufreq_update_policy(i); | ||
| 147 | } | ||
| 115 | return 0; | 148 | return 0; |
| 116 | } | 149 | } |
| 117 | 150 | ||
| @@ -119,10 +152,6 @@ void acpi_thermal_cpufreq_init(void) | |||
| 119 | { | 152 | { |
| 120 | int i; | 153 | int i; |
| 121 | 154 | ||
| 122 | for (i = 0; i < nr_cpu_ids; i++) | ||
| 123 | if (cpu_present(i)) | ||
| 124 | per_cpu(cpufreq_thermal_reduction_pctg, i) = 0; | ||
| 125 | |||
| 126 | i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, | 155 | i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, |
| 127 | CPUFREQ_POLICY_NOTIFIER); | 156 | CPUFREQ_POLICY_NOTIFIER); |
| 128 | if (!i) | 157 | if (!i) |
