diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-09-01 09:52:35 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-09-01 09:52:35 -0400 |
commit | 4ffe18c2556f2848c4e57457915b08a63dc00fd5 (patch) | |
tree | 0e5045b2137095c9ad88cb7c5062e5801e377936 | |
parent | 498012511a060575a56551d28a10bb392aa361b5 (diff) | |
parent | 72e624de6e6f0d5a638fbc23842aa76ae048e9e7 (diff) |
Merge branch 'pm-cpufreq'
* pm-cpufreq: (53 commits)
cpufreq: speedstep-lib: Use monotonic clock
cpufreq: powernv: Increase the verbosity of OCC console messages
cpufreq: sfi: use kmemdup rather than duplicating its implementation
cpufreq: drop !cpufreq_driver check from cpufreq_parse_governor()
cpufreq: rename cpufreq_real_policy as cpufreq_user_policy
cpufreq: remove redundant 'policy' field from user_policy
cpufreq: remove redundant 'governor' field from user_policy
cpufreq: update user_policy.* on success
cpufreq: use memcpy() to copy policy
cpufreq: remove redundant CPUFREQ_INCOMPATIBLE notifier event
cpufreq: mediatek: Add MT8173 cpufreq driver
dt-bindings: mediatek: Add MT8173 CPU DVFS clock bindings
intel_pstate: append more Oracle OEM table id to vendor bypass list
intel_pstate: Add SKY-S support
intel_pstate: Fix possible overflow complained by Coverity
cpufreq: Correct a freq check in cpufreq_set_policy()
cpufreq: Lock CPU online/offline in cpufreq_register_driver()
cpufreq: Replace recover_policy with new_policy in cpufreq_online()
cpufreq: Separate CPU device registration from CPU online
cpufreq: powernv: Restore cpu frequency to policy->cur on unthrottling
...
28 files changed, 1280 insertions, 458 deletions
diff --git a/Documentation/cpu-freq/core.txt b/Documentation/cpu-freq/core.txt index 70933eadc308..ba78e7c2a069 100644 --- a/Documentation/cpu-freq/core.txt +++ b/Documentation/cpu-freq/core.txt | |||
@@ -55,16 +55,13 @@ transition notifiers. | |||
55 | ---------------------------- | 55 | ---------------------------- |
56 | 56 | ||
57 | These are notified when a new policy is intended to be set. Each | 57 | These are notified when a new policy is intended to be set. Each |
58 | CPUFreq policy notifier is called three times for a policy transition: | 58 | CPUFreq policy notifier is called twice for a policy transition: |
59 | 59 | ||
60 | 1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if | 60 | 1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if |
61 | they see a need for this - may it be thermal considerations or | 61 | they see a need for this - may it be thermal considerations or |
62 | hardware limitations. | 62 | hardware limitations. |
63 | 63 | ||
64 | 2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid | 64 | 2.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy |
65 | hardware failure. | ||
66 | |||
67 | 3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy | ||
68 | - if two hardware drivers failed to agree on a new policy before this | 65 | - if two hardware drivers failed to agree on a new policy before this |
69 | stage, the incompatible hardware shall be shut down, and the user | 66 | stage, the incompatible hardware shall be shut down, and the user |
70 | informed of this. | 67 | informed of this. |
diff --git a/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt b/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt new file mode 100644 index 000000000000..52b457c23eed --- /dev/null +++ b/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt | |||
@@ -0,0 +1,83 @@ | |||
1 | Device Tree Clock bindins for CPU DVFS of Mediatek MT8173 SoC | ||
2 | |||
3 | Required properties: | ||
4 | - clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names. | ||
5 | - clock-names: Should contain the following: | ||
6 | "cpu" - The multiplexer for clock input of CPU cluster. | ||
7 | "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock | ||
8 | source (usually MAINPLL) when the original CPU PLL is under | ||
9 | transition and not stable yet. | ||
10 | Please refer to Documentation/devicetree/bindings/clk/clock-bindings.txt for | ||
11 | generic clock consumer properties. | ||
12 | - proc-supply: Regulator for Vproc of CPU cluster. | ||
13 | |||
14 | Optional properties: | ||
15 | - sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver | ||
16 | needs to do "voltage tracking" to step by step scale up/down Vproc and | ||
17 | Vsram to fit SoC specific needs. When absent, the voltage scaling | ||
18 | flow is handled by hardware, hence no software "voltage tracking" is | ||
19 | needed. | ||
20 | |||
21 | Example: | ||
22 | -------- | ||
23 | cpu0: cpu@0 { | ||
24 | device_type = "cpu"; | ||
25 | compatible = "arm,cortex-a53"; | ||
26 | reg = <0x000>; | ||
27 | enable-method = "psci"; | ||
28 | cpu-idle-states = <&CPU_SLEEP_0>; | ||
29 | clocks = <&infracfg CLK_INFRA_CA53SEL>, | ||
30 | <&apmixedsys CLK_APMIXED_MAINPLL>; | ||
31 | clock-names = "cpu", "intermediate"; | ||
32 | }; | ||
33 | |||
34 | cpu1: cpu@1 { | ||
35 | device_type = "cpu"; | ||
36 | compatible = "arm,cortex-a53"; | ||
37 | reg = <0x001>; | ||
38 | enable-method = "psci"; | ||
39 | cpu-idle-states = <&CPU_SLEEP_0>; | ||
40 | clocks = <&infracfg CLK_INFRA_CA53SEL>, | ||
41 | <&apmixedsys CLK_APMIXED_MAINPLL>; | ||
42 | clock-names = "cpu", "intermediate"; | ||
43 | }; | ||
44 | |||
45 | cpu2: cpu@100 { | ||
46 | device_type = "cpu"; | ||
47 | compatible = "arm,cortex-a57"; | ||
48 | reg = <0x100>; | ||
49 | enable-method = "psci"; | ||
50 | cpu-idle-states = <&CPU_SLEEP_0>; | ||
51 | clocks = <&infracfg CLK_INFRA_CA57SEL>, | ||
52 | <&apmixedsys CLK_APMIXED_MAINPLL>; | ||
53 | clock-names = "cpu", "intermediate"; | ||
54 | }; | ||
55 | |||
56 | cpu3: cpu@101 { | ||
57 | device_type = "cpu"; | ||
58 | compatible = "arm,cortex-a57"; | ||
59 | reg = <0x101>; | ||
60 | enable-method = "psci"; | ||
61 | cpu-idle-states = <&CPU_SLEEP_0>; | ||
62 | clocks = <&infracfg CLK_INFRA_CA57SEL>, | ||
63 | <&apmixedsys CLK_APMIXED_MAINPLL>; | ||
64 | clock-names = "cpu", "intermediate"; | ||
65 | }; | ||
66 | |||
67 | &cpu0 { | ||
68 | proc-supply = <&mt6397_vpca15_reg>; | ||
69 | }; | ||
70 | |||
71 | &cpu1 { | ||
72 | proc-supply = <&mt6397_vpca15_reg>; | ||
73 | }; | ||
74 | |||
75 | &cpu2 { | ||
76 | proc-supply = <&da9211_vcpu_reg>; | ||
77 | sram-supply = <&mt6397_vsramca7_reg>; | ||
78 | }; | ||
79 | |||
80 | &cpu3 { | ||
81 | proc-supply = <&da9211_vcpu_reg>; | ||
82 | sram-supply = <&mt6397_vsramca7_reg>; | ||
83 | }; | ||
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index e9e4c52f3685..64dc9f547fb6 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h | |||
@@ -361,6 +361,7 @@ enum opal_msg_type { | |||
361 | OPAL_MSG_HMI_EVT, | 361 | OPAL_MSG_HMI_EVT, |
362 | OPAL_MSG_DPO, | 362 | OPAL_MSG_DPO, |
363 | OPAL_MSG_PRD, | 363 | OPAL_MSG_PRD, |
364 | OPAL_MSG_OCC, | ||
364 | OPAL_MSG_TYPE_MAX, | 365 | OPAL_MSG_TYPE_MAX, |
365 | }; | 366 | }; |
366 | 367 | ||
@@ -700,6 +701,17 @@ struct opal_prd_msg_header { | |||
700 | 701 | ||
701 | struct opal_prd_msg; | 702 | struct opal_prd_msg; |
702 | 703 | ||
704 | #define OCC_RESET 0 | ||
705 | #define OCC_LOAD 1 | ||
706 | #define OCC_THROTTLE 2 | ||
707 | #define OCC_MAX_THROTTLE_STATUS 5 | ||
708 | |||
709 | struct opal_occ_msg { | ||
710 | __be64 type; | ||
711 | __be64 chip; | ||
712 | __be64 throttle_status; | ||
713 | }; | ||
714 | |||
703 | /* | 715 | /* |
704 | * SG entries | 716 | * SG entries |
705 | * | 717 | * |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 53cfe8ba9799..bb01dea39fdc 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -83,7 +83,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, | |||
83 | if (ignore_ppc) | 83 | if (ignore_ppc) |
84 | return 0; | 84 | return 0; |
85 | 85 | ||
86 | if (event != CPUFREQ_INCOMPATIBLE) | 86 | if (event != CPUFREQ_ADJUST) |
87 | return 0; | 87 | return 0; |
88 | 88 | ||
89 | mutex_lock(&performance_mutex); | 89 | mutex_lock(&performance_mutex); |
@@ -780,9 +780,7 @@ acpi_processor_register_performance(struct acpi_processor_performance | |||
780 | 780 | ||
781 | EXPORT_SYMBOL(acpi_processor_register_performance); | 781 | EXPORT_SYMBOL(acpi_processor_register_performance); |
782 | 782 | ||
783 | void | 783 | void acpi_processor_unregister_performance(unsigned int cpu) |
784 | acpi_processor_unregister_performance(struct acpi_processor_performance | ||
785 | *performance, unsigned int cpu) | ||
786 | { | 784 | { |
787 | struct acpi_processor *pr; | 785 | struct acpi_processor *pr; |
788 | 786 | ||
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index cc8a71c267b8..2bacf24a19a9 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -130,6 +130,13 @@ config ARM_KIRKWOOD_CPUFREQ | |||
130 | This adds the CPUFreq driver for Marvell Kirkwood | 130 | This adds the CPUFreq driver for Marvell Kirkwood |
131 | SoCs. | 131 | SoCs. |
132 | 132 | ||
133 | config ARM_MT8173_CPUFREQ | ||
134 | bool "Mediatek MT8173 CPUFreq support" | ||
135 | depends on ARCH_MEDIATEK && REGULATOR | ||
136 | select PM_OPP | ||
137 | help | ||
138 | This adds the CPUFreq driver support for Mediatek MT8173 SoC. | ||
139 | |||
133 | config ARM_OMAP2PLUS_CPUFREQ | 140 | config ARM_OMAP2PLUS_CPUFREQ |
134 | bool "TI OMAP2+" | 141 | bool "TI OMAP2+" |
135 | depends on ARCH_OMAP2PLUS | 142 | depends on ARCH_OMAP2PLUS |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 2169bf792db7..9c75fafd2901 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o | |||
62 | obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o | 62 | obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o |
63 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o | 63 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o |
64 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o | 64 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o |
65 | obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt8173-cpufreq.o | ||
65 | obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o | 66 | obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o |
66 | obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o | 67 | obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o |
67 | obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o | 68 | obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 0136dfcdabf0..15b921a9248c 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -65,18 +65,21 @@ enum { | |||
65 | #define MSR_K7_HWCR_CPB_DIS (1ULL << 25) | 65 | #define MSR_K7_HWCR_CPB_DIS (1ULL << 25) |
66 | 66 | ||
67 | struct acpi_cpufreq_data { | 67 | struct acpi_cpufreq_data { |
68 | struct acpi_processor_performance *acpi_data; | ||
69 | struct cpufreq_frequency_table *freq_table; | 68 | struct cpufreq_frequency_table *freq_table; |
70 | unsigned int resume; | 69 | unsigned int resume; |
71 | unsigned int cpu_feature; | 70 | unsigned int cpu_feature; |
71 | unsigned int acpi_perf_cpu; | ||
72 | cpumask_var_t freqdomain_cpus; | 72 | cpumask_var_t freqdomain_cpus; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); | ||
76 | |||
77 | /* acpi_perf_data is a pointer to percpu data. */ | 75 | /* acpi_perf_data is a pointer to percpu data. */ |
78 | static struct acpi_processor_performance __percpu *acpi_perf_data; | 76 | static struct acpi_processor_performance __percpu *acpi_perf_data; |
79 | 77 | ||
78 | static inline struct acpi_processor_performance *to_perf_data(struct acpi_cpufreq_data *data) | ||
79 | { | ||
80 | return per_cpu_ptr(acpi_perf_data, data->acpi_perf_cpu); | ||
81 | } | ||
82 | |||
80 | static struct cpufreq_driver acpi_cpufreq_driver; | 83 | static struct cpufreq_driver acpi_cpufreq_driver; |
81 | 84 | ||
82 | static unsigned int acpi_pstate_strict; | 85 | static unsigned int acpi_pstate_strict; |
@@ -144,7 +147,7 @@ static int _store_boost(int val) | |||
144 | 147 | ||
145 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) | 148 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) |
146 | { | 149 | { |
147 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 150 | struct acpi_cpufreq_data *data = policy->driver_data; |
148 | 151 | ||
149 | return cpufreq_show_cpus(data->freqdomain_cpus, buf); | 152 | return cpufreq_show_cpus(data->freqdomain_cpus, buf); |
150 | } | 153 | } |
@@ -202,7 +205,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data) | |||
202 | struct acpi_processor_performance *perf; | 205 | struct acpi_processor_performance *perf; |
203 | int i; | 206 | int i; |
204 | 207 | ||
205 | perf = data->acpi_data; | 208 | perf = to_perf_data(data); |
206 | 209 | ||
207 | for (i = 0; i < perf->state_count; i++) { | 210 | for (i = 0; i < perf->state_count; i++) { |
208 | if (value == perf->states[i].status) | 211 | if (value == perf->states[i].status) |
@@ -221,7 +224,7 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) | |||
221 | else | 224 | else |
222 | msr &= INTEL_MSR_RANGE; | 225 | msr &= INTEL_MSR_RANGE; |
223 | 226 | ||
224 | perf = data->acpi_data; | 227 | perf = to_perf_data(data); |
225 | 228 | ||
226 | cpufreq_for_each_entry(pos, data->freq_table) | 229 | cpufreq_for_each_entry(pos, data->freq_table) |
227 | if (msr == perf->states[pos->driver_data].status) | 230 | if (msr == perf->states[pos->driver_data].status) |
@@ -327,7 +330,8 @@ static void drv_write(struct drv_cmd *cmd) | |||
327 | put_cpu(); | 330 | put_cpu(); |
328 | } | 331 | } |
329 | 332 | ||
330 | static u32 get_cur_val(const struct cpumask *mask) | 333 | static u32 |
334 | get_cur_val(const struct cpumask *mask, struct acpi_cpufreq_data *data) | ||
331 | { | 335 | { |
332 | struct acpi_processor_performance *perf; | 336 | struct acpi_processor_performance *perf; |
333 | struct drv_cmd cmd; | 337 | struct drv_cmd cmd; |
@@ -335,7 +339,7 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
335 | if (unlikely(cpumask_empty(mask))) | 339 | if (unlikely(cpumask_empty(mask))) |
336 | return 0; | 340 | return 0; |
337 | 341 | ||
338 | switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) { | 342 | switch (data->cpu_feature) { |
339 | case SYSTEM_INTEL_MSR_CAPABLE: | 343 | case SYSTEM_INTEL_MSR_CAPABLE: |
340 | cmd.type = SYSTEM_INTEL_MSR_CAPABLE; | 344 | cmd.type = SYSTEM_INTEL_MSR_CAPABLE; |
341 | cmd.addr.msr.reg = MSR_IA32_PERF_CTL; | 345 | cmd.addr.msr.reg = MSR_IA32_PERF_CTL; |
@@ -346,7 +350,7 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
346 | break; | 350 | break; |
347 | case SYSTEM_IO_CAPABLE: | 351 | case SYSTEM_IO_CAPABLE: |
348 | cmd.type = SYSTEM_IO_CAPABLE; | 352 | cmd.type = SYSTEM_IO_CAPABLE; |
349 | perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data; | 353 | perf = to_perf_data(data); |
350 | cmd.addr.io.port = perf->control_register.address; | 354 | cmd.addr.io.port = perf->control_register.address; |
351 | cmd.addr.io.bit_width = perf->control_register.bit_width; | 355 | cmd.addr.io.bit_width = perf->control_register.bit_width; |
352 | break; | 356 | break; |
@@ -364,19 +368,24 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
364 | 368 | ||
365 | static unsigned int get_cur_freq_on_cpu(unsigned int cpu) | 369 | static unsigned int get_cur_freq_on_cpu(unsigned int cpu) |
366 | { | 370 | { |
367 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu); | 371 | struct acpi_cpufreq_data *data; |
372 | struct cpufreq_policy *policy; | ||
368 | unsigned int freq; | 373 | unsigned int freq; |
369 | unsigned int cached_freq; | 374 | unsigned int cached_freq; |
370 | 375 | ||
371 | pr_debug("get_cur_freq_on_cpu (%d)\n", cpu); | 376 | pr_debug("get_cur_freq_on_cpu (%d)\n", cpu); |
372 | 377 | ||
373 | if (unlikely(data == NULL || | 378 | policy = cpufreq_cpu_get(cpu); |
374 | data->acpi_data == NULL || data->freq_table == NULL)) { | 379 | if (unlikely(!policy)) |
375 | return 0; | 380 | return 0; |
376 | } | ||
377 | 381 | ||
378 | cached_freq = data->freq_table[data->acpi_data->state].frequency; | 382 | data = policy->driver_data; |
379 | freq = extract_freq(get_cur_val(cpumask_of(cpu)), data); | 383 | cpufreq_cpu_put(policy); |
384 | if (unlikely(!data || !data->freq_table)) | ||
385 | return 0; | ||
386 | |||
387 | cached_freq = data->freq_table[to_perf_data(data)->state].frequency; | ||
388 | freq = extract_freq(get_cur_val(cpumask_of(cpu), data), data); | ||
380 | if (freq != cached_freq) { | 389 | if (freq != cached_freq) { |
381 | /* | 390 | /* |
382 | * The dreaded BIOS frequency change behind our back. | 391 | * The dreaded BIOS frequency change behind our back. |
@@ -397,7 +406,7 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, | |||
397 | unsigned int i; | 406 | unsigned int i; |
398 | 407 | ||
399 | for (i = 0; i < 100; i++) { | 408 | for (i = 0; i < 100; i++) { |
400 | cur_freq = extract_freq(get_cur_val(mask), data); | 409 | cur_freq = extract_freq(get_cur_val(mask, data), data); |
401 | if (cur_freq == freq) | 410 | if (cur_freq == freq) |
402 | return 1; | 411 | return 1; |
403 | udelay(10); | 412 | udelay(10); |
@@ -408,18 +417,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, | |||
408 | static int acpi_cpufreq_target(struct cpufreq_policy *policy, | 417 | static int acpi_cpufreq_target(struct cpufreq_policy *policy, |
409 | unsigned int index) | 418 | unsigned int index) |
410 | { | 419 | { |
411 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 420 | struct acpi_cpufreq_data *data = policy->driver_data; |
412 | struct acpi_processor_performance *perf; | 421 | struct acpi_processor_performance *perf; |
413 | struct drv_cmd cmd; | 422 | struct drv_cmd cmd; |
414 | unsigned int next_perf_state = 0; /* Index into perf table */ | 423 | unsigned int next_perf_state = 0; /* Index into perf table */ |
415 | int result = 0; | 424 | int result = 0; |
416 | 425 | ||
417 | if (unlikely(data == NULL || | 426 | if (unlikely(data == NULL || data->freq_table == NULL)) { |
418 | data->acpi_data == NULL || data->freq_table == NULL)) { | ||
419 | return -ENODEV; | 427 | return -ENODEV; |
420 | } | 428 | } |
421 | 429 | ||
422 | perf = data->acpi_data; | 430 | perf = to_perf_data(data); |
423 | next_perf_state = data->freq_table[index].driver_data; | 431 | next_perf_state = data->freq_table[index].driver_data; |
424 | if (perf->state == next_perf_state) { | 432 | if (perf->state == next_perf_state) { |
425 | if (unlikely(data->resume)) { | 433 | if (unlikely(data->resume)) { |
@@ -482,8 +490,9 @@ out: | |||
482 | static unsigned long | 490 | static unsigned long |
483 | acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | 491 | acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) |
484 | { | 492 | { |
485 | struct acpi_processor_performance *perf = data->acpi_data; | 493 | struct acpi_processor_performance *perf; |
486 | 494 | ||
495 | perf = to_perf_data(data); | ||
487 | if (cpu_khz) { | 496 | if (cpu_khz) { |
488 | /* search the closest match to cpu_khz */ | 497 | /* search the closest match to cpu_khz */ |
489 | unsigned int i; | 498 | unsigned int i; |
@@ -672,17 +681,17 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
672 | goto err_free; | 681 | goto err_free; |
673 | } | 682 | } |
674 | 683 | ||
675 | data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu); | 684 | perf = per_cpu_ptr(acpi_perf_data, cpu); |
676 | per_cpu(acfreq_data, cpu) = data; | 685 | data->acpi_perf_cpu = cpu; |
686 | policy->driver_data = data; | ||
677 | 687 | ||
678 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) | 688 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) |
679 | acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; | 689 | acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; |
680 | 690 | ||
681 | result = acpi_processor_register_performance(data->acpi_data, cpu); | 691 | result = acpi_processor_register_performance(perf, cpu); |
682 | if (result) | 692 | if (result) |
683 | goto err_free_mask; | 693 | goto err_free_mask; |
684 | 694 | ||
685 | perf = data->acpi_data; | ||
686 | policy->shared_type = perf->shared_type; | 695 | policy->shared_type = perf->shared_type; |
687 | 696 | ||
688 | /* | 697 | /* |
@@ -838,26 +847,25 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
838 | err_freqfree: | 847 | err_freqfree: |
839 | kfree(data->freq_table); | 848 | kfree(data->freq_table); |
840 | err_unreg: | 849 | err_unreg: |
841 | acpi_processor_unregister_performance(perf, cpu); | 850 | acpi_processor_unregister_performance(cpu); |
842 | err_free_mask: | 851 | err_free_mask: |
843 | free_cpumask_var(data->freqdomain_cpus); | 852 | free_cpumask_var(data->freqdomain_cpus); |
844 | err_free: | 853 | err_free: |
845 | kfree(data); | 854 | kfree(data); |
846 | per_cpu(acfreq_data, cpu) = NULL; | 855 | policy->driver_data = NULL; |
847 | 856 | ||
848 | return result; | 857 | return result; |
849 | } | 858 | } |
850 | 859 | ||
851 | static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) | 860 | static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) |
852 | { | 861 | { |
853 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 862 | struct acpi_cpufreq_data *data = policy->driver_data; |
854 | 863 | ||
855 | pr_debug("acpi_cpufreq_cpu_exit\n"); | 864 | pr_debug("acpi_cpufreq_cpu_exit\n"); |
856 | 865 | ||
857 | if (data) { | 866 | if (data) { |
858 | per_cpu(acfreq_data, policy->cpu) = NULL; | 867 | policy->driver_data = NULL; |
859 | acpi_processor_unregister_performance(data->acpi_data, | 868 | acpi_processor_unregister_performance(data->acpi_perf_cpu); |
860 | policy->cpu); | ||
861 | free_cpumask_var(data->freqdomain_cpus); | 869 | free_cpumask_var(data->freqdomain_cpus); |
862 | kfree(data->freq_table); | 870 | kfree(data->freq_table); |
863 | kfree(data); | 871 | kfree(data); |
@@ -868,7 +876,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) | |||
868 | 876 | ||
869 | static int acpi_cpufreq_resume(struct cpufreq_policy *policy) | 877 | static int acpi_cpufreq_resume(struct cpufreq_policy *policy) |
870 | { | 878 | { |
871 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 879 | struct acpi_cpufreq_data *data = policy->driver_data; |
872 | 880 | ||
873 | pr_debug("acpi_cpufreq_resume\n"); | 881 | pr_debug("acpi_cpufreq_resume\n"); |
874 | 882 | ||
@@ -880,7 +888,9 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy) | |||
880 | static struct freq_attr *acpi_cpufreq_attr[] = { | 888 | static struct freq_attr *acpi_cpufreq_attr[] = { |
881 | &cpufreq_freq_attr_scaling_available_freqs, | 889 | &cpufreq_freq_attr_scaling_available_freqs, |
882 | &freqdomain_cpus, | 890 | &freqdomain_cpus, |
883 | NULL, /* this is a placeholder for cpb, do not remove */ | 891 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB |
892 | &cpb, | ||
893 | #endif | ||
884 | NULL, | 894 | NULL, |
885 | }; | 895 | }; |
886 | 896 | ||
@@ -953,17 +963,16 @@ static int __init acpi_cpufreq_init(void) | |||
953 | * only if configured. This is considered legacy code, which | 963 | * only if configured. This is considered legacy code, which |
954 | * will probably be removed at some point in the future. | 964 | * will probably be removed at some point in the future. |
955 | */ | 965 | */ |
956 | if (check_amd_hwpstate_cpu(0)) { | 966 | if (!check_amd_hwpstate_cpu(0)) { |
957 | struct freq_attr **iter; | 967 | struct freq_attr **attr; |
958 | |||
959 | pr_debug("adding sysfs entry for cpb\n"); | ||
960 | 968 | ||
961 | for (iter = acpi_cpufreq_attr; *iter != NULL; iter++) | 969 | pr_debug("CPB unsupported, do not expose it\n"); |
962 | ; | ||
963 | 970 | ||
964 | /* make sure there is a terminator behind it */ | 971 | for (attr = acpi_cpufreq_attr; *attr; attr++) |
965 | if (iter[1] == NULL) | 972 | if (*attr == &cpb) { |
966 | *iter = &cpb; | 973 | *attr = NULL; |
974 | break; | ||
975 | } | ||
967 | } | 976 | } |
968 | #endif | 977 | #endif |
969 | acpi_cpufreq_boost_init(); | 978 | acpi_cpufreq_boost_init(); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7a3c30c4336f..a05cc75cc45d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -112,12 +112,6 @@ static inline bool has_target(void) | |||
112 | return cpufreq_driver->target_index || cpufreq_driver->target; | 112 | return cpufreq_driver->target_index || cpufreq_driver->target; |
113 | } | 113 | } |
114 | 114 | ||
115 | /* | ||
116 | * rwsem to guarantee that cpufreq driver module doesn't unload during critical | ||
117 | * sections | ||
118 | */ | ||
119 | static DECLARE_RWSEM(cpufreq_rwsem); | ||
120 | |||
121 | /* internal prototypes */ | 115 | /* internal prototypes */ |
122 | static int __cpufreq_governor(struct cpufreq_policy *policy, | 116 | static int __cpufreq_governor(struct cpufreq_policy *policy, |
123 | unsigned int event); | 117 | unsigned int event); |
@@ -277,10 +271,6 @@ EXPORT_SYMBOL_GPL(cpufreq_generic_get); | |||
277 | * If corresponding call cpufreq_cpu_put() isn't made, the policy wouldn't be | 271 | * If corresponding call cpufreq_cpu_put() isn't made, the policy wouldn't be |
278 | * freed as that depends on the kobj count. | 272 | * freed as that depends on the kobj count. |
279 | * | 273 | * |
280 | * It also takes a read-lock of 'cpufreq_rwsem' and doesn't put it back if a | ||
281 | * valid policy is found. This is done to make sure the driver doesn't get | ||
282 | * unregistered while the policy is being used. | ||
283 | * | ||
284 | * Return: A valid policy on success, otherwise NULL on failure. | 274 | * Return: A valid policy on success, otherwise NULL on failure. |
285 | */ | 275 | */ |
286 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 276 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
@@ -291,9 +281,6 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | |||
291 | if (WARN_ON(cpu >= nr_cpu_ids)) | 281 | if (WARN_ON(cpu >= nr_cpu_ids)) |
292 | return NULL; | 282 | return NULL; |
293 | 283 | ||
294 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
295 | return NULL; | ||
296 | |||
297 | /* get the cpufreq driver */ | 284 | /* get the cpufreq driver */ |
298 | read_lock_irqsave(&cpufreq_driver_lock, flags); | 285 | read_lock_irqsave(&cpufreq_driver_lock, flags); |
299 | 286 | ||
@@ -306,9 +293,6 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | |||
306 | 293 | ||
307 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 294 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); |
308 | 295 | ||
309 | if (!policy) | ||
310 | up_read(&cpufreq_rwsem); | ||
311 | |||
312 | return policy; | 296 | return policy; |
313 | } | 297 | } |
314 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); | 298 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); |
@@ -320,13 +304,10 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_get); | |||
320 | * | 304 | * |
321 | * This decrements the kobject reference count incremented earlier by calling | 305 | * This decrements the kobject reference count incremented earlier by calling |
322 | * cpufreq_cpu_get(). | 306 | * cpufreq_cpu_get(). |
323 | * | ||
324 | * It also drops the read-lock of 'cpufreq_rwsem' taken at cpufreq_cpu_get(). | ||
325 | */ | 307 | */ |
326 | void cpufreq_cpu_put(struct cpufreq_policy *policy) | 308 | void cpufreq_cpu_put(struct cpufreq_policy *policy) |
327 | { | 309 | { |
328 | kobject_put(&policy->kobj); | 310 | kobject_put(&policy->kobj); |
329 | up_read(&cpufreq_rwsem); | ||
330 | } | 311 | } |
331 | EXPORT_SYMBOL_GPL(cpufreq_cpu_put); | 312 | EXPORT_SYMBOL_GPL(cpufreq_cpu_put); |
332 | 313 | ||
@@ -539,9 +520,6 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
539 | { | 520 | { |
540 | int err = -EINVAL; | 521 | int err = -EINVAL; |
541 | 522 | ||
542 | if (!cpufreq_driver) | ||
543 | goto out; | ||
544 | |||
545 | if (cpufreq_driver->setpolicy) { | 523 | if (cpufreq_driver->setpolicy) { |
546 | if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { | 524 | if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { |
547 | *policy = CPUFREQ_POLICY_PERFORMANCE; | 525 | *policy = CPUFREQ_POLICY_PERFORMANCE; |
@@ -576,7 +554,6 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
576 | 554 | ||
577 | mutex_unlock(&cpufreq_governor_mutex); | 555 | mutex_unlock(&cpufreq_governor_mutex); |
578 | } | 556 | } |
579 | out: | ||
580 | return err; | 557 | return err; |
581 | } | 558 | } |
582 | 559 | ||
@@ -625,9 +602,7 @@ static ssize_t store_##file_name \ | |||
625 | int ret, temp; \ | 602 | int ret, temp; \ |
626 | struct cpufreq_policy new_policy; \ | 603 | struct cpufreq_policy new_policy; \ |
627 | \ | 604 | \ |
628 | ret = cpufreq_get_policy(&new_policy, policy->cpu); \ | 605 | memcpy(&new_policy, policy, sizeof(*policy)); \ |
629 | if (ret) \ | ||
630 | return -EINVAL; \ | ||
631 | \ | 606 | \ |
632 | ret = sscanf(buf, "%u", &new_policy.object); \ | 607 | ret = sscanf(buf, "%u", &new_policy.object); \ |
633 | if (ret != 1) \ | 608 | if (ret != 1) \ |
@@ -681,9 +656,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, | |||
681 | char str_governor[16]; | 656 | char str_governor[16]; |
682 | struct cpufreq_policy new_policy; | 657 | struct cpufreq_policy new_policy; |
683 | 658 | ||
684 | ret = cpufreq_get_policy(&new_policy, policy->cpu); | 659 | memcpy(&new_policy, policy, sizeof(*policy)); |
685 | if (ret) | ||
686 | return ret; | ||
687 | 660 | ||
688 | ret = sscanf(buf, "%15s", str_governor); | 661 | ret = sscanf(buf, "%15s", str_governor); |
689 | if (ret != 1) | 662 | if (ret != 1) |
@@ -694,14 +667,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, | |||
694 | return -EINVAL; | 667 | return -EINVAL; |
695 | 668 | ||
696 | ret = cpufreq_set_policy(policy, &new_policy); | 669 | ret = cpufreq_set_policy(policy, &new_policy); |
697 | 670 | return ret ? ret : count; | |
698 | policy->user_policy.policy = policy->policy; | ||
699 | policy->user_policy.governor = policy->governor; | ||
700 | |||
701 | if (ret) | ||
702 | return ret; | ||
703 | else | ||
704 | return count; | ||
705 | } | 671 | } |
706 | 672 | ||
707 | /** | 673 | /** |
@@ -851,9 +817,6 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
851 | struct freq_attr *fattr = to_attr(attr); | 817 | struct freq_attr *fattr = to_attr(attr); |
852 | ssize_t ret; | 818 | ssize_t ret; |
853 | 819 | ||
854 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
855 | return -EINVAL; | ||
856 | |||
857 | down_read(&policy->rwsem); | 820 | down_read(&policy->rwsem); |
858 | 821 | ||
859 | if (fattr->show) | 822 | if (fattr->show) |
@@ -862,7 +825,6 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
862 | ret = -EIO; | 825 | ret = -EIO; |
863 | 826 | ||
864 | up_read(&policy->rwsem); | 827 | up_read(&policy->rwsem); |
865 | up_read(&cpufreq_rwsem); | ||
866 | 828 | ||
867 | return ret; | 829 | return ret; |
868 | } | 830 | } |
@@ -879,9 +841,6 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
879 | if (!cpu_online(policy->cpu)) | 841 | if (!cpu_online(policy->cpu)) |
880 | goto unlock; | 842 | goto unlock; |
881 | 843 | ||
882 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
883 | goto unlock; | ||
884 | |||
885 | down_write(&policy->rwsem); | 844 | down_write(&policy->rwsem); |
886 | 845 | ||
887 | /* Updating inactive policies is invalid, so avoid doing that. */ | 846 | /* Updating inactive policies is invalid, so avoid doing that. */ |
@@ -897,8 +856,6 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
897 | 856 | ||
898 | unlock_policy_rwsem: | 857 | unlock_policy_rwsem: |
899 | up_write(&policy->rwsem); | 858 | up_write(&policy->rwsem); |
900 | |||
901 | up_read(&cpufreq_rwsem); | ||
902 | unlock: | 859 | unlock: |
903 | put_online_cpus(); | 860 | put_online_cpus(); |
904 | 861 | ||
@@ -1027,8 +984,7 @@ static void cpufreq_remove_dev_symlink(struct cpufreq_policy *policy) | |||
1027 | } | 984 | } |
1028 | } | 985 | } |
1029 | 986 | ||
1030 | static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, | 987 | static int cpufreq_add_dev_interface(struct cpufreq_policy *policy) |
1031 | struct device *dev) | ||
1032 | { | 988 | { |
1033 | struct freq_attr **drv_attr; | 989 | struct freq_attr **drv_attr; |
1034 | int ret = 0; | 990 | int ret = 0; |
@@ -1060,11 +1016,10 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, | |||
1060 | return cpufreq_add_dev_symlink(policy); | 1016 | return cpufreq_add_dev_symlink(policy); |
1061 | } | 1017 | } |
1062 | 1018 | ||
1063 | static void cpufreq_init_policy(struct cpufreq_policy *policy) | 1019 | static int cpufreq_init_policy(struct cpufreq_policy *policy) |
1064 | { | 1020 | { |
1065 | struct cpufreq_governor *gov = NULL; | 1021 | struct cpufreq_governor *gov = NULL; |
1066 | struct cpufreq_policy new_policy; | 1022 | struct cpufreq_policy new_policy; |
1067 | int ret = 0; | ||
1068 | 1023 | ||
1069 | memcpy(&new_policy, policy, sizeof(*policy)); | 1024 | memcpy(&new_policy, policy, sizeof(*policy)); |
1070 | 1025 | ||
@@ -1083,16 +1038,10 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) | |||
1083 | cpufreq_parse_governor(gov->name, &new_policy.policy, NULL); | 1038 | cpufreq_parse_governor(gov->name, &new_policy.policy, NULL); |
1084 | 1039 | ||
1085 | /* set default policy */ | 1040 | /* set default policy */ |
1086 | ret = cpufreq_set_policy(policy, &new_policy); | 1041 | return cpufreq_set_policy(policy, &new_policy); |
1087 | if (ret) { | ||
1088 | pr_debug("setting policy failed\n"); | ||
1089 | if (cpufreq_driver->exit) | ||
1090 | cpufreq_driver->exit(policy); | ||
1091 | } | ||
1092 | } | 1042 | } |
1093 | 1043 | ||
1094 | static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | 1044 | static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) |
1095 | unsigned int cpu, struct device *dev) | ||
1096 | { | 1045 | { |
1097 | int ret = 0; | 1046 | int ret = 0; |
1098 | 1047 | ||
@@ -1126,33 +1075,15 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | |||
1126 | return 0; | 1075 | return 0; |
1127 | } | 1076 | } |
1128 | 1077 | ||
1129 | static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) | 1078 | static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) |
1130 | { | ||
1131 | struct cpufreq_policy *policy; | ||
1132 | unsigned long flags; | ||
1133 | |||
1134 | read_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1135 | policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1136 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1137 | |||
1138 | if (likely(policy)) { | ||
1139 | /* Policy should be inactive here */ | ||
1140 | WARN_ON(!policy_is_inactive(policy)); | ||
1141 | |||
1142 | down_write(&policy->rwsem); | ||
1143 | policy->cpu = cpu; | ||
1144 | policy->governor = NULL; | ||
1145 | up_write(&policy->rwsem); | ||
1146 | } | ||
1147 | |||
1148 | return policy; | ||
1149 | } | ||
1150 | |||
1151 | static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev) | ||
1152 | { | 1079 | { |
1080 | struct device *dev = get_cpu_device(cpu); | ||
1153 | struct cpufreq_policy *policy; | 1081 | struct cpufreq_policy *policy; |
1154 | int ret; | 1082 | int ret; |
1155 | 1083 | ||
1084 | if (WARN_ON(!dev)) | ||
1085 | return NULL; | ||
1086 | |||
1156 | policy = kzalloc(sizeof(*policy), GFP_KERNEL); | 1087 | policy = kzalloc(sizeof(*policy), GFP_KERNEL); |
1157 | if (!policy) | 1088 | if (!policy) |
1158 | return NULL; | 1089 | return NULL; |
@@ -1180,10 +1111,10 @@ static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev) | |||
1180 | init_completion(&policy->kobj_unregister); | 1111 | init_completion(&policy->kobj_unregister); |
1181 | INIT_WORK(&policy->update, handle_update); | 1112 | INIT_WORK(&policy->update, handle_update); |
1182 | 1113 | ||
1183 | policy->cpu = dev->id; | 1114 | policy->cpu = cpu; |
1184 | 1115 | ||
1185 | /* Set this once on allocation */ | 1116 | /* Set this once on allocation */ |
1186 | policy->kobj_cpu = dev->id; | 1117 | policy->kobj_cpu = cpu; |
1187 | 1118 | ||
1188 | return policy; | 1119 | return policy; |
1189 | 1120 | ||
@@ -1245,59 +1176,34 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy, bool notify) | |||
1245 | kfree(policy); | 1176 | kfree(policy); |
1246 | } | 1177 | } |
1247 | 1178 | ||
1248 | /** | 1179 | static int cpufreq_online(unsigned int cpu) |
1249 | * cpufreq_add_dev - add a CPU device | ||
1250 | * | ||
1251 | * Adds the cpufreq interface for a CPU device. | ||
1252 | * | ||
1253 | * The Oracle says: try running cpufreq registration/unregistration concurrently | ||
1254 | * with with cpu hotplugging and all hell will break loose. Tried to clean this | ||
1255 | * mess up, but more thorough testing is needed. - Mathieu | ||
1256 | */ | ||
1257 | static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | ||
1258 | { | 1180 | { |
1259 | unsigned int j, cpu = dev->id; | ||
1260 | int ret = -ENOMEM; | ||
1261 | struct cpufreq_policy *policy; | 1181 | struct cpufreq_policy *policy; |
1182 | bool new_policy; | ||
1262 | unsigned long flags; | 1183 | unsigned long flags; |
1263 | bool recover_policy = !sif; | 1184 | unsigned int j; |
1264 | 1185 | int ret; | |
1265 | pr_debug("adding CPU %u\n", cpu); | ||
1266 | |||
1267 | if (cpu_is_offline(cpu)) { | ||
1268 | /* | ||
1269 | * Only possible if we are here from the subsys_interface add | ||
1270 | * callback. A hotplug notifier will follow and we will handle | ||
1271 | * it as CPU online then. For now, just create the sysfs link, | ||
1272 | * unless there is no policy or the link is already present. | ||
1273 | */ | ||
1274 | policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1275 | return policy && !cpumask_test_and_set_cpu(cpu, policy->real_cpus) | ||
1276 | ? add_cpu_dev_symlink(policy, cpu) : 0; | ||
1277 | } | ||
1278 | 1186 | ||
1279 | if (!down_read_trylock(&cpufreq_rwsem)) | 1187 | pr_debug("%s: bringing CPU%u online\n", __func__, cpu); |
1280 | return 0; | ||
1281 | 1188 | ||
1282 | /* Check if this CPU already has a policy to manage it */ | 1189 | /* Check if this CPU already has a policy to manage it */ |
1283 | policy = per_cpu(cpufreq_cpu_data, cpu); | 1190 | policy = per_cpu(cpufreq_cpu_data, cpu); |
1284 | if (policy && !policy_is_inactive(policy)) { | 1191 | if (policy) { |
1285 | WARN_ON(!cpumask_test_cpu(cpu, policy->related_cpus)); | 1192 | WARN_ON(!cpumask_test_cpu(cpu, policy->related_cpus)); |
1286 | ret = cpufreq_add_policy_cpu(policy, cpu, dev); | 1193 | if (!policy_is_inactive(policy)) |
1287 | up_read(&cpufreq_rwsem); | 1194 | return cpufreq_add_policy_cpu(policy, cpu); |
1288 | return ret; | ||
1289 | } | ||
1290 | 1195 | ||
1291 | /* | 1196 | /* This is the only online CPU for the policy. Start over. */ |
1292 | * Restore the saved policy when doing light-weight init and fall back | 1197 | new_policy = false; |
1293 | * to the full init if that fails. | 1198 | down_write(&policy->rwsem); |
1294 | */ | 1199 | policy->cpu = cpu; |
1295 | policy = recover_policy ? cpufreq_policy_restore(cpu) : NULL; | 1200 | policy->governor = NULL; |
1296 | if (!policy) { | 1201 | up_write(&policy->rwsem); |
1297 | recover_policy = false; | 1202 | } else { |
1298 | policy = cpufreq_policy_alloc(dev); | 1203 | new_policy = true; |
1204 | policy = cpufreq_policy_alloc(cpu); | ||
1299 | if (!policy) | 1205 | if (!policy) |
1300 | goto nomem_out; | 1206 | return -ENOMEM; |
1301 | } | 1207 | } |
1302 | 1208 | ||
1303 | cpumask_copy(policy->cpus, cpumask_of(cpu)); | 1209 | cpumask_copy(policy->cpus, cpumask_of(cpu)); |
@@ -1308,17 +1214,17 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1308 | ret = cpufreq_driver->init(policy); | 1214 | ret = cpufreq_driver->init(policy); |
1309 | if (ret) { | 1215 | if (ret) { |
1310 | pr_debug("initialization failed\n"); | 1216 | pr_debug("initialization failed\n"); |
1311 | goto err_set_policy_cpu; | 1217 | goto out_free_policy; |
1312 | } | 1218 | } |
1313 | 1219 | ||
1314 | down_write(&policy->rwsem); | 1220 | down_write(&policy->rwsem); |
1315 | 1221 | ||
1316 | /* related cpus should atleast have policy->cpus */ | 1222 | if (new_policy) { |
1317 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | 1223 | /* related_cpus should at least include policy->cpus. */ |
1318 | 1224 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | |
1319 | /* Remember which CPUs have been present at the policy creation time. */ | 1225 | /* Remember CPUs present at the policy creation time. */ |
1320 | if (!recover_policy) | ||
1321 | cpumask_and(policy->real_cpus, policy->cpus, cpu_present_mask); | 1226 | cpumask_and(policy->real_cpus, policy->cpus, cpu_present_mask); |
1227 | } | ||
1322 | 1228 | ||
1323 | /* | 1229 | /* |
1324 | * affected cpus must always be the one, which are online. We aren't | 1230 | * affected cpus must always be the one, which are online. We aren't |
@@ -1326,7 +1232,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1326 | */ | 1232 | */ |
1327 | cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); | 1233 | cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); |
1328 | 1234 | ||
1329 | if (!recover_policy) { | 1235 | if (new_policy) { |
1330 | policy->user_policy.min = policy->min; | 1236 | policy->user_policy.min = policy->min; |
1331 | policy->user_policy.max = policy->max; | 1237 | policy->user_policy.max = policy->max; |
1332 | 1238 | ||
@@ -1340,7 +1246,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1340 | policy->cur = cpufreq_driver->get(policy->cpu); | 1246 | policy->cur = cpufreq_driver->get(policy->cpu); |
1341 | if (!policy->cur) { | 1247 | if (!policy->cur) { |
1342 | pr_err("%s: ->get() failed\n", __func__); | 1248 | pr_err("%s: ->get() failed\n", __func__); |
1343 | goto err_get_freq; | 1249 | goto out_exit_policy; |
1344 | } | 1250 | } |
1345 | } | 1251 | } |
1346 | 1252 | ||
@@ -1387,10 +1293,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1387 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1293 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1388 | CPUFREQ_START, policy); | 1294 | CPUFREQ_START, policy); |
1389 | 1295 | ||
1390 | if (!recover_policy) { | 1296 | if (new_policy) { |
1391 | ret = cpufreq_add_dev_interface(policy, dev); | 1297 | ret = cpufreq_add_dev_interface(policy); |
1392 | if (ret) | 1298 | if (ret) |
1393 | goto err_out_unregister; | 1299 | goto out_exit_policy; |
1394 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1300 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1395 | CPUFREQ_CREATE_POLICY, policy); | 1301 | CPUFREQ_CREATE_POLICY, policy); |
1396 | 1302 | ||
@@ -1399,18 +1305,19 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1399 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1305 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1400 | } | 1306 | } |
1401 | 1307 | ||
1402 | cpufreq_init_policy(policy); | 1308 | ret = cpufreq_init_policy(policy); |
1403 | 1309 | if (ret) { | |
1404 | if (!recover_policy) { | 1310 | pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n", |
1405 | policy->user_policy.policy = policy->policy; | 1311 | __func__, cpu, ret); |
1406 | policy->user_policy.governor = policy->governor; | 1312 | /* cpufreq_policy_free() will notify based on this */ |
1313 | new_policy = false; | ||
1314 | goto out_exit_policy; | ||
1407 | } | 1315 | } |
1316 | |||
1408 | up_write(&policy->rwsem); | 1317 | up_write(&policy->rwsem); |
1409 | 1318 | ||
1410 | kobject_uevent(&policy->kobj, KOBJ_ADD); | 1319 | kobject_uevent(&policy->kobj, KOBJ_ADD); |
1411 | 1320 | ||
1412 | up_read(&cpufreq_rwsem); | ||
1413 | |||
1414 | /* Callback for handling stuff after policy is ready */ | 1321 | /* Callback for handling stuff after policy is ready */ |
1415 | if (cpufreq_driver->ready) | 1322 | if (cpufreq_driver->ready) |
1416 | cpufreq_driver->ready(policy); | 1323 | cpufreq_driver->ready(policy); |
@@ -1419,24 +1326,47 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1419 | 1326 | ||
1420 | return 0; | 1327 | return 0; |
1421 | 1328 | ||
1422 | err_out_unregister: | 1329 | out_exit_policy: |
1423 | err_get_freq: | ||
1424 | up_write(&policy->rwsem); | 1330 | up_write(&policy->rwsem); |
1425 | 1331 | ||
1426 | if (cpufreq_driver->exit) | 1332 | if (cpufreq_driver->exit) |
1427 | cpufreq_driver->exit(policy); | 1333 | cpufreq_driver->exit(policy); |
1428 | err_set_policy_cpu: | 1334 | out_free_policy: |
1429 | cpufreq_policy_free(policy, recover_policy); | 1335 | cpufreq_policy_free(policy, !new_policy); |
1430 | nomem_out: | 1336 | return ret; |
1431 | up_read(&cpufreq_rwsem); | 1337 | } |
1338 | |||
1339 | /** | ||
1340 | * cpufreq_add_dev - the cpufreq interface for a CPU device. | ||
1341 | * @dev: CPU device. | ||
1342 | * @sif: Subsystem interface structure pointer (not used) | ||
1343 | */ | ||
1344 | static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | ||
1345 | { | ||
1346 | unsigned cpu = dev->id; | ||
1347 | int ret; | ||
1348 | |||
1349 | dev_dbg(dev, "%s: adding CPU%u\n", __func__, cpu); | ||
1350 | |||
1351 | if (cpu_online(cpu)) { | ||
1352 | ret = cpufreq_online(cpu); | ||
1353 | } else { | ||
1354 | /* | ||
1355 | * A hotplug notifier will follow and we will handle it as CPU | ||
1356 | * online then. For now, just create the sysfs link, unless | ||
1357 | * there is no policy or the link is already present. | ||
1358 | */ | ||
1359 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1360 | |||
1361 | ret = policy && !cpumask_test_and_set_cpu(cpu, policy->real_cpus) | ||
1362 | ? add_cpu_dev_symlink(policy, cpu) : 0; | ||
1363 | } | ||
1432 | 1364 | ||
1433 | return ret; | 1365 | return ret; |
1434 | } | 1366 | } |
1435 | 1367 | ||
1436 | static int __cpufreq_remove_dev_prepare(struct device *dev) | 1368 | static void cpufreq_offline_prepare(unsigned int cpu) |
1437 | { | 1369 | { |
1438 | unsigned int cpu = dev->id; | ||
1439 | int ret = 0; | ||
1440 | struct cpufreq_policy *policy; | 1370 | struct cpufreq_policy *policy; |
1441 | 1371 | ||
1442 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); | 1372 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); |
@@ -1444,11 +1374,11 @@ static int __cpufreq_remove_dev_prepare(struct device *dev) | |||
1444 | policy = cpufreq_cpu_get_raw(cpu); | 1374 | policy = cpufreq_cpu_get_raw(cpu); |
1445 | if (!policy) { | 1375 | if (!policy) { |
1446 | pr_debug("%s: No cpu_data found\n", __func__); | 1376 | pr_debug("%s: No cpu_data found\n", __func__); |
1447 | return -EINVAL; | 1377 | return; |
1448 | } | 1378 | } |
1449 | 1379 | ||
1450 | if (has_target()) { | 1380 | if (has_target()) { |
1451 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 1381 | int ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
1452 | if (ret) | 1382 | if (ret) |
1453 | pr_err("%s: Failed to stop governor\n", __func__); | 1383 | pr_err("%s: Failed to stop governor\n", __func__); |
1454 | } | 1384 | } |
@@ -1469,7 +1399,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev) | |||
1469 | /* Start governor again for active policy */ | 1399 | /* Start governor again for active policy */ |
1470 | if (!policy_is_inactive(policy)) { | 1400 | if (!policy_is_inactive(policy)) { |
1471 | if (has_target()) { | 1401 | if (has_target()) { |
1472 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); | 1402 | int ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); |
1473 | if (!ret) | 1403 | if (!ret) |
1474 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 1404 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); |
1475 | 1405 | ||
@@ -1479,28 +1409,24 @@ static int __cpufreq_remove_dev_prepare(struct device *dev) | |||
1479 | } else if (cpufreq_driver->stop_cpu) { | 1409 | } else if (cpufreq_driver->stop_cpu) { |
1480 | cpufreq_driver->stop_cpu(policy); | 1410 | cpufreq_driver->stop_cpu(policy); |
1481 | } | 1411 | } |
1482 | |||
1483 | return ret; | ||
1484 | } | 1412 | } |
1485 | 1413 | ||
1486 | static int __cpufreq_remove_dev_finish(struct device *dev) | 1414 | static void cpufreq_offline_finish(unsigned int cpu) |
1487 | { | 1415 | { |
1488 | unsigned int cpu = dev->id; | ||
1489 | int ret; | ||
1490 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | 1416 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); |
1491 | 1417 | ||
1492 | if (!policy) { | 1418 | if (!policy) { |
1493 | pr_debug("%s: No cpu_data found\n", __func__); | 1419 | pr_debug("%s: No cpu_data found\n", __func__); |
1494 | return -EINVAL; | 1420 | return; |
1495 | } | 1421 | } |
1496 | 1422 | ||
1497 | /* Only proceed for inactive policies */ | 1423 | /* Only proceed for inactive policies */ |
1498 | if (!policy_is_inactive(policy)) | 1424 | if (!policy_is_inactive(policy)) |
1499 | return 0; | 1425 | return; |
1500 | 1426 | ||
1501 | /* If cpu is last user of policy, free policy */ | 1427 | /* If cpu is last user of policy, free policy */ |
1502 | if (has_target()) { | 1428 | if (has_target()) { |
1503 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); | 1429 | int ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); |
1504 | if (ret) | 1430 | if (ret) |
1505 | pr_err("%s: Failed to exit governor\n", __func__); | 1431 | pr_err("%s: Failed to exit governor\n", __func__); |
1506 | } | 1432 | } |
@@ -1512,8 +1438,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev) | |||
1512 | */ | 1438 | */ |
1513 | if (cpufreq_driver->exit) | 1439 | if (cpufreq_driver->exit) |
1514 | cpufreq_driver->exit(policy); | 1440 | cpufreq_driver->exit(policy); |
1515 | |||
1516 | return 0; | ||
1517 | } | 1441 | } |
1518 | 1442 | ||
1519 | /** | 1443 | /** |
@@ -1530,8 +1454,8 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | |||
1530 | return 0; | 1454 | return 0; |
1531 | 1455 | ||
1532 | if (cpu_online(cpu)) { | 1456 | if (cpu_online(cpu)) { |
1533 | __cpufreq_remove_dev_prepare(dev); | 1457 | cpufreq_offline_prepare(cpu); |
1534 | __cpufreq_remove_dev_finish(dev); | 1458 | cpufreq_offline_finish(cpu); |
1535 | } | 1459 | } |
1536 | 1460 | ||
1537 | cpumask_clear_cpu(cpu, policy->real_cpus); | 1461 | cpumask_clear_cpu(cpu, policy->real_cpus); |
@@ -2247,7 +2171,11 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2247 | 2171 | ||
2248 | memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); | 2172 | memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); |
2249 | 2173 | ||
2250 | if (new_policy->min > policy->max || new_policy->max < policy->min) | 2174 | /* |
2175 | * This check works well when we store new min/max freq attributes, | ||
2176 | * because new_policy is a copy of policy with one field updated. | ||
2177 | */ | ||
2178 | if (new_policy->min > new_policy->max) | ||
2251 | return -EINVAL; | 2179 | return -EINVAL; |
2252 | 2180 | ||
2253 | /* verify the cpu speed can be set within this limit */ | 2181 | /* verify the cpu speed can be set within this limit */ |
@@ -2259,10 +2187,6 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2259 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 2187 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
2260 | CPUFREQ_ADJUST, new_policy); | 2188 | CPUFREQ_ADJUST, new_policy); |
2261 | 2189 | ||
2262 | /* adjust if necessary - hardware incompatibility*/ | ||
2263 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | ||
2264 | CPUFREQ_INCOMPATIBLE, new_policy); | ||
2265 | |||
2266 | /* | 2190 | /* |
2267 | * verify the cpu speed can be set within this limit, which might be | 2191 | * verify the cpu speed can be set within this limit, which might be |
2268 | * different to the first one | 2192 | * different to the first one |
@@ -2296,16 +2220,31 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2296 | old_gov = policy->governor; | 2220 | old_gov = policy->governor; |
2297 | /* end old governor */ | 2221 | /* end old governor */ |
2298 | if (old_gov) { | 2222 | if (old_gov) { |
2299 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 2223 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
2224 | if (ret) { | ||
2225 | /* This can happen due to race with other operations */ | ||
2226 | pr_debug("%s: Failed to Stop Governor: %s (%d)\n", | ||
2227 | __func__, old_gov->name, ret); | ||
2228 | return ret; | ||
2229 | } | ||
2230 | |||
2300 | up_write(&policy->rwsem); | 2231 | up_write(&policy->rwsem); |
2301 | __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); | 2232 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); |
2302 | down_write(&policy->rwsem); | 2233 | down_write(&policy->rwsem); |
2234 | |||
2235 | if (ret) { | ||
2236 | pr_err("%s: Failed to Exit Governor: %s (%d)\n", | ||
2237 | __func__, old_gov->name, ret); | ||
2238 | return ret; | ||
2239 | } | ||
2303 | } | 2240 | } |
2304 | 2241 | ||
2305 | /* start new governor */ | 2242 | /* start new governor */ |
2306 | policy->governor = new_policy->governor; | 2243 | policy->governor = new_policy->governor; |
2307 | if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { | 2244 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); |
2308 | if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) | 2245 | if (!ret) { |
2246 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); | ||
2247 | if (!ret) | ||
2309 | goto out; | 2248 | goto out; |
2310 | 2249 | ||
2311 | up_write(&policy->rwsem); | 2250 | up_write(&policy->rwsem); |
@@ -2317,11 +2256,13 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2317 | pr_debug("starting governor %s failed\n", policy->governor->name); | 2256 | pr_debug("starting governor %s failed\n", policy->governor->name); |
2318 | if (old_gov) { | 2257 | if (old_gov) { |
2319 | policy->governor = old_gov; | 2258 | policy->governor = old_gov; |
2320 | __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); | 2259 | if (__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) |
2321 | __cpufreq_governor(policy, CPUFREQ_GOV_START); | 2260 | policy->governor = NULL; |
2261 | else | ||
2262 | __cpufreq_governor(policy, CPUFREQ_GOV_START); | ||
2322 | } | 2263 | } |
2323 | 2264 | ||
2324 | return -EINVAL; | 2265 | return ret; |
2325 | 2266 | ||
2326 | out: | 2267 | out: |
2327 | pr_debug("governor: change or update limits\n"); | 2268 | pr_debug("governor: change or update limits\n"); |
@@ -2350,8 +2291,6 @@ int cpufreq_update_policy(unsigned int cpu) | |||
2350 | memcpy(&new_policy, policy, sizeof(*policy)); | 2291 | memcpy(&new_policy, policy, sizeof(*policy)); |
2351 | new_policy.min = policy->user_policy.min; | 2292 | new_policy.min = policy->user_policy.min; |
2352 | new_policy.max = policy->user_policy.max; | 2293 | new_policy.max = policy->user_policy.max; |
2353 | new_policy.policy = policy->user_policy.policy; | ||
2354 | new_policy.governor = policy->user_policy.governor; | ||
2355 | 2294 | ||
2356 | /* | 2295 | /* |
2357 | * BIOS might change freq behind our back | 2296 | * BIOS might change freq behind our back |
@@ -2387,27 +2326,23 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
2387 | unsigned long action, void *hcpu) | 2326 | unsigned long action, void *hcpu) |
2388 | { | 2327 | { |
2389 | unsigned int cpu = (unsigned long)hcpu; | 2328 | unsigned int cpu = (unsigned long)hcpu; |
2390 | struct device *dev; | ||
2391 | 2329 | ||
2392 | dev = get_cpu_device(cpu); | 2330 | switch (action & ~CPU_TASKS_FROZEN) { |
2393 | if (dev) { | 2331 | case CPU_ONLINE: |
2394 | switch (action & ~CPU_TASKS_FROZEN) { | 2332 | cpufreq_online(cpu); |
2395 | case CPU_ONLINE: | 2333 | break; |
2396 | cpufreq_add_dev(dev, NULL); | ||
2397 | break; | ||
2398 | 2334 | ||
2399 | case CPU_DOWN_PREPARE: | 2335 | case CPU_DOWN_PREPARE: |
2400 | __cpufreq_remove_dev_prepare(dev); | 2336 | cpufreq_offline_prepare(cpu); |
2401 | break; | 2337 | break; |
2402 | 2338 | ||
2403 | case CPU_POST_DEAD: | 2339 | case CPU_POST_DEAD: |
2404 | __cpufreq_remove_dev_finish(dev); | 2340 | cpufreq_offline_finish(cpu); |
2405 | break; | 2341 | break; |
2406 | 2342 | ||
2407 | case CPU_DOWN_FAILED: | 2343 | case CPU_DOWN_FAILED: |
2408 | cpufreq_add_dev(dev, NULL); | 2344 | cpufreq_online(cpu); |
2409 | break; | 2345 | break; |
2410 | } | ||
2411 | } | 2346 | } |
2412 | return NOTIFY_OK; | 2347 | return NOTIFY_OK; |
2413 | } | 2348 | } |
@@ -2515,10 +2450,14 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2515 | 2450 | ||
2516 | pr_debug("trying to register driver %s\n", driver_data->name); | 2451 | pr_debug("trying to register driver %s\n", driver_data->name); |
2517 | 2452 | ||
2453 | /* Protect against concurrent CPU online/offline. */ | ||
2454 | get_online_cpus(); | ||
2455 | |||
2518 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2456 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2519 | if (cpufreq_driver) { | 2457 | if (cpufreq_driver) { |
2520 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2458 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2521 | return -EEXIST; | 2459 | ret = -EEXIST; |
2460 | goto out; | ||
2522 | } | 2461 | } |
2523 | cpufreq_driver = driver_data; | 2462 | cpufreq_driver = driver_data; |
2524 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2463 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
@@ -2557,7 +2496,10 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2557 | register_hotcpu_notifier(&cpufreq_cpu_notifier); | 2496 | register_hotcpu_notifier(&cpufreq_cpu_notifier); |
2558 | pr_debug("driver %s up and running\n", driver_data->name); | 2497 | pr_debug("driver %s up and running\n", driver_data->name); |
2559 | 2498 | ||
2560 | return 0; | 2499 | out: |
2500 | put_online_cpus(); | ||
2501 | return ret; | ||
2502 | |||
2561 | err_if_unreg: | 2503 | err_if_unreg: |
2562 | subsys_interface_unregister(&cpufreq_interface); | 2504 | subsys_interface_unregister(&cpufreq_interface); |
2563 | err_boost_unreg: | 2505 | err_boost_unreg: |
@@ -2567,7 +2509,7 @@ err_null_driver: | |||
2567 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2509 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2568 | cpufreq_driver = NULL; | 2510 | cpufreq_driver = NULL; |
2569 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2511 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2570 | return ret; | 2512 | goto out; |
2571 | } | 2513 | } |
2572 | EXPORT_SYMBOL_GPL(cpufreq_register_driver); | 2514 | EXPORT_SYMBOL_GPL(cpufreq_register_driver); |
2573 | 2515 | ||
@@ -2588,19 +2530,20 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) | |||
2588 | 2530 | ||
2589 | pr_debug("unregistering driver %s\n", driver->name); | 2531 | pr_debug("unregistering driver %s\n", driver->name); |
2590 | 2532 | ||
2533 | /* Protect against concurrent cpu hotplug */ | ||
2534 | get_online_cpus(); | ||
2591 | subsys_interface_unregister(&cpufreq_interface); | 2535 | subsys_interface_unregister(&cpufreq_interface); |
2592 | if (cpufreq_boost_supported()) | 2536 | if (cpufreq_boost_supported()) |
2593 | cpufreq_sysfs_remove_file(&boost.attr); | 2537 | cpufreq_sysfs_remove_file(&boost.attr); |
2594 | 2538 | ||
2595 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); | 2539 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); |
2596 | 2540 | ||
2597 | down_write(&cpufreq_rwsem); | ||
2598 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2541 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2599 | 2542 | ||
2600 | cpufreq_driver = NULL; | 2543 | cpufreq_driver = NULL; |
2601 | 2544 | ||
2602 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2545 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2603 | up_write(&cpufreq_rwsem); | 2546 | put_online_cpus(); |
2604 | 2547 | ||
2605 | return 0; | 2548 | return 0; |
2606 | } | 2549 | } |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index c86a10c30912..84a1506950a7 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -47,7 +47,7 @@ static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners, | |||
47 | static void cs_check_cpu(int cpu, unsigned int load) | 47 | static void cs_check_cpu(int cpu, unsigned int load) |
48 | { | 48 | { |
49 | struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); | 49 | struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); |
50 | struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; | 50 | struct cpufreq_policy *policy = dbs_info->cdbs.shared->policy; |
51 | struct dbs_data *dbs_data = policy->governor_data; | 51 | struct dbs_data *dbs_data = policy->governor_data; |
52 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; | 52 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; |
53 | 53 | ||
@@ -102,26 +102,15 @@ static void cs_check_cpu(int cpu, unsigned int load) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | static void cs_dbs_timer(struct work_struct *work) | 105 | static unsigned int cs_dbs_timer(struct cpu_dbs_info *cdbs, |
106 | struct dbs_data *dbs_data, bool modify_all) | ||
106 | { | 107 | { |
107 | struct cs_cpu_dbs_info_s *dbs_info = container_of(work, | ||
108 | struct cs_cpu_dbs_info_s, cdbs.work.work); | ||
109 | unsigned int cpu = dbs_info->cdbs.cur_policy->cpu; | ||
110 | struct cs_cpu_dbs_info_s *core_dbs_info = &per_cpu(cs_cpu_dbs_info, | ||
111 | cpu); | ||
112 | struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data; | ||
113 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; | 108 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; |
114 | int delay = delay_for_sampling_rate(cs_tuners->sampling_rate); | ||
115 | bool modify_all = true; | ||
116 | 109 | ||
117 | mutex_lock(&core_dbs_info->cdbs.timer_mutex); | 110 | if (modify_all) |
118 | if (!need_load_eval(&core_dbs_info->cdbs, cs_tuners->sampling_rate)) | 111 | dbs_check_cpu(dbs_data, cdbs->shared->policy->cpu); |
119 | modify_all = false; | ||
120 | else | ||
121 | dbs_check_cpu(dbs_data, cpu); | ||
122 | 112 | ||
123 | gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all); | 113 | return delay_for_sampling_rate(cs_tuners->sampling_rate); |
124 | mutex_unlock(&core_dbs_info->cdbs.timer_mutex); | ||
125 | } | 114 | } |
126 | 115 | ||
127 | static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | 116 | static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, |
@@ -135,7 +124,7 @@ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
135 | if (!dbs_info->enable) | 124 | if (!dbs_info->enable) |
136 | return 0; | 125 | return 0; |
137 | 126 | ||
138 | policy = dbs_info->cdbs.cur_policy; | 127 | policy = dbs_info->cdbs.shared->policy; |
139 | 128 | ||
140 | /* | 129 | /* |
141 | * we only care if our internally tracked freq moves outside the 'valid' | 130 | * we only care if our internally tracked freq moves outside the 'valid' |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 57a39f8a92b7..939197ffa4ac 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
@@ -32,10 +32,10 @@ static struct attribute_group *get_sysfs_attr(struct dbs_data *dbs_data) | |||
32 | 32 | ||
33 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) | 33 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) |
34 | { | 34 | { |
35 | struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); | 35 | struct cpu_dbs_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); |
36 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; | 36 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; |
37 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; | 37 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; |
38 | struct cpufreq_policy *policy; | 38 | struct cpufreq_policy *policy = cdbs->shared->policy; |
39 | unsigned int sampling_rate; | 39 | unsigned int sampling_rate; |
40 | unsigned int max_load = 0; | 40 | unsigned int max_load = 0; |
41 | unsigned int ignore_nice; | 41 | unsigned int ignore_nice; |
@@ -60,11 +60,9 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) | |||
60 | ignore_nice = cs_tuners->ignore_nice_load; | 60 | ignore_nice = cs_tuners->ignore_nice_load; |
61 | } | 61 | } |
62 | 62 | ||
63 | policy = cdbs->cur_policy; | ||
64 | |||
65 | /* Get Absolute Load */ | 63 | /* Get Absolute Load */ |
66 | for_each_cpu(j, policy->cpus) { | 64 | for_each_cpu(j, policy->cpus) { |
67 | struct cpu_dbs_common_info *j_cdbs; | 65 | struct cpu_dbs_info *j_cdbs; |
68 | u64 cur_wall_time, cur_idle_time; | 66 | u64 cur_wall_time, cur_idle_time; |
69 | unsigned int idle_time, wall_time; | 67 | unsigned int idle_time, wall_time; |
70 | unsigned int load; | 68 | unsigned int load; |
@@ -163,9 +161,9 @@ EXPORT_SYMBOL_GPL(dbs_check_cpu); | |||
163 | static inline void __gov_queue_work(int cpu, struct dbs_data *dbs_data, | 161 | static inline void __gov_queue_work(int cpu, struct dbs_data *dbs_data, |
164 | unsigned int delay) | 162 | unsigned int delay) |
165 | { | 163 | { |
166 | struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); | 164 | struct cpu_dbs_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); |
167 | 165 | ||
168 | mod_delayed_work_on(cpu, system_wq, &cdbs->work, delay); | 166 | mod_delayed_work_on(cpu, system_wq, &cdbs->dwork, delay); |
169 | } | 167 | } |
170 | 168 | ||
171 | void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | 169 | void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, |
@@ -199,33 +197,63 @@ EXPORT_SYMBOL_GPL(gov_queue_work); | |||
199 | static inline void gov_cancel_work(struct dbs_data *dbs_data, | 197 | static inline void gov_cancel_work(struct dbs_data *dbs_data, |
200 | struct cpufreq_policy *policy) | 198 | struct cpufreq_policy *policy) |
201 | { | 199 | { |
202 | struct cpu_dbs_common_info *cdbs; | 200 | struct cpu_dbs_info *cdbs; |
203 | int i; | 201 | int i; |
204 | 202 | ||
205 | for_each_cpu(i, policy->cpus) { | 203 | for_each_cpu(i, policy->cpus) { |
206 | cdbs = dbs_data->cdata->get_cpu_cdbs(i); | 204 | cdbs = dbs_data->cdata->get_cpu_cdbs(i); |
207 | cancel_delayed_work_sync(&cdbs->work); | 205 | cancel_delayed_work_sync(&cdbs->dwork); |
208 | } | 206 | } |
209 | } | 207 | } |
210 | 208 | ||
211 | /* Will return if we need to evaluate cpu load again or not */ | 209 | /* Will return if we need to evaluate cpu load again or not */ |
212 | bool need_load_eval(struct cpu_dbs_common_info *cdbs, | 210 | static bool need_load_eval(struct cpu_common_dbs_info *shared, |
213 | unsigned int sampling_rate) | 211 | unsigned int sampling_rate) |
214 | { | 212 | { |
215 | if (policy_is_shared(cdbs->cur_policy)) { | 213 | if (policy_is_shared(shared->policy)) { |
216 | ktime_t time_now = ktime_get(); | 214 | ktime_t time_now = ktime_get(); |
217 | s64 delta_us = ktime_us_delta(time_now, cdbs->time_stamp); | 215 | s64 delta_us = ktime_us_delta(time_now, shared->time_stamp); |
218 | 216 | ||
219 | /* Do nothing if we recently have sampled */ | 217 | /* Do nothing if we recently have sampled */ |
220 | if (delta_us < (s64)(sampling_rate / 2)) | 218 | if (delta_us < (s64)(sampling_rate / 2)) |
221 | return false; | 219 | return false; |
222 | else | 220 | else |
223 | cdbs->time_stamp = time_now; | 221 | shared->time_stamp = time_now; |
224 | } | 222 | } |
225 | 223 | ||
226 | return true; | 224 | return true; |
227 | } | 225 | } |
228 | EXPORT_SYMBOL_GPL(need_load_eval); | 226 | |
227 | static void dbs_timer(struct work_struct *work) | ||
228 | { | ||
229 | struct cpu_dbs_info *cdbs = container_of(work, struct cpu_dbs_info, | ||
230 | dwork.work); | ||
231 | struct cpu_common_dbs_info *shared = cdbs->shared; | ||
232 | struct cpufreq_policy *policy = shared->policy; | ||
233 | struct dbs_data *dbs_data = policy->governor_data; | ||
234 | unsigned int sampling_rate, delay; | ||
235 | bool modify_all = true; | ||
236 | |||
237 | mutex_lock(&shared->timer_mutex); | ||
238 | |||
239 | if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { | ||
240 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; | ||
241 | |||
242 | sampling_rate = cs_tuners->sampling_rate; | ||
243 | } else { | ||
244 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; | ||
245 | |||
246 | sampling_rate = od_tuners->sampling_rate; | ||
247 | } | ||
248 | |||
249 | if (!need_load_eval(cdbs->shared, sampling_rate)) | ||
250 | modify_all = false; | ||
251 | |||
252 | delay = dbs_data->cdata->gov_dbs_timer(cdbs, dbs_data, modify_all); | ||
253 | gov_queue_work(dbs_data, policy, delay, modify_all); | ||
254 | |||
255 | mutex_unlock(&shared->timer_mutex); | ||
256 | } | ||
229 | 257 | ||
230 | static void set_sampling_rate(struct dbs_data *dbs_data, | 258 | static void set_sampling_rate(struct dbs_data *dbs_data, |
231 | unsigned int sampling_rate) | 259 | unsigned int sampling_rate) |
@@ -239,6 +267,37 @@ static void set_sampling_rate(struct dbs_data *dbs_data, | |||
239 | } | 267 | } |
240 | } | 268 | } |
241 | 269 | ||
270 | static int alloc_common_dbs_info(struct cpufreq_policy *policy, | ||
271 | struct common_dbs_data *cdata) | ||
272 | { | ||
273 | struct cpu_common_dbs_info *shared; | ||
274 | int j; | ||
275 | |||
276 | /* Allocate memory for the common information for policy->cpus */ | ||
277 | shared = kzalloc(sizeof(*shared), GFP_KERNEL); | ||
278 | if (!shared) | ||
279 | return -ENOMEM; | ||
280 | |||
281 | /* Set shared for all CPUs, online+offline */ | ||
282 | for_each_cpu(j, policy->related_cpus) | ||
283 | cdata->get_cpu_cdbs(j)->shared = shared; | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static void free_common_dbs_info(struct cpufreq_policy *policy, | ||
289 | struct common_dbs_data *cdata) | ||
290 | { | ||
291 | struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(policy->cpu); | ||
292 | struct cpu_common_dbs_info *shared = cdbs->shared; | ||
293 | int j; | ||
294 | |||
295 | for_each_cpu(j, policy->cpus) | ||
296 | cdata->get_cpu_cdbs(j)->shared = NULL; | ||
297 | |||
298 | kfree(shared); | ||
299 | } | ||
300 | |||
242 | static int cpufreq_governor_init(struct cpufreq_policy *policy, | 301 | static int cpufreq_governor_init(struct cpufreq_policy *policy, |
243 | struct dbs_data *dbs_data, | 302 | struct dbs_data *dbs_data, |
244 | struct common_dbs_data *cdata) | 303 | struct common_dbs_data *cdata) |
@@ -246,9 +305,18 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy, | |||
246 | unsigned int latency; | 305 | unsigned int latency; |
247 | int ret; | 306 | int ret; |
248 | 307 | ||
308 | /* State should be equivalent to EXIT */ | ||
309 | if (policy->governor_data) | ||
310 | return -EBUSY; | ||
311 | |||
249 | if (dbs_data) { | 312 | if (dbs_data) { |
250 | if (WARN_ON(have_governor_per_policy())) | 313 | if (WARN_ON(have_governor_per_policy())) |
251 | return -EINVAL; | 314 | return -EINVAL; |
315 | |||
316 | ret = alloc_common_dbs_info(policy, cdata); | ||
317 | if (ret) | ||
318 | return ret; | ||
319 | |||
252 | dbs_data->usage_count++; | 320 | dbs_data->usage_count++; |
253 | policy->governor_data = dbs_data; | 321 | policy->governor_data = dbs_data; |
254 | return 0; | 322 | return 0; |
@@ -258,12 +326,16 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy, | |||
258 | if (!dbs_data) | 326 | if (!dbs_data) |
259 | return -ENOMEM; | 327 | return -ENOMEM; |
260 | 328 | ||
329 | ret = alloc_common_dbs_info(policy, cdata); | ||
330 | if (ret) | ||
331 | goto free_dbs_data; | ||
332 | |||
261 | dbs_data->cdata = cdata; | 333 | dbs_data->cdata = cdata; |
262 | dbs_data->usage_count = 1; | 334 | dbs_data->usage_count = 1; |
263 | 335 | ||
264 | ret = cdata->init(dbs_data, !policy->governor->initialized); | 336 | ret = cdata->init(dbs_data, !policy->governor->initialized); |
265 | if (ret) | 337 | if (ret) |
266 | goto free_dbs_data; | 338 | goto free_common_dbs_info; |
267 | 339 | ||
268 | /* policy latency is in ns. Convert it to us first */ | 340 | /* policy latency is in ns. Convert it to us first */ |
269 | latency = policy->cpuinfo.transition_latency / 1000; | 341 | latency = policy->cpuinfo.transition_latency / 1000; |
@@ -300,15 +372,22 @@ put_kobj: | |||
300 | } | 372 | } |
301 | cdata_exit: | 373 | cdata_exit: |
302 | cdata->exit(dbs_data, !policy->governor->initialized); | 374 | cdata->exit(dbs_data, !policy->governor->initialized); |
375 | free_common_dbs_info: | ||
376 | free_common_dbs_info(policy, cdata); | ||
303 | free_dbs_data: | 377 | free_dbs_data: |
304 | kfree(dbs_data); | 378 | kfree(dbs_data); |
305 | return ret; | 379 | return ret; |
306 | } | 380 | } |
307 | 381 | ||
308 | static void cpufreq_governor_exit(struct cpufreq_policy *policy, | 382 | static int cpufreq_governor_exit(struct cpufreq_policy *policy, |
309 | struct dbs_data *dbs_data) | 383 | struct dbs_data *dbs_data) |
310 | { | 384 | { |
311 | struct common_dbs_data *cdata = dbs_data->cdata; | 385 | struct common_dbs_data *cdata = dbs_data->cdata; |
386 | struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(policy->cpu); | ||
387 | |||
388 | /* State should be equivalent to INIT */ | ||
389 | if (!cdbs->shared || cdbs->shared->policy) | ||
390 | return -EBUSY; | ||
312 | 391 | ||
313 | policy->governor_data = NULL; | 392 | policy->governor_data = NULL; |
314 | if (!--dbs_data->usage_count) { | 393 | if (!--dbs_data->usage_count) { |
@@ -323,6 +402,9 @@ static void cpufreq_governor_exit(struct cpufreq_policy *policy, | |||
323 | cdata->exit(dbs_data, policy->governor->initialized == 1); | 402 | cdata->exit(dbs_data, policy->governor->initialized == 1); |
324 | kfree(dbs_data); | 403 | kfree(dbs_data); |
325 | } | 404 | } |
405 | |||
406 | free_common_dbs_info(policy, cdata); | ||
407 | return 0; | ||
326 | } | 408 | } |
327 | 409 | ||
328 | static int cpufreq_governor_start(struct cpufreq_policy *policy, | 410 | static int cpufreq_governor_start(struct cpufreq_policy *policy, |
@@ -330,12 +412,17 @@ static int cpufreq_governor_start(struct cpufreq_policy *policy, | |||
330 | { | 412 | { |
331 | struct common_dbs_data *cdata = dbs_data->cdata; | 413 | struct common_dbs_data *cdata = dbs_data->cdata; |
332 | unsigned int sampling_rate, ignore_nice, j, cpu = policy->cpu; | 414 | unsigned int sampling_rate, ignore_nice, j, cpu = policy->cpu; |
333 | struct cpu_dbs_common_info *cpu_cdbs = cdata->get_cpu_cdbs(cpu); | 415 | struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(cpu); |
416 | struct cpu_common_dbs_info *shared = cdbs->shared; | ||
334 | int io_busy = 0; | 417 | int io_busy = 0; |
335 | 418 | ||
336 | if (!policy->cur) | 419 | if (!policy->cur) |
337 | return -EINVAL; | 420 | return -EINVAL; |
338 | 421 | ||
422 | /* State should be equivalent to INIT */ | ||
423 | if (!shared || shared->policy) | ||
424 | return -EBUSY; | ||
425 | |||
339 | if (cdata->governor == GOV_CONSERVATIVE) { | 426 | if (cdata->governor == GOV_CONSERVATIVE) { |
340 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; | 427 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; |
341 | 428 | ||
@@ -349,12 +436,14 @@ static int cpufreq_governor_start(struct cpufreq_policy *policy, | |||
349 | io_busy = od_tuners->io_is_busy; | 436 | io_busy = od_tuners->io_is_busy; |
350 | } | 437 | } |
351 | 438 | ||
439 | shared->policy = policy; | ||
440 | shared->time_stamp = ktime_get(); | ||
441 | mutex_init(&shared->timer_mutex); | ||
442 | |||
352 | for_each_cpu(j, policy->cpus) { | 443 | for_each_cpu(j, policy->cpus) { |
353 | struct cpu_dbs_common_info *j_cdbs = cdata->get_cpu_cdbs(j); | 444 | struct cpu_dbs_info *j_cdbs = cdata->get_cpu_cdbs(j); |
354 | unsigned int prev_load; | 445 | unsigned int prev_load; |
355 | 446 | ||
356 | j_cdbs->cpu = j; | ||
357 | j_cdbs->cur_policy = policy; | ||
358 | j_cdbs->prev_cpu_idle = | 447 | j_cdbs->prev_cpu_idle = |
359 | get_cpu_idle_time(j, &j_cdbs->prev_cpu_wall, io_busy); | 448 | get_cpu_idle_time(j, &j_cdbs->prev_cpu_wall, io_busy); |
360 | 449 | ||
@@ -366,8 +455,7 @@ static int cpufreq_governor_start(struct cpufreq_policy *policy, | |||
366 | if (ignore_nice) | 455 | if (ignore_nice) |
367 | j_cdbs->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; | 456 | j_cdbs->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; |
368 | 457 | ||
369 | mutex_init(&j_cdbs->timer_mutex); | 458 | INIT_DEFERRABLE_WORK(&j_cdbs->dwork, dbs_timer); |
370 | INIT_DEFERRABLE_WORK(&j_cdbs->work, cdata->gov_dbs_timer); | ||
371 | } | 459 | } |
372 | 460 | ||
373 | if (cdata->governor == GOV_CONSERVATIVE) { | 461 | if (cdata->governor == GOV_CONSERVATIVE) { |
@@ -386,20 +474,24 @@ static int cpufreq_governor_start(struct cpufreq_policy *policy, | |||
386 | od_ops->powersave_bias_init_cpu(cpu); | 474 | od_ops->powersave_bias_init_cpu(cpu); |
387 | } | 475 | } |
388 | 476 | ||
389 | /* Initiate timer time stamp */ | ||
390 | cpu_cdbs->time_stamp = ktime_get(); | ||
391 | |||
392 | gov_queue_work(dbs_data, policy, delay_for_sampling_rate(sampling_rate), | 477 | gov_queue_work(dbs_data, policy, delay_for_sampling_rate(sampling_rate), |
393 | true); | 478 | true); |
394 | return 0; | 479 | return 0; |
395 | } | 480 | } |
396 | 481 | ||
397 | static void cpufreq_governor_stop(struct cpufreq_policy *policy, | 482 | static int cpufreq_governor_stop(struct cpufreq_policy *policy, |
398 | struct dbs_data *dbs_data) | 483 | struct dbs_data *dbs_data) |
399 | { | 484 | { |
400 | struct common_dbs_data *cdata = dbs_data->cdata; | 485 | struct common_dbs_data *cdata = dbs_data->cdata; |
401 | unsigned int cpu = policy->cpu; | 486 | unsigned int cpu = policy->cpu; |
402 | struct cpu_dbs_common_info *cpu_cdbs = cdata->get_cpu_cdbs(cpu); | 487 | struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(cpu); |
488 | struct cpu_common_dbs_info *shared = cdbs->shared; | ||
489 | |||
490 | /* State should be equivalent to START */ | ||
491 | if (!shared || !shared->policy) | ||
492 | return -EBUSY; | ||
493 | |||
494 | gov_cancel_work(dbs_data, policy); | ||
403 | 495 | ||
404 | if (cdata->governor == GOV_CONSERVATIVE) { | 496 | if (cdata->governor == GOV_CONSERVATIVE) { |
405 | struct cs_cpu_dbs_info_s *cs_dbs_info = | 497 | struct cs_cpu_dbs_info_s *cs_dbs_info = |
@@ -408,38 +500,40 @@ static void cpufreq_governor_stop(struct cpufreq_policy *policy, | |||
408 | cs_dbs_info->enable = 0; | 500 | cs_dbs_info->enable = 0; |
409 | } | 501 | } |
410 | 502 | ||
411 | gov_cancel_work(dbs_data, policy); | 503 | shared->policy = NULL; |
412 | 504 | mutex_destroy(&shared->timer_mutex); | |
413 | mutex_destroy(&cpu_cdbs->timer_mutex); | 505 | return 0; |
414 | cpu_cdbs->cur_policy = NULL; | ||
415 | } | 506 | } |
416 | 507 | ||
417 | static void cpufreq_governor_limits(struct cpufreq_policy *policy, | 508 | static int cpufreq_governor_limits(struct cpufreq_policy *policy, |
418 | struct dbs_data *dbs_data) | 509 | struct dbs_data *dbs_data) |
419 | { | 510 | { |
420 | struct common_dbs_data *cdata = dbs_data->cdata; | 511 | struct common_dbs_data *cdata = dbs_data->cdata; |
421 | unsigned int cpu = policy->cpu; | 512 | unsigned int cpu = policy->cpu; |
422 | struct cpu_dbs_common_info *cpu_cdbs = cdata->get_cpu_cdbs(cpu); | 513 | struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(cpu); |
423 | 514 | ||
424 | if (!cpu_cdbs->cur_policy) | 515 | /* State should be equivalent to START */ |
425 | return; | 516 | if (!cdbs->shared || !cdbs->shared->policy) |
517 | return -EBUSY; | ||
426 | 518 | ||
427 | mutex_lock(&cpu_cdbs->timer_mutex); | 519 | mutex_lock(&cdbs->shared->timer_mutex); |
428 | if (policy->max < cpu_cdbs->cur_policy->cur) | 520 | if (policy->max < cdbs->shared->policy->cur) |
429 | __cpufreq_driver_target(cpu_cdbs->cur_policy, policy->max, | 521 | __cpufreq_driver_target(cdbs->shared->policy, policy->max, |
430 | CPUFREQ_RELATION_H); | 522 | CPUFREQ_RELATION_H); |
431 | else if (policy->min > cpu_cdbs->cur_policy->cur) | 523 | else if (policy->min > cdbs->shared->policy->cur) |
432 | __cpufreq_driver_target(cpu_cdbs->cur_policy, policy->min, | 524 | __cpufreq_driver_target(cdbs->shared->policy, policy->min, |
433 | CPUFREQ_RELATION_L); | 525 | CPUFREQ_RELATION_L); |
434 | dbs_check_cpu(dbs_data, cpu); | 526 | dbs_check_cpu(dbs_data, cpu); |
435 | mutex_unlock(&cpu_cdbs->timer_mutex); | 527 | mutex_unlock(&cdbs->shared->timer_mutex); |
528 | |||
529 | return 0; | ||
436 | } | 530 | } |
437 | 531 | ||
438 | int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 532 | int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
439 | struct common_dbs_data *cdata, unsigned int event) | 533 | struct common_dbs_data *cdata, unsigned int event) |
440 | { | 534 | { |
441 | struct dbs_data *dbs_data; | 535 | struct dbs_data *dbs_data; |
442 | int ret = 0; | 536 | int ret; |
443 | 537 | ||
444 | /* Lock governor to block concurrent initialization of governor */ | 538 | /* Lock governor to block concurrent initialization of governor */ |
445 | mutex_lock(&cdata->mutex); | 539 | mutex_lock(&cdata->mutex); |
@@ -449,7 +543,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
449 | else | 543 | else |
450 | dbs_data = cdata->gdbs_data; | 544 | dbs_data = cdata->gdbs_data; |
451 | 545 | ||
452 | if (WARN_ON(!dbs_data && (event != CPUFREQ_GOV_POLICY_INIT))) { | 546 | if (!dbs_data && (event != CPUFREQ_GOV_POLICY_INIT)) { |
453 | ret = -EINVAL; | 547 | ret = -EINVAL; |
454 | goto unlock; | 548 | goto unlock; |
455 | } | 549 | } |
@@ -459,17 +553,19 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
459 | ret = cpufreq_governor_init(policy, dbs_data, cdata); | 553 | ret = cpufreq_governor_init(policy, dbs_data, cdata); |
460 | break; | 554 | break; |
461 | case CPUFREQ_GOV_POLICY_EXIT: | 555 | case CPUFREQ_GOV_POLICY_EXIT: |
462 | cpufreq_governor_exit(policy, dbs_data); | 556 | ret = cpufreq_governor_exit(policy, dbs_data); |
463 | break; | 557 | break; |
464 | case CPUFREQ_GOV_START: | 558 | case CPUFREQ_GOV_START: |
465 | ret = cpufreq_governor_start(policy, dbs_data); | 559 | ret = cpufreq_governor_start(policy, dbs_data); |
466 | break; | 560 | break; |
467 | case CPUFREQ_GOV_STOP: | 561 | case CPUFREQ_GOV_STOP: |
468 | cpufreq_governor_stop(policy, dbs_data); | 562 | ret = cpufreq_governor_stop(policy, dbs_data); |
469 | break; | 563 | break; |
470 | case CPUFREQ_GOV_LIMITS: | 564 | case CPUFREQ_GOV_LIMITS: |
471 | cpufreq_governor_limits(policy, dbs_data); | 565 | ret = cpufreq_governor_limits(policy, dbs_data); |
472 | break; | 566 | break; |
567 | default: | ||
568 | ret = -EINVAL; | ||
473 | } | 569 | } |
474 | 570 | ||
475 | unlock: | 571 | unlock: |
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 34736f5e869d..50f171796632 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h | |||
@@ -109,7 +109,7 @@ store_one(_gov, file_name) | |||
109 | 109 | ||
110 | /* create helper routines */ | 110 | /* create helper routines */ |
111 | #define define_get_cpu_dbs_routines(_dbs_info) \ | 111 | #define define_get_cpu_dbs_routines(_dbs_info) \ |
112 | static struct cpu_dbs_common_info *get_cpu_cdbs(int cpu) \ | 112 | static struct cpu_dbs_info *get_cpu_cdbs(int cpu) \ |
113 | { \ | 113 | { \ |
114 | return &per_cpu(_dbs_info, cpu).cdbs; \ | 114 | return &per_cpu(_dbs_info, cpu).cdbs; \ |
115 | } \ | 115 | } \ |
@@ -128,9 +128,20 @@ static void *get_cpu_dbs_info_s(int cpu) \ | |||
128 | * cs_*: Conservative governor | 128 | * cs_*: Conservative governor |
129 | */ | 129 | */ |
130 | 130 | ||
131 | /* Common to all CPUs of a policy */ | ||
132 | struct cpu_common_dbs_info { | ||
133 | struct cpufreq_policy *policy; | ||
134 | /* | ||
135 | * percpu mutex that serializes governor limit change with dbs_timer | ||
136 | * invocation. We do not want dbs_timer to run when user is changing | ||
137 | * the governor or limits. | ||
138 | */ | ||
139 | struct mutex timer_mutex; | ||
140 | ktime_t time_stamp; | ||
141 | }; | ||
142 | |||
131 | /* Per cpu structures */ | 143 | /* Per cpu structures */ |
132 | struct cpu_dbs_common_info { | 144 | struct cpu_dbs_info { |
133 | int cpu; | ||
134 | u64 prev_cpu_idle; | 145 | u64 prev_cpu_idle; |
135 | u64 prev_cpu_wall; | 146 | u64 prev_cpu_wall; |
136 | u64 prev_cpu_nice; | 147 | u64 prev_cpu_nice; |
@@ -141,19 +152,12 @@ struct cpu_dbs_common_info { | |||
141 | * wake-up from idle. | 152 | * wake-up from idle. |
142 | */ | 153 | */ |
143 | unsigned int prev_load; | 154 | unsigned int prev_load; |
144 | struct cpufreq_policy *cur_policy; | 155 | struct delayed_work dwork; |
145 | struct delayed_work work; | 156 | struct cpu_common_dbs_info *shared; |
146 | /* | ||
147 | * percpu mutex that serializes governor limit change with gov_dbs_timer | ||
148 | * invocation. We do not want gov_dbs_timer to run when user is changing | ||
149 | * the governor or limits. | ||
150 | */ | ||
151 | struct mutex timer_mutex; | ||
152 | ktime_t time_stamp; | ||
153 | }; | 157 | }; |
154 | 158 | ||
155 | struct od_cpu_dbs_info_s { | 159 | struct od_cpu_dbs_info_s { |
156 | struct cpu_dbs_common_info cdbs; | 160 | struct cpu_dbs_info cdbs; |
157 | struct cpufreq_frequency_table *freq_table; | 161 | struct cpufreq_frequency_table *freq_table; |
158 | unsigned int freq_lo; | 162 | unsigned int freq_lo; |
159 | unsigned int freq_lo_jiffies; | 163 | unsigned int freq_lo_jiffies; |
@@ -163,7 +167,7 @@ struct od_cpu_dbs_info_s { | |||
163 | }; | 167 | }; |
164 | 168 | ||
165 | struct cs_cpu_dbs_info_s { | 169 | struct cs_cpu_dbs_info_s { |
166 | struct cpu_dbs_common_info cdbs; | 170 | struct cpu_dbs_info cdbs; |
167 | unsigned int down_skip; | 171 | unsigned int down_skip; |
168 | unsigned int requested_freq; | 172 | unsigned int requested_freq; |
169 | unsigned int enable:1; | 173 | unsigned int enable:1; |
@@ -204,9 +208,11 @@ struct common_dbs_data { | |||
204 | */ | 208 | */ |
205 | struct dbs_data *gdbs_data; | 209 | struct dbs_data *gdbs_data; |
206 | 210 | ||
207 | struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu); | 211 | struct cpu_dbs_info *(*get_cpu_cdbs)(int cpu); |
208 | void *(*get_cpu_dbs_info_s)(int cpu); | 212 | void *(*get_cpu_dbs_info_s)(int cpu); |
209 | void (*gov_dbs_timer)(struct work_struct *work); | 213 | unsigned int (*gov_dbs_timer)(struct cpu_dbs_info *cdbs, |
214 | struct dbs_data *dbs_data, | ||
215 | bool modify_all); | ||
210 | void (*gov_check_cpu)(int cpu, unsigned int load); | 216 | void (*gov_check_cpu)(int cpu, unsigned int load); |
211 | int (*init)(struct dbs_data *dbs_data, bool notify); | 217 | int (*init)(struct dbs_data *dbs_data, bool notify); |
212 | void (*exit)(struct dbs_data *dbs_data, bool notify); | 218 | void (*exit)(struct dbs_data *dbs_data, bool notify); |
@@ -265,8 +271,6 @@ static ssize_t show_sampling_rate_min_gov_pol \ | |||
265 | extern struct mutex cpufreq_governor_lock; | 271 | extern struct mutex cpufreq_governor_lock; |
266 | 272 | ||
267 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); | 273 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); |
268 | bool need_load_eval(struct cpu_dbs_common_info *cdbs, | ||
269 | unsigned int sampling_rate); | ||
270 | int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 274 | int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
271 | struct common_dbs_data *cdata, unsigned int event); | 275 | struct common_dbs_data *cdata, unsigned int event); |
272 | void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | 276 | void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 3c1e10f2304c..1fa9088c84a8 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -155,7 +155,7 @@ static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq) | |||
155 | static void od_check_cpu(int cpu, unsigned int load) | 155 | static void od_check_cpu(int cpu, unsigned int load) |
156 | { | 156 | { |
157 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); | 157 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); |
158 | struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; | 158 | struct cpufreq_policy *policy = dbs_info->cdbs.shared->policy; |
159 | struct dbs_data *dbs_data = policy->governor_data; | 159 | struct dbs_data *dbs_data = policy->governor_data; |
160 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; | 160 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; |
161 | 161 | ||
@@ -191,46 +191,40 @@ static void od_check_cpu(int cpu, unsigned int load) | |||
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | static void od_dbs_timer(struct work_struct *work) | 194 | static unsigned int od_dbs_timer(struct cpu_dbs_info *cdbs, |
195 | struct dbs_data *dbs_data, bool modify_all) | ||
195 | { | 196 | { |
196 | struct od_cpu_dbs_info_s *dbs_info = | 197 | struct cpufreq_policy *policy = cdbs->shared->policy; |
197 | container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work); | 198 | unsigned int cpu = policy->cpu; |
198 | unsigned int cpu = dbs_info->cdbs.cur_policy->cpu; | 199 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, |
199 | struct od_cpu_dbs_info_s *core_dbs_info = &per_cpu(od_cpu_dbs_info, | ||
200 | cpu); | 200 | cpu); |
201 | struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data; | ||
202 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; | 201 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; |
203 | int delay = 0, sample_type = core_dbs_info->sample_type; | 202 | int delay = 0, sample_type = dbs_info->sample_type; |
204 | bool modify_all = true; | ||
205 | 203 | ||
206 | mutex_lock(&core_dbs_info->cdbs.timer_mutex); | 204 | if (!modify_all) |
207 | if (!need_load_eval(&core_dbs_info->cdbs, od_tuners->sampling_rate)) { | ||
208 | modify_all = false; | ||
209 | goto max_delay; | 205 | goto max_delay; |
210 | } | ||
211 | 206 | ||
212 | /* Common NORMAL_SAMPLE setup */ | 207 | /* Common NORMAL_SAMPLE setup */ |
213 | core_dbs_info->sample_type = OD_NORMAL_SAMPLE; | 208 | dbs_info->sample_type = OD_NORMAL_SAMPLE; |
214 | if (sample_type == OD_SUB_SAMPLE) { | 209 | if (sample_type == OD_SUB_SAMPLE) { |
215 | delay = core_dbs_info->freq_lo_jiffies; | 210 | delay = dbs_info->freq_lo_jiffies; |
216 | __cpufreq_driver_target(core_dbs_info->cdbs.cur_policy, | 211 | __cpufreq_driver_target(policy, dbs_info->freq_lo, |
217 | core_dbs_info->freq_lo, CPUFREQ_RELATION_H); | 212 | CPUFREQ_RELATION_H); |
218 | } else { | 213 | } else { |
219 | dbs_check_cpu(dbs_data, cpu); | 214 | dbs_check_cpu(dbs_data, cpu); |
220 | if (core_dbs_info->freq_lo) { | 215 | if (dbs_info->freq_lo) { |
221 | /* Setup timer for SUB_SAMPLE */ | 216 | /* Setup timer for SUB_SAMPLE */ |
222 | core_dbs_info->sample_type = OD_SUB_SAMPLE; | 217 | dbs_info->sample_type = OD_SUB_SAMPLE; |
223 | delay = core_dbs_info->freq_hi_jiffies; | 218 | delay = dbs_info->freq_hi_jiffies; |
224 | } | 219 | } |
225 | } | 220 | } |
226 | 221 | ||
227 | max_delay: | 222 | max_delay: |
228 | if (!delay) | 223 | if (!delay) |
229 | delay = delay_for_sampling_rate(od_tuners->sampling_rate | 224 | delay = delay_for_sampling_rate(od_tuners->sampling_rate |
230 | * core_dbs_info->rate_mult); | 225 | * dbs_info->rate_mult); |
231 | 226 | ||
232 | gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all); | 227 | return delay; |
233 | mutex_unlock(&core_dbs_info->cdbs.timer_mutex); | ||
234 | } | 228 | } |
235 | 229 | ||
236 | /************************** sysfs interface ************************/ | 230 | /************************** sysfs interface ************************/ |
@@ -273,27 +267,27 @@ static void update_sampling_rate(struct dbs_data *dbs_data, | |||
273 | dbs_info = &per_cpu(od_cpu_dbs_info, cpu); | 267 | dbs_info = &per_cpu(od_cpu_dbs_info, cpu); |
274 | cpufreq_cpu_put(policy); | 268 | cpufreq_cpu_put(policy); |
275 | 269 | ||
276 | mutex_lock(&dbs_info->cdbs.timer_mutex); | 270 | mutex_lock(&dbs_info->cdbs.shared->timer_mutex); |
277 | 271 | ||
278 | if (!delayed_work_pending(&dbs_info->cdbs.work)) { | 272 | if (!delayed_work_pending(&dbs_info->cdbs.dwork)) { |
279 | mutex_unlock(&dbs_info->cdbs.timer_mutex); | 273 | mutex_unlock(&dbs_info->cdbs.shared->timer_mutex); |
280 | continue; | 274 | continue; |
281 | } | 275 | } |
282 | 276 | ||
283 | next_sampling = jiffies + usecs_to_jiffies(new_rate); | 277 | next_sampling = jiffies + usecs_to_jiffies(new_rate); |
284 | appointed_at = dbs_info->cdbs.work.timer.expires; | 278 | appointed_at = dbs_info->cdbs.dwork.timer.expires; |
285 | 279 | ||
286 | if (time_before(next_sampling, appointed_at)) { | 280 | if (time_before(next_sampling, appointed_at)) { |
287 | 281 | ||
288 | mutex_unlock(&dbs_info->cdbs.timer_mutex); | 282 | mutex_unlock(&dbs_info->cdbs.shared->timer_mutex); |
289 | cancel_delayed_work_sync(&dbs_info->cdbs.work); | 283 | cancel_delayed_work_sync(&dbs_info->cdbs.dwork); |
290 | mutex_lock(&dbs_info->cdbs.timer_mutex); | 284 | mutex_lock(&dbs_info->cdbs.shared->timer_mutex); |
291 | 285 | ||
292 | gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, | 286 | gov_queue_work(dbs_data, policy, |
293 | usecs_to_jiffies(new_rate), true); | 287 | usecs_to_jiffies(new_rate), true); |
294 | 288 | ||
295 | } | 289 | } |
296 | mutex_unlock(&dbs_info->cdbs.timer_mutex); | 290 | mutex_unlock(&dbs_info->cdbs.shared->timer_mutex); |
297 | } | 291 | } |
298 | } | 292 | } |
299 | 293 | ||
@@ -556,13 +550,16 @@ static void od_set_powersave_bias(unsigned int powersave_bias) | |||
556 | 550 | ||
557 | get_online_cpus(); | 551 | get_online_cpus(); |
558 | for_each_online_cpu(cpu) { | 552 | for_each_online_cpu(cpu) { |
553 | struct cpu_common_dbs_info *shared; | ||
554 | |||
559 | if (cpumask_test_cpu(cpu, &done)) | 555 | if (cpumask_test_cpu(cpu, &done)) |
560 | continue; | 556 | continue; |
561 | 557 | ||
562 | policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy; | 558 | shared = per_cpu(od_cpu_dbs_info, cpu).cdbs.shared; |
563 | if (!policy) | 559 | if (!shared) |
564 | continue; | 560 | continue; |
565 | 561 | ||
562 | policy = shared->policy; | ||
566 | cpumask_or(&done, &done, policy->cpus); | 563 | cpumask_or(&done, &done, policy->cpus); |
567 | 564 | ||
568 | if (policy->governor != &cpufreq_gov_ondemand) | 565 | if (policy->governor != &cpufreq_gov_ondemand) |
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index a0d2a423cea9..4085244c8a67 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c | |||
@@ -78,7 +78,7 @@ static int eps_acpi_init(void) | |||
78 | static int eps_acpi_exit(struct cpufreq_policy *policy) | 78 | static int eps_acpi_exit(struct cpufreq_policy *policy) |
79 | { | 79 | { |
80 | if (eps_acpi_cpu_perf) { | 80 | if (eps_acpi_cpu_perf) { |
81 | acpi_processor_unregister_performance(eps_acpi_cpu_perf, 0); | 81 | acpi_processor_unregister_performance(0); |
82 | free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map); | 82 | free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map); |
83 | kfree(eps_acpi_cpu_perf); | 83 | kfree(eps_acpi_cpu_perf); |
84 | eps_acpi_cpu_perf = NULL; | 84 | eps_acpi_cpu_perf = NULL; |
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index c30aaa6a54e8..0202429f1c5b 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c | |||
@@ -29,7 +29,6 @@ MODULE_LICENSE("GPL"); | |||
29 | 29 | ||
30 | struct cpufreq_acpi_io { | 30 | struct cpufreq_acpi_io { |
31 | struct acpi_processor_performance acpi_data; | 31 | struct acpi_processor_performance acpi_data; |
32 | struct cpufreq_frequency_table *freq_table; | ||
33 | unsigned int resume; | 32 | unsigned int resume; |
34 | }; | 33 | }; |
35 | 34 | ||
@@ -221,6 +220,7 @@ acpi_cpufreq_cpu_init ( | |||
221 | unsigned int cpu = policy->cpu; | 220 | unsigned int cpu = policy->cpu; |
222 | struct cpufreq_acpi_io *data; | 221 | struct cpufreq_acpi_io *data; |
223 | unsigned int result = 0; | 222 | unsigned int result = 0; |
223 | struct cpufreq_frequency_table *freq_table; | ||
224 | 224 | ||
225 | pr_debug("acpi_cpufreq_cpu_init\n"); | 225 | pr_debug("acpi_cpufreq_cpu_init\n"); |
226 | 226 | ||
@@ -254,10 +254,10 @@ acpi_cpufreq_cpu_init ( | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /* alloc freq_table */ | 256 | /* alloc freq_table */ |
257 | data->freq_table = kzalloc(sizeof(*data->freq_table) * | 257 | freq_table = kzalloc(sizeof(*freq_table) * |
258 | (data->acpi_data.state_count + 1), | 258 | (data->acpi_data.state_count + 1), |
259 | GFP_KERNEL); | 259 | GFP_KERNEL); |
260 | if (!data->freq_table) { | 260 | if (!freq_table) { |
261 | result = -ENOMEM; | 261 | result = -ENOMEM; |
262 | goto err_unreg; | 262 | goto err_unreg; |
263 | } | 263 | } |
@@ -276,14 +276,14 @@ acpi_cpufreq_cpu_init ( | |||
276 | for (i = 0; i <= data->acpi_data.state_count; i++) | 276 | for (i = 0; i <= data->acpi_data.state_count; i++) |
277 | { | 277 | { |
278 | if (i < data->acpi_data.state_count) { | 278 | if (i < data->acpi_data.state_count) { |
279 | data->freq_table[i].frequency = | 279 | freq_table[i].frequency = |
280 | data->acpi_data.states[i].core_frequency * 1000; | 280 | data->acpi_data.states[i].core_frequency * 1000; |
281 | } else { | 281 | } else { |
282 | data->freq_table[i].frequency = CPUFREQ_TABLE_END; | 282 | freq_table[i].frequency = CPUFREQ_TABLE_END; |
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | result = cpufreq_table_validate_and_show(policy, data->freq_table); | 286 | result = cpufreq_table_validate_and_show(policy, freq_table); |
287 | if (result) { | 287 | if (result) { |
288 | goto err_freqfree; | 288 | goto err_freqfree; |
289 | } | 289 | } |
@@ -311,9 +311,9 @@ acpi_cpufreq_cpu_init ( | |||
311 | return (result); | 311 | return (result); |
312 | 312 | ||
313 | err_freqfree: | 313 | err_freqfree: |
314 | kfree(data->freq_table); | 314 | kfree(freq_table); |
315 | err_unreg: | 315 | err_unreg: |
316 | acpi_processor_unregister_performance(&data->acpi_data, cpu); | 316 | acpi_processor_unregister_performance(cpu); |
317 | err_free: | 317 | err_free: |
318 | kfree(data); | 318 | kfree(data); |
319 | acpi_io_data[cpu] = NULL; | 319 | acpi_io_data[cpu] = NULL; |
@@ -332,8 +332,8 @@ acpi_cpufreq_cpu_exit ( | |||
332 | 332 | ||
333 | if (data) { | 333 | if (data) { |
334 | acpi_io_data[policy->cpu] = NULL; | 334 | acpi_io_data[policy->cpu] = NULL; |
335 | acpi_processor_unregister_performance(&data->acpi_data, | 335 | acpi_processor_unregister_performance(policy->cpu); |
336 | policy->cpu); | 336 | kfree(policy->freq_table); |
337 | kfree(data); | 337 | kfree(data); |
338 | } | 338 | } |
339 | 339 | ||
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index 129e266f7621..2faa4216bf2a 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c | |||
@@ -98,11 +98,10 @@ static int integrator_set_target(struct cpufreq_policy *policy, | |||
98 | /* get current setting */ | 98 | /* get current setting */ |
99 | cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); | 99 | cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); |
100 | 100 | ||
101 | if (machine_is_integrator()) { | 101 | if (machine_is_integrator()) |
102 | vco.s = (cm_osc >> 8) & 7; | 102 | vco.s = (cm_osc >> 8) & 7; |
103 | } else if (machine_is_cintegrator()) { | 103 | else if (machine_is_cintegrator()) |
104 | vco.s = 1; | 104 | vco.s = 1; |
105 | } | ||
106 | vco.v = cm_osc & 255; | 105 | vco.v = cm_osc & 255; |
107 | vco.r = 22; | 106 | vco.r = 22; |
108 | freqs.old = icst_hz(&cclk_params, vco) / 1000; | 107 | freqs.old = icst_hz(&cclk_params, vco) / 1000; |
@@ -163,11 +162,10 @@ static unsigned int integrator_get(unsigned int cpu) | |||
163 | /* detect memory etc. */ | 162 | /* detect memory etc. */ |
164 | cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); | 163 | cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); |
165 | 164 | ||
166 | if (machine_is_integrator()) { | 165 | if (machine_is_integrator()) |
167 | vco.s = (cm_osc >> 8) & 7; | 166 | vco.s = (cm_osc >> 8) & 7; |
168 | } else { | 167 | else |
169 | vco.s = 1; | 168 | vco.s = 1; |
170 | } | ||
171 | vco.v = cm_osc & 255; | 169 | vco.v = cm_osc & 255; |
172 | vco.r = 22; | 170 | vco.r = 22; |
173 | 171 | ||
@@ -203,7 +201,7 @@ static int __init integrator_cpufreq_probe(struct platform_device *pdev) | |||
203 | struct resource *res; | 201 | struct resource *res; |
204 | 202 | ||
205 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 203 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
206 | if (!res) | 204 | if (!res) |
207 | return -ENODEV; | 205 | return -ENODEV; |
208 | 206 | ||
209 | cm_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | 207 | cm_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); |
@@ -234,6 +232,6 @@ static struct platform_driver integrator_cpufreq_driver = { | |||
234 | module_platform_driver_probe(integrator_cpufreq_driver, | 232 | module_platform_driver_probe(integrator_cpufreq_driver, |
235 | integrator_cpufreq_probe); | 233 | integrator_cpufreq_probe); |
236 | 234 | ||
237 | MODULE_AUTHOR ("Russell M. King"); | 235 | MODULE_AUTHOR("Russell M. King"); |
238 | MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs"); | 236 | MODULE_DESCRIPTION("cpufreq driver for ARM Integrator CPUs"); |
239 | MODULE_LICENSE ("GPL"); | 237 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index fcb929ec5304..31d0548638e8 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -484,12 +484,11 @@ static void __init intel_pstate_sysfs_expose_params(void) | |||
484 | } | 484 | } |
485 | /************************** sysfs end ************************/ | 485 | /************************** sysfs end ************************/ |
486 | 486 | ||
487 | static void intel_pstate_hwp_enable(void) | 487 | static void intel_pstate_hwp_enable(struct cpudata *cpudata) |
488 | { | 488 | { |
489 | hwp_active++; | ||
490 | pr_info("intel_pstate: HWP enabled\n"); | 489 | pr_info("intel_pstate: HWP enabled\n"); |
491 | 490 | ||
492 | wrmsrl( MSR_PM_ENABLE, 0x1); | 491 | wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1); |
493 | } | 492 | } |
494 | 493 | ||
495 | static int byt_get_min_pstate(void) | 494 | static int byt_get_min_pstate(void) |
@@ -522,7 +521,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) | |||
522 | int32_t vid_fp; | 521 | int32_t vid_fp; |
523 | u32 vid; | 522 | u32 vid; |
524 | 523 | ||
525 | val = pstate << 8; | 524 | val = (u64)pstate << 8; |
526 | if (limits.no_turbo && !limits.turbo_disabled) | 525 | if (limits.no_turbo && !limits.turbo_disabled) |
527 | val |= (u64)1 << 32; | 526 | val |= (u64)1 << 32; |
528 | 527 | ||
@@ -611,7 +610,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate) | |||
611 | { | 610 | { |
612 | u64 val; | 611 | u64 val; |
613 | 612 | ||
614 | val = pstate << 8; | 613 | val = (u64)pstate << 8; |
615 | if (limits.no_turbo && !limits.turbo_disabled) | 614 | if (limits.no_turbo && !limits.turbo_disabled) |
616 | val |= (u64)1 << 32; | 615 | val |= (u64)1 << 32; |
617 | 616 | ||
@@ -909,6 +908,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
909 | ICPU(0x4c, byt_params), | 908 | ICPU(0x4c, byt_params), |
910 | ICPU(0x4e, core_params), | 909 | ICPU(0x4e, core_params), |
911 | ICPU(0x4f, core_params), | 910 | ICPU(0x4f, core_params), |
911 | ICPU(0x5e, core_params), | ||
912 | ICPU(0x56, core_params), | 912 | ICPU(0x56, core_params), |
913 | ICPU(0x57, knl_params), | 913 | ICPU(0x57, knl_params), |
914 | {} | 914 | {} |
@@ -933,6 +933,10 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
933 | cpu = all_cpu_data[cpunum]; | 933 | cpu = all_cpu_data[cpunum]; |
934 | 934 | ||
935 | cpu->cpu = cpunum; | 935 | cpu->cpu = cpunum; |
936 | |||
937 | if (hwp_active) | ||
938 | intel_pstate_hwp_enable(cpu); | ||
939 | |||
936 | intel_pstate_get_cpu_pstates(cpu); | 940 | intel_pstate_get_cpu_pstates(cpu); |
937 | 941 | ||
938 | init_timer_deferrable(&cpu->timer); | 942 | init_timer_deferrable(&cpu->timer); |
@@ -1170,6 +1174,10 @@ static struct hw_vendor_info vendor_info[] = { | |||
1170 | {1, "ORACLE", "X4270M3 ", PPC}, | 1174 | {1, "ORACLE", "X4270M3 ", PPC}, |
1171 | {1, "ORACLE", "X4270M2 ", PPC}, | 1175 | {1, "ORACLE", "X4270M2 ", PPC}, |
1172 | {1, "ORACLE", "X4170M2 ", PPC}, | 1176 | {1, "ORACLE", "X4170M2 ", PPC}, |
1177 | {1, "ORACLE", "X4170 M3", PPC}, | ||
1178 | {1, "ORACLE", "X4275 M3", PPC}, | ||
1179 | {1, "ORACLE", "X6-2 ", PPC}, | ||
1180 | {1, "ORACLE", "Sudbury ", PPC}, | ||
1173 | {0, "", ""}, | 1181 | {0, "", ""}, |
1174 | }; | 1182 | }; |
1175 | 1183 | ||
@@ -1246,7 +1254,7 @@ static int __init intel_pstate_init(void) | |||
1246 | return -ENOMEM; | 1254 | return -ENOMEM; |
1247 | 1255 | ||
1248 | if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) | 1256 | if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) |
1249 | intel_pstate_hwp_enable(); | 1257 | hwp_active++; |
1250 | 1258 | ||
1251 | if (!hwp_active && hwp_only) | 1259 | if (!hwp_active && hwp_only) |
1252 | goto out; | 1260 | goto out; |
diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c new file mode 100644 index 000000000000..49caed293a3b --- /dev/null +++ b/drivers/cpufreq/mt8173-cpufreq.c | |||
@@ -0,0 +1,527 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Linaro Ltd. | ||
3 | * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/cpu.h> | ||
17 | #include <linux/cpu_cooling.h> | ||
18 | #include <linux/cpufreq.h> | ||
19 | #include <linux/cpumask.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/pm_opp.h> | ||
23 | #include <linux/regulator/consumer.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/thermal.h> | ||
26 | |||
27 | #define MIN_VOLT_SHIFT (100000) | ||
28 | #define MAX_VOLT_SHIFT (200000) | ||
29 | #define MAX_VOLT_LIMIT (1150000) | ||
30 | #define VOLT_TOL (10000) | ||
31 | |||
32 | /* | ||
33 | * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS | ||
34 | * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in | ||
35 | * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two | ||
36 | * voltage inputs need to be controlled under a hardware limitation: | ||
37 | * 100mV < Vsram - Vproc < 200mV | ||
38 | * | ||
39 | * When scaling the clock frequency of a CPU clock domain, the clock source | ||
40 | * needs to be switched to another stable PLL clock temporarily until | ||
41 | * the original PLL becomes stable at target frequency. | ||
42 | */ | ||
43 | struct mtk_cpu_dvfs_info { | ||
44 | struct device *cpu_dev; | ||
45 | struct regulator *proc_reg; | ||
46 | struct regulator *sram_reg; | ||
47 | struct clk *cpu_clk; | ||
48 | struct clk *inter_clk; | ||
49 | struct thermal_cooling_device *cdev; | ||
50 | int intermediate_voltage; | ||
51 | bool need_voltage_tracking; | ||
52 | }; | ||
53 | |||
54 | static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, | ||
55 | int new_vproc) | ||
56 | { | ||
57 | struct regulator *proc_reg = info->proc_reg; | ||
58 | struct regulator *sram_reg = info->sram_reg; | ||
59 | int old_vproc, old_vsram, new_vsram, vsram, vproc, ret; | ||
60 | |||
61 | old_vproc = regulator_get_voltage(proc_reg); | ||
62 | old_vsram = regulator_get_voltage(sram_reg); | ||
63 | /* Vsram should not exceed the maximum allowed voltage of SoC. */ | ||
64 | new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT); | ||
65 | |||
66 | if (old_vproc < new_vproc) { | ||
67 | /* | ||
68 | * When scaling up voltages, Vsram and Vproc scale up step | ||
69 | * by step. At each step, set Vsram to (Vproc + 200mV) first, | ||
70 | * then set Vproc to (Vsram - 100mV). | ||
71 | * Keep doing it until Vsram and Vproc hit target voltages. | ||
72 | */ | ||
73 | do { | ||
74 | old_vsram = regulator_get_voltage(sram_reg); | ||
75 | old_vproc = regulator_get_voltage(proc_reg); | ||
76 | |||
77 | vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT); | ||
78 | |||
79 | if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { | ||
80 | vsram = MAX_VOLT_LIMIT; | ||
81 | |||
82 | /* | ||
83 | * If the target Vsram hits the maximum voltage, | ||
84 | * try to set the exact voltage value first. | ||
85 | */ | ||
86 | ret = regulator_set_voltage(sram_reg, vsram, | ||
87 | vsram); | ||
88 | if (ret) | ||
89 | ret = regulator_set_voltage(sram_reg, | ||
90 | vsram - VOLT_TOL, | ||
91 | vsram); | ||
92 | |||
93 | vproc = new_vproc; | ||
94 | } else { | ||
95 | ret = regulator_set_voltage(sram_reg, vsram, | ||
96 | vsram + VOLT_TOL); | ||
97 | |||
98 | vproc = vsram - MIN_VOLT_SHIFT; | ||
99 | } | ||
100 | if (ret) | ||
101 | return ret; | ||
102 | |||
103 | ret = regulator_set_voltage(proc_reg, vproc, | ||
104 | vproc + VOLT_TOL); | ||
105 | if (ret) { | ||
106 | regulator_set_voltage(sram_reg, old_vsram, | ||
107 | old_vsram); | ||
108 | return ret; | ||
109 | } | ||
110 | } while (vproc < new_vproc || vsram < new_vsram); | ||
111 | } else if (old_vproc > new_vproc) { | ||
112 | /* | ||
113 | * When scaling down voltages, Vsram and Vproc scale down step | ||
114 | * by step. At each step, set Vproc to (Vsram - 200mV) first, | ||
115 | * then set Vproc to (Vproc + 100mV). | ||
116 | * Keep doing it until Vsram and Vproc hit target voltages. | ||
117 | */ | ||
118 | do { | ||
119 | old_vproc = regulator_get_voltage(proc_reg); | ||
120 | old_vsram = regulator_get_voltage(sram_reg); | ||
121 | |||
122 | vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT); | ||
123 | ret = regulator_set_voltage(proc_reg, vproc, | ||
124 | vproc + VOLT_TOL); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | |||
128 | if (vproc == new_vproc) | ||
129 | vsram = new_vsram; | ||
130 | else | ||
131 | vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT); | ||
132 | |||
133 | if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { | ||
134 | vsram = MAX_VOLT_LIMIT; | ||
135 | |||
136 | /* | ||
137 | * If the target Vsram hits the maximum voltage, | ||
138 | * try to set the exact voltage value first. | ||
139 | */ | ||
140 | ret = regulator_set_voltage(sram_reg, vsram, | ||
141 | vsram); | ||
142 | if (ret) | ||
143 | ret = regulator_set_voltage(sram_reg, | ||
144 | vsram - VOLT_TOL, | ||
145 | vsram); | ||
146 | } else { | ||
147 | ret = regulator_set_voltage(sram_reg, vsram, | ||
148 | vsram + VOLT_TOL); | ||
149 | } | ||
150 | |||
151 | if (ret) { | ||
152 | regulator_set_voltage(proc_reg, old_vproc, | ||
153 | old_vproc); | ||
154 | return ret; | ||
155 | } | ||
156 | } while (vproc > new_vproc + VOLT_TOL || | ||
157 | vsram > new_vsram + VOLT_TOL); | ||
158 | } | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) | ||
164 | { | ||
165 | if (info->need_voltage_tracking) | ||
166 | return mtk_cpufreq_voltage_tracking(info, vproc); | ||
167 | else | ||
168 | return regulator_set_voltage(info->proc_reg, vproc, | ||
169 | vproc + VOLT_TOL); | ||
170 | } | ||
171 | |||
172 | static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, | ||
173 | unsigned int index) | ||
174 | { | ||
175 | struct cpufreq_frequency_table *freq_table = policy->freq_table; | ||
176 | struct clk *cpu_clk = policy->clk; | ||
177 | struct clk *armpll = clk_get_parent(cpu_clk); | ||
178 | struct mtk_cpu_dvfs_info *info = policy->driver_data; | ||
179 | struct device *cpu_dev = info->cpu_dev; | ||
180 | struct dev_pm_opp *opp; | ||
181 | long freq_hz, old_freq_hz; | ||
182 | int vproc, old_vproc, inter_vproc, target_vproc, ret; | ||
183 | |||
184 | inter_vproc = info->intermediate_voltage; | ||
185 | |||
186 | old_freq_hz = clk_get_rate(cpu_clk); | ||
187 | old_vproc = regulator_get_voltage(info->proc_reg); | ||
188 | |||
189 | freq_hz = freq_table[index].frequency * 1000; | ||
190 | |||
191 | rcu_read_lock(); | ||
192 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); | ||
193 | if (IS_ERR(opp)) { | ||
194 | rcu_read_unlock(); | ||
195 | pr_err("cpu%d: failed to find OPP for %ld\n", | ||
196 | policy->cpu, freq_hz); | ||
197 | return PTR_ERR(opp); | ||
198 | } | ||
199 | vproc = dev_pm_opp_get_voltage(opp); | ||
200 | rcu_read_unlock(); | ||
201 | |||
202 | /* | ||
203 | * If the new voltage or the intermediate voltage is higher than the | ||
204 | * current voltage, scale up voltage first. | ||
205 | */ | ||
206 | target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc; | ||
207 | if (old_vproc < target_vproc) { | ||
208 | ret = mtk_cpufreq_set_voltage(info, target_vproc); | ||
209 | if (ret) { | ||
210 | pr_err("cpu%d: failed to scale up voltage!\n", | ||
211 | policy->cpu); | ||
212 | mtk_cpufreq_set_voltage(info, old_vproc); | ||
213 | return ret; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | /* Reparent the CPU clock to intermediate clock. */ | ||
218 | ret = clk_set_parent(cpu_clk, info->inter_clk); | ||
219 | if (ret) { | ||
220 | pr_err("cpu%d: failed to re-parent cpu clock!\n", | ||
221 | policy->cpu); | ||
222 | mtk_cpufreq_set_voltage(info, old_vproc); | ||
223 | WARN_ON(1); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | /* Set the original PLL to target rate. */ | ||
228 | ret = clk_set_rate(armpll, freq_hz); | ||
229 | if (ret) { | ||
230 | pr_err("cpu%d: failed to scale cpu clock rate!\n", | ||
231 | policy->cpu); | ||
232 | clk_set_parent(cpu_clk, armpll); | ||
233 | mtk_cpufreq_set_voltage(info, old_vproc); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | /* Set parent of CPU clock back to the original PLL. */ | ||
238 | ret = clk_set_parent(cpu_clk, armpll); | ||
239 | if (ret) { | ||
240 | pr_err("cpu%d: failed to re-parent cpu clock!\n", | ||
241 | policy->cpu); | ||
242 | mtk_cpufreq_set_voltage(info, inter_vproc); | ||
243 | WARN_ON(1); | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * If the new voltage is lower than the intermediate voltage or the | ||
249 | * original voltage, scale down to the new voltage. | ||
250 | */ | ||
251 | if (vproc < inter_vproc || vproc < old_vproc) { | ||
252 | ret = mtk_cpufreq_set_voltage(info, vproc); | ||
253 | if (ret) { | ||
254 | pr_err("cpu%d: failed to scale down voltage!\n", | ||
255 | policy->cpu); | ||
256 | clk_set_parent(cpu_clk, info->inter_clk); | ||
257 | clk_set_rate(armpll, old_freq_hz); | ||
258 | clk_set_parent(cpu_clk, armpll); | ||
259 | return ret; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static void mtk_cpufreq_ready(struct cpufreq_policy *policy) | ||
267 | { | ||
268 | struct mtk_cpu_dvfs_info *info = policy->driver_data; | ||
269 | struct device_node *np = of_node_get(info->cpu_dev->of_node); | ||
270 | |||
271 | if (WARN_ON(!np)) | ||
272 | return; | ||
273 | |||
274 | if (of_find_property(np, "#cooling-cells", NULL)) { | ||
275 | info->cdev = of_cpufreq_cooling_register(np, | ||
276 | policy->related_cpus); | ||
277 | |||
278 | if (IS_ERR(info->cdev)) { | ||
279 | dev_err(info->cpu_dev, | ||
280 | "running cpufreq without cooling device: %ld\n", | ||
281 | PTR_ERR(info->cdev)); | ||
282 | |||
283 | info->cdev = NULL; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | of_node_put(np); | ||
288 | } | ||
289 | |||
290 | static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) | ||
291 | { | ||
292 | struct device *cpu_dev; | ||
293 | struct regulator *proc_reg = ERR_PTR(-ENODEV); | ||
294 | struct regulator *sram_reg = ERR_PTR(-ENODEV); | ||
295 | struct clk *cpu_clk = ERR_PTR(-ENODEV); | ||
296 | struct clk *inter_clk = ERR_PTR(-ENODEV); | ||
297 | struct dev_pm_opp *opp; | ||
298 | unsigned long rate; | ||
299 | int ret; | ||
300 | |||
301 | cpu_dev = get_cpu_device(cpu); | ||
302 | if (!cpu_dev) { | ||
303 | pr_err("failed to get cpu%d device\n", cpu); | ||
304 | return -ENODEV; | ||
305 | } | ||
306 | |||
307 | cpu_clk = clk_get(cpu_dev, "cpu"); | ||
308 | if (IS_ERR(cpu_clk)) { | ||
309 | if (PTR_ERR(cpu_clk) == -EPROBE_DEFER) | ||
310 | pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu); | ||
311 | else | ||
312 | pr_err("failed to get cpu clk for cpu%d\n", cpu); | ||
313 | |||
314 | ret = PTR_ERR(cpu_clk); | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | inter_clk = clk_get(cpu_dev, "intermediate"); | ||
319 | if (IS_ERR(inter_clk)) { | ||
320 | if (PTR_ERR(inter_clk) == -EPROBE_DEFER) | ||
321 | pr_warn("intermediate clk for cpu%d not ready, retry.\n", | ||
322 | cpu); | ||
323 | else | ||
324 | pr_err("failed to get intermediate clk for cpu%d\n", | ||
325 | cpu); | ||
326 | |||
327 | ret = PTR_ERR(inter_clk); | ||
328 | goto out_free_resources; | ||
329 | } | ||
330 | |||
331 | proc_reg = regulator_get_exclusive(cpu_dev, "proc"); | ||
332 | if (IS_ERR(proc_reg)) { | ||
333 | if (PTR_ERR(proc_reg) == -EPROBE_DEFER) | ||
334 | pr_warn("proc regulator for cpu%d not ready, retry.\n", | ||
335 | cpu); | ||
336 | else | ||
337 | pr_err("failed to get proc regulator for cpu%d\n", | ||
338 | cpu); | ||
339 | |||
340 | ret = PTR_ERR(proc_reg); | ||
341 | goto out_free_resources; | ||
342 | } | ||
343 | |||
344 | /* Both presence and absence of sram regulator are valid cases. */ | ||
345 | sram_reg = regulator_get_exclusive(cpu_dev, "sram"); | ||
346 | |||
347 | ret = of_init_opp_table(cpu_dev); | ||
348 | if (ret) { | ||
349 | pr_warn("no OPP table for cpu%d\n", cpu); | ||
350 | goto out_free_resources; | ||
351 | } | ||
352 | |||
353 | /* Search a safe voltage for intermediate frequency. */ | ||
354 | rate = clk_get_rate(inter_clk); | ||
355 | rcu_read_lock(); | ||
356 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); | ||
357 | if (IS_ERR(opp)) { | ||
358 | rcu_read_unlock(); | ||
359 | pr_err("failed to get intermediate opp for cpu%d\n", cpu); | ||
360 | ret = PTR_ERR(opp); | ||
361 | goto out_free_opp_table; | ||
362 | } | ||
363 | info->intermediate_voltage = dev_pm_opp_get_voltage(opp); | ||
364 | rcu_read_unlock(); | ||
365 | |||
366 | info->cpu_dev = cpu_dev; | ||
367 | info->proc_reg = proc_reg; | ||
368 | info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg; | ||
369 | info->cpu_clk = cpu_clk; | ||
370 | info->inter_clk = inter_clk; | ||
371 | |||
372 | /* | ||
373 | * If SRAM regulator is present, software "voltage tracking" is needed | ||
374 | * for this CPU power domain. | ||
375 | */ | ||
376 | info->need_voltage_tracking = !IS_ERR(sram_reg); | ||
377 | |||
378 | return 0; | ||
379 | |||
380 | out_free_opp_table: | ||
381 | of_free_opp_table(cpu_dev); | ||
382 | |||
383 | out_free_resources: | ||
384 | if (!IS_ERR(proc_reg)) | ||
385 | regulator_put(proc_reg); | ||
386 | if (!IS_ERR(sram_reg)) | ||
387 | regulator_put(sram_reg); | ||
388 | if (!IS_ERR(cpu_clk)) | ||
389 | clk_put(cpu_clk); | ||
390 | if (!IS_ERR(inter_clk)) | ||
391 | clk_put(inter_clk); | ||
392 | |||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info) | ||
397 | { | ||
398 | if (!IS_ERR(info->proc_reg)) | ||
399 | regulator_put(info->proc_reg); | ||
400 | if (!IS_ERR(info->sram_reg)) | ||
401 | regulator_put(info->sram_reg); | ||
402 | if (!IS_ERR(info->cpu_clk)) | ||
403 | clk_put(info->cpu_clk); | ||
404 | if (!IS_ERR(info->inter_clk)) | ||
405 | clk_put(info->inter_clk); | ||
406 | |||
407 | of_free_opp_table(info->cpu_dev); | ||
408 | } | ||
409 | |||
410 | static int mtk_cpufreq_init(struct cpufreq_policy *policy) | ||
411 | { | ||
412 | struct mtk_cpu_dvfs_info *info; | ||
413 | struct cpufreq_frequency_table *freq_table; | ||
414 | int ret; | ||
415 | |||
416 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
417 | if (!info) | ||
418 | return -ENOMEM; | ||
419 | |||
420 | ret = mtk_cpu_dvfs_info_init(info, policy->cpu); | ||
421 | if (ret) { | ||
422 | pr_err("%s failed to initialize dvfs info for cpu%d\n", | ||
423 | __func__, policy->cpu); | ||
424 | goto out_free_dvfs_info; | ||
425 | } | ||
426 | |||
427 | ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); | ||
428 | if (ret) { | ||
429 | pr_err("failed to init cpufreq table for cpu%d: %d\n", | ||
430 | policy->cpu, ret); | ||
431 | goto out_release_dvfs_info; | ||
432 | } | ||
433 | |||
434 | ret = cpufreq_table_validate_and_show(policy, freq_table); | ||
435 | if (ret) { | ||
436 | pr_err("%s: invalid frequency table: %d\n", __func__, ret); | ||
437 | goto out_free_cpufreq_table; | ||
438 | } | ||
439 | |||
440 | /* CPUs in the same cluster share a clock and power domain. */ | ||
441 | cpumask_copy(policy->cpus, &cpu_topology[policy->cpu].core_sibling); | ||
442 | policy->driver_data = info; | ||
443 | policy->clk = info->cpu_clk; | ||
444 | |||
445 | return 0; | ||
446 | |||
447 | out_free_cpufreq_table: | ||
448 | dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); | ||
449 | |||
450 | out_release_dvfs_info: | ||
451 | mtk_cpu_dvfs_info_release(info); | ||
452 | |||
453 | out_free_dvfs_info: | ||
454 | kfree(info); | ||
455 | |||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | static int mtk_cpufreq_exit(struct cpufreq_policy *policy) | ||
460 | { | ||
461 | struct mtk_cpu_dvfs_info *info = policy->driver_data; | ||
462 | |||
463 | cpufreq_cooling_unregister(info->cdev); | ||
464 | dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); | ||
465 | mtk_cpu_dvfs_info_release(info); | ||
466 | kfree(info); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static struct cpufreq_driver mt8173_cpufreq_driver = { | ||
472 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
473 | .verify = cpufreq_generic_frequency_table_verify, | ||
474 | .target_index = mtk_cpufreq_set_target, | ||
475 | .get = cpufreq_generic_get, | ||
476 | .init = mtk_cpufreq_init, | ||
477 | .exit = mtk_cpufreq_exit, | ||
478 | .ready = mtk_cpufreq_ready, | ||
479 | .name = "mtk-cpufreq", | ||
480 | .attr = cpufreq_generic_attr, | ||
481 | }; | ||
482 | |||
483 | static int mt8173_cpufreq_probe(struct platform_device *pdev) | ||
484 | { | ||
485 | int ret; | ||
486 | |||
487 | ret = cpufreq_register_driver(&mt8173_cpufreq_driver); | ||
488 | if (ret) | ||
489 | pr_err("failed to register mtk cpufreq driver\n"); | ||
490 | |||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | static struct platform_driver mt8173_cpufreq_platdrv = { | ||
495 | .driver = { | ||
496 | .name = "mt8173-cpufreq", | ||
497 | }, | ||
498 | .probe = mt8173_cpufreq_probe, | ||
499 | }; | ||
500 | |||
501 | static int mt8173_cpufreq_driver_init(void) | ||
502 | { | ||
503 | struct platform_device *pdev; | ||
504 | int err; | ||
505 | |||
506 | if (!of_machine_is_compatible("mediatek,mt8173")) | ||
507 | return -ENODEV; | ||
508 | |||
509 | err = platform_driver_register(&mt8173_cpufreq_platdrv); | ||
510 | if (err) | ||
511 | return err; | ||
512 | |||
513 | /* | ||
514 | * Since there's no place to hold device registration code and no | ||
515 | * device tree based way to match cpufreq driver yet, both the driver | ||
516 | * and the device registration codes are put here to handle defer | ||
517 | * probing. | ||
518 | */ | ||
519 | pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0); | ||
520 | if (IS_ERR(pdev)) { | ||
521 | pr_err("failed to register mtk-cpufreq platform device\n"); | ||
522 | return PTR_ERR(pdev); | ||
523 | } | ||
524 | |||
525 | return 0; | ||
526 | } | ||
527 | device_initcall(mt8173_cpufreq_driver_init); | ||
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 37c5742482d8..c1ae1999770a 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c | |||
@@ -421,7 +421,7 @@ static int powernow_acpi_init(void) | |||
421 | return 0; | 421 | return 0; |
422 | 422 | ||
423 | err2: | 423 | err2: |
424 | acpi_processor_unregister_performance(acpi_processor_perf, 0); | 424 | acpi_processor_unregister_performance(0); |
425 | err1: | 425 | err1: |
426 | free_cpumask_var(acpi_processor_perf->shared_cpu_map); | 426 | free_cpumask_var(acpi_processor_perf->shared_cpu_map); |
427 | err05: | 427 | err05: |
@@ -661,7 +661,7 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy) | |||
661 | { | 661 | { |
662 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI | 662 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
663 | if (acpi_processor_perf) { | 663 | if (acpi_processor_perf) { |
664 | acpi_processor_unregister_performance(acpi_processor_perf, 0); | 664 | acpi_processor_unregister_performance(0); |
665 | free_cpumask_var(acpi_processor_perf->shared_cpu_map); | 665 | free_cpumask_var(acpi_processor_perf->shared_cpu_map); |
666 | kfree(acpi_processor_perf); | 666 | kfree(acpi_processor_perf); |
667 | } | 667 | } |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 5c035d04d827..0b5bf135b090 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -795,7 +795,7 @@ err_out_mem: | |||
795 | kfree(powernow_table); | 795 | kfree(powernow_table); |
796 | 796 | ||
797 | err_out: | 797 | err_out: |
798 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); | 798 | acpi_processor_unregister_performance(data->cpu); |
799 | 799 | ||
800 | /* data->acpi_data.state_count informs us at ->exit() | 800 | /* data->acpi_data.state_count informs us at ->exit() |
801 | * whether ACPI was used */ | 801 | * whether ACPI was used */ |
@@ -863,8 +863,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, | |||
863 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) | 863 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) |
864 | { | 864 | { |
865 | if (data->acpi_data.state_count) | 865 | if (data->acpi_data.state_count) |
866 | acpi_processor_unregister_performance(&data->acpi_data, | 866 | acpi_processor_unregister_performance(data->cpu); |
867 | data->cpu); | ||
868 | free_cpumask_var(data->acpi_data.shared_cpu_map); | 867 | free_cpumask_var(data->acpi_data.shared_cpu_map); |
869 | } | 868 | } |
870 | 869 | ||
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index ebef0d8279c7..64994e10638e 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c | |||
@@ -27,20 +27,31 @@ | |||
27 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
28 | #include <linux/of.h> | 28 | #include <linux/of.h> |
29 | #include <linux/reboot.h> | 29 | #include <linux/reboot.h> |
30 | #include <linux/slab.h> | ||
30 | 31 | ||
31 | #include <asm/cputhreads.h> | 32 | #include <asm/cputhreads.h> |
32 | #include <asm/firmware.h> | 33 | #include <asm/firmware.h> |
33 | #include <asm/reg.h> | 34 | #include <asm/reg.h> |
34 | #include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ | 35 | #include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ |
36 | #include <asm/opal.h> | ||
35 | 37 | ||
36 | #define POWERNV_MAX_PSTATES 256 | 38 | #define POWERNV_MAX_PSTATES 256 |
37 | #define PMSR_PSAFE_ENABLE (1UL << 30) | 39 | #define PMSR_PSAFE_ENABLE (1UL << 30) |
38 | #define PMSR_SPR_EM_DISABLE (1UL << 31) | 40 | #define PMSR_SPR_EM_DISABLE (1UL << 31) |
39 | #define PMSR_MAX(x) ((x >> 32) & 0xFF) | 41 | #define PMSR_MAX(x) ((x >> 32) & 0xFF) |
40 | #define PMSR_LP(x) ((x >> 48) & 0xFF) | ||
41 | 42 | ||
42 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; | 43 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; |
43 | static bool rebooting, throttled; | 44 | static bool rebooting, throttled, occ_reset; |
45 | |||
46 | static struct chip { | ||
47 | unsigned int id; | ||
48 | bool throttled; | ||
49 | cpumask_t mask; | ||
50 | struct work_struct throttle; | ||
51 | bool restore; | ||
52 | } *chips; | ||
53 | |||
54 | static int nr_chips; | ||
44 | 55 | ||
45 | /* | 56 | /* |
46 | * Note: The set of pstates consists of contiguous integers, the | 57 | * Note: The set of pstates consists of contiguous integers, the |
@@ -298,28 +309,35 @@ static inline unsigned int get_nominal_index(void) | |||
298 | return powernv_pstate_info.max - powernv_pstate_info.nominal; | 309 | return powernv_pstate_info.max - powernv_pstate_info.nominal; |
299 | } | 310 | } |
300 | 311 | ||
301 | static void powernv_cpufreq_throttle_check(unsigned int cpu) | 312 | static void powernv_cpufreq_throttle_check(void *data) |
302 | { | 313 | { |
314 | unsigned int cpu = smp_processor_id(); | ||
303 | unsigned long pmsr; | 315 | unsigned long pmsr; |
304 | int pmsr_pmax, pmsr_lp; | 316 | int pmsr_pmax, i; |
305 | 317 | ||
306 | pmsr = get_pmspr(SPRN_PMSR); | 318 | pmsr = get_pmspr(SPRN_PMSR); |
307 | 319 | ||
320 | for (i = 0; i < nr_chips; i++) | ||
321 | if (chips[i].id == cpu_to_chip_id(cpu)) | ||
322 | break; | ||
323 | |||
308 | /* Check for Pmax Capping */ | 324 | /* Check for Pmax Capping */ |
309 | pmsr_pmax = (s8)PMSR_MAX(pmsr); | 325 | pmsr_pmax = (s8)PMSR_MAX(pmsr); |
310 | if (pmsr_pmax != powernv_pstate_info.max) { | 326 | if (pmsr_pmax != powernv_pstate_info.max) { |
311 | throttled = true; | 327 | if (chips[i].throttled) |
312 | pr_info("CPU %d Pmax is reduced to %d\n", cpu, pmsr_pmax); | 328 | goto next; |
313 | pr_info("Max allowed Pstate is capped\n"); | 329 | chips[i].throttled = true; |
330 | pr_info("CPU %d on Chip %u has Pmax reduced to %d\n", cpu, | ||
331 | chips[i].id, pmsr_pmax); | ||
332 | } else if (chips[i].throttled) { | ||
333 | chips[i].throttled = false; | ||
334 | pr_info("CPU %d on Chip %u has Pmax restored to %d\n", cpu, | ||
335 | chips[i].id, pmsr_pmax); | ||
314 | } | 336 | } |
315 | 337 | ||
316 | /* | 338 | /* Check if Psafe_mode_active is set in PMSR. */ |
317 | * Check for Psafe by reading LocalPstate | 339 | next: |
318 | * or check if Psafe_mode_active is set in PMSR. | 340 | if (pmsr & PMSR_PSAFE_ENABLE) { |
319 | */ | ||
320 | pmsr_lp = (s8)PMSR_LP(pmsr); | ||
321 | if ((pmsr_lp < powernv_pstate_info.min) || | ||
322 | (pmsr & PMSR_PSAFE_ENABLE)) { | ||
323 | throttled = true; | 341 | throttled = true; |
324 | pr_info("Pstate set to safe frequency\n"); | 342 | pr_info("Pstate set to safe frequency\n"); |
325 | } | 343 | } |
@@ -350,7 +368,7 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy, | |||
350 | return 0; | 368 | return 0; |
351 | 369 | ||
352 | if (!throttled) | 370 | if (!throttled) |
353 | powernv_cpufreq_throttle_check(smp_processor_id()); | 371 | powernv_cpufreq_throttle_check(NULL); |
354 | 372 | ||
355 | freq_data.pstate_id = powernv_freqs[new_index].driver_data; | 373 | freq_data.pstate_id = powernv_freqs[new_index].driver_data; |
356 | 374 | ||
@@ -395,6 +413,119 @@ static struct notifier_block powernv_cpufreq_reboot_nb = { | |||
395 | .notifier_call = powernv_cpufreq_reboot_notifier, | 413 | .notifier_call = powernv_cpufreq_reboot_notifier, |
396 | }; | 414 | }; |
397 | 415 | ||
416 | void powernv_cpufreq_work_fn(struct work_struct *work) | ||
417 | { | ||
418 | struct chip *chip = container_of(work, struct chip, throttle); | ||
419 | unsigned int cpu; | ||
420 | cpumask_var_t mask; | ||
421 | |||
422 | smp_call_function_any(&chip->mask, | ||
423 | powernv_cpufreq_throttle_check, NULL, 0); | ||
424 | |||
425 | if (!chip->restore) | ||
426 | return; | ||
427 | |||
428 | chip->restore = false; | ||
429 | cpumask_copy(mask, &chip->mask); | ||
430 | for_each_cpu_and(cpu, mask, cpu_online_mask) { | ||
431 | int index, tcpu; | ||
432 | struct cpufreq_policy policy; | ||
433 | |||
434 | cpufreq_get_policy(&policy, cpu); | ||
435 | cpufreq_frequency_table_target(&policy, policy.freq_table, | ||
436 | policy.cur, | ||
437 | CPUFREQ_RELATION_C, &index); | ||
438 | powernv_cpufreq_target_index(&policy, index); | ||
439 | for_each_cpu(tcpu, policy.cpus) | ||
440 | cpumask_clear_cpu(tcpu, mask); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | static char throttle_reason[][30] = { | ||
445 | "No throttling", | ||
446 | "Power Cap", | ||
447 | "Processor Over Temperature", | ||
448 | "Power Supply Failure", | ||
449 | "Over Current", | ||
450 | "OCC Reset" | ||
451 | }; | ||
452 | |||
453 | static int powernv_cpufreq_occ_msg(struct notifier_block *nb, | ||
454 | unsigned long msg_type, void *_msg) | ||
455 | { | ||
456 | struct opal_msg *msg = _msg; | ||
457 | struct opal_occ_msg omsg; | ||
458 | int i; | ||
459 | |||
460 | if (msg_type != OPAL_MSG_OCC) | ||
461 | return 0; | ||
462 | |||
463 | omsg.type = be64_to_cpu(msg->params[0]); | ||
464 | |||
465 | switch (omsg.type) { | ||
466 | case OCC_RESET: | ||
467 | occ_reset = true; | ||
468 | pr_info("OCC (On Chip Controller - enforces hard thermal/power limits) Resetting\n"); | ||
469 | /* | ||
470 | * powernv_cpufreq_throttle_check() is called in | ||
471 | * target() callback which can detect the throttle state | ||
472 | * for governors like ondemand. | ||
473 | * But static governors will not call target() often thus | ||
474 | * report throttling here. | ||
475 | */ | ||
476 | if (!throttled) { | ||
477 | throttled = true; | ||
478 | pr_crit("CPU frequency is throttled for duration\n"); | ||
479 | } | ||
480 | |||
481 | break; | ||
482 | case OCC_LOAD: | ||
483 | pr_info("OCC Loading, CPU frequency is throttled until OCC is started\n"); | ||
484 | break; | ||
485 | case OCC_THROTTLE: | ||
486 | omsg.chip = be64_to_cpu(msg->params[1]); | ||
487 | omsg.throttle_status = be64_to_cpu(msg->params[2]); | ||
488 | |||
489 | if (occ_reset) { | ||
490 | occ_reset = false; | ||
491 | throttled = false; | ||
492 | pr_info("OCC Active, CPU frequency is no longer throttled\n"); | ||
493 | |||
494 | for (i = 0; i < nr_chips; i++) { | ||
495 | chips[i].restore = true; | ||
496 | schedule_work(&chips[i].throttle); | ||
497 | } | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | if (omsg.throttle_status && | ||
503 | omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) | ||
504 | pr_info("OCC: Chip %u Pmax reduced due to %s\n", | ||
505 | (unsigned int)omsg.chip, | ||
506 | throttle_reason[omsg.throttle_status]); | ||
507 | else if (!omsg.throttle_status) | ||
508 | pr_info("OCC: Chip %u %s\n", (unsigned int)omsg.chip, | ||
509 | throttle_reason[omsg.throttle_status]); | ||
510 | else | ||
511 | return 0; | ||
512 | |||
513 | for (i = 0; i < nr_chips; i++) | ||
514 | if (chips[i].id == omsg.chip) { | ||
515 | if (!omsg.throttle_status) | ||
516 | chips[i].restore = true; | ||
517 | schedule_work(&chips[i].throttle); | ||
518 | } | ||
519 | } | ||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | static struct notifier_block powernv_cpufreq_opal_nb = { | ||
524 | .notifier_call = powernv_cpufreq_occ_msg, | ||
525 | .next = NULL, | ||
526 | .priority = 0, | ||
527 | }; | ||
528 | |||
398 | static void powernv_cpufreq_stop_cpu(struct cpufreq_policy *policy) | 529 | static void powernv_cpufreq_stop_cpu(struct cpufreq_policy *policy) |
399 | { | 530 | { |
400 | struct powernv_smp_call_data freq_data; | 531 | struct powernv_smp_call_data freq_data; |
@@ -414,6 +545,36 @@ static struct cpufreq_driver powernv_cpufreq_driver = { | |||
414 | .attr = powernv_cpu_freq_attr, | 545 | .attr = powernv_cpu_freq_attr, |
415 | }; | 546 | }; |
416 | 547 | ||
548 | static int init_chip_info(void) | ||
549 | { | ||
550 | unsigned int chip[256]; | ||
551 | unsigned int cpu, i; | ||
552 | unsigned int prev_chip_id = UINT_MAX; | ||
553 | |||
554 | for_each_possible_cpu(cpu) { | ||
555 | unsigned int id = cpu_to_chip_id(cpu); | ||
556 | |||
557 | if (prev_chip_id != id) { | ||
558 | prev_chip_id = id; | ||
559 | chip[nr_chips++] = id; | ||
560 | } | ||
561 | } | ||
562 | |||
563 | chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL); | ||
564 | if (!chips) | ||
565 | return -ENOMEM; | ||
566 | |||
567 | for (i = 0; i < nr_chips; i++) { | ||
568 | chips[i].id = chip[i]; | ||
569 | chips[i].throttled = false; | ||
570 | cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); | ||
571 | INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); | ||
572 | chips[i].restore = false; | ||
573 | } | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
417 | static int __init powernv_cpufreq_init(void) | 578 | static int __init powernv_cpufreq_init(void) |
418 | { | 579 | { |
419 | int rc = 0; | 580 | int rc = 0; |
@@ -429,7 +590,13 @@ static int __init powernv_cpufreq_init(void) | |||
429 | return rc; | 590 | return rc; |
430 | } | 591 | } |
431 | 592 | ||
593 | /* Populate chip info */ | ||
594 | rc = init_chip_info(); | ||
595 | if (rc) | ||
596 | return rc; | ||
597 | |||
432 | register_reboot_notifier(&powernv_cpufreq_reboot_nb); | 598 | register_reboot_notifier(&powernv_cpufreq_reboot_nb); |
599 | opal_message_notifier_register(OPAL_MSG_OCC, &powernv_cpufreq_opal_nb); | ||
433 | return cpufreq_register_driver(&powernv_cpufreq_driver); | 600 | return cpufreq_register_driver(&powernv_cpufreq_driver); |
434 | } | 601 | } |
435 | module_init(powernv_cpufreq_init); | 602 | module_init(powernv_cpufreq_init); |
@@ -437,6 +604,8 @@ module_init(powernv_cpufreq_init); | |||
437 | static void __exit powernv_cpufreq_exit(void) | 604 | static void __exit powernv_cpufreq_exit(void) |
438 | { | 605 | { |
439 | unregister_reboot_notifier(&powernv_cpufreq_reboot_nb); | 606 | unregister_reboot_notifier(&powernv_cpufreq_reboot_nb); |
607 | opal_message_notifier_unregister(OPAL_MSG_OCC, | ||
608 | &powernv_cpufreq_opal_nb); | ||
440 | cpufreq_unregister_driver(&powernv_cpufreq_driver); | 609 | cpufreq_unregister_driver(&powernv_cpufreq_driver); |
441 | } | 610 | } |
442 | module_exit(powernv_cpufreq_exit); | 611 | module_exit(powernv_cpufreq_exit); |
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c index d29e8da396a0..7969f7690498 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c | |||
@@ -97,8 +97,8 @@ static int pmi_notifier(struct notifier_block *nb, | |||
97 | struct cpufreq_frequency_table *cbe_freqs; | 97 | struct cpufreq_frequency_table *cbe_freqs; |
98 | u8 node; | 98 | u8 node; |
99 | 99 | ||
100 | /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE | 100 | /* Should this really be called for CPUFREQ_ADJUST and CPUFREQ_NOTIFY |
101 | * and CPUFREQ_NOTIFY policy events?) | 101 | * policy events?) |
102 | */ | 102 | */ |
103 | if (event == CPUFREQ_START) | 103 | if (event == CPUFREQ_START) |
104 | return 0; | 104 | return 0; |
diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c index ffa3389e535b..992ce6f9abec 100644 --- a/drivers/cpufreq/sfi-cpufreq.c +++ b/drivers/cpufreq/sfi-cpufreq.c | |||
@@ -45,12 +45,10 @@ static int sfi_parse_freq(struct sfi_table_header *table) | |||
45 | pentry = (struct sfi_freq_table_entry *)sb->pentry; | 45 | pentry = (struct sfi_freq_table_entry *)sb->pentry; |
46 | totallen = num_freq_table_entries * sizeof(*pentry); | 46 | totallen = num_freq_table_entries * sizeof(*pentry); |
47 | 47 | ||
48 | sfi_cpufreq_array = kzalloc(totallen, GFP_KERNEL); | 48 | sfi_cpufreq_array = kmemdup(pentry, totallen, GFP_KERNEL); |
49 | if (!sfi_cpufreq_array) | 49 | if (!sfi_cpufreq_array) |
50 | return -ENOMEM; | 50 | return -ENOMEM; |
51 | 51 | ||
52 | memcpy(sfi_cpufreq_array, pentry, totallen); | ||
53 | |||
54 | return 0; | 52 | return 0; |
55 | } | 53 | } |
56 | 54 | ||
diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c index 4ab7a2156672..15d3214aaa00 100644 --- a/drivers/cpufreq/speedstep-lib.c +++ b/drivers/cpufreq/speedstep-lib.c | |||
@@ -386,7 +386,7 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, | |||
386 | unsigned int prev_speed; | 386 | unsigned int prev_speed; |
387 | unsigned int ret = 0; | 387 | unsigned int ret = 0; |
388 | unsigned long flags; | 388 | unsigned long flags; |
389 | struct timeval tv1, tv2; | 389 | ktime_t tv1, tv2; |
390 | 390 | ||
391 | if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) | 391 | if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) |
392 | return -EINVAL; | 392 | return -EINVAL; |
@@ -415,14 +415,14 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, | |||
415 | 415 | ||
416 | /* start latency measurement */ | 416 | /* start latency measurement */ |
417 | if (transition_latency) | 417 | if (transition_latency) |
418 | do_gettimeofday(&tv1); | 418 | tv1 = ktime_get(); |
419 | 419 | ||
420 | /* switch to high state */ | 420 | /* switch to high state */ |
421 | set_state(SPEEDSTEP_HIGH); | 421 | set_state(SPEEDSTEP_HIGH); |
422 | 422 | ||
423 | /* end latency measurement */ | 423 | /* end latency measurement */ |
424 | if (transition_latency) | 424 | if (transition_latency) |
425 | do_gettimeofday(&tv2); | 425 | tv2 = ktime_get(); |
426 | 426 | ||
427 | *high_speed = speedstep_get_frequency(processor); | 427 | *high_speed = speedstep_get_frequency(processor); |
428 | if (!*high_speed) { | 428 | if (!*high_speed) { |
@@ -442,8 +442,7 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, | |||
442 | set_state(SPEEDSTEP_LOW); | 442 | set_state(SPEEDSTEP_LOW); |
443 | 443 | ||
444 | if (transition_latency) { | 444 | if (transition_latency) { |
445 | *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC + | 445 | *transition_latency = ktime_to_us(ktime_sub(tv2, tv1)); |
446 | tv2.tv_usec - tv1.tv_usec; | ||
447 | pr_debug("transition latency is %u uSec\n", *transition_latency); | 446 | pr_debug("transition latency is %u uSec\n", *transition_latency); |
448 | 447 | ||
449 | /* convert uSec to nSec and add 20% for safety reasons */ | 448 | /* convert uSec to nSec and add 20% for safety reasons */ |
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index 7245611ec963..94813af97f09 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c | |||
@@ -1668,7 +1668,6 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) | |||
1668 | 1668 | ||
1669 | switch (val) { | 1669 | switch (val) { |
1670 | case CPUFREQ_ADJUST: | 1670 | case CPUFREQ_ADJUST: |
1671 | case CPUFREQ_INCOMPATIBLE: | ||
1672 | pr_debug("min dma period: %d ps, " | 1671 | pr_debug("min dma period: %d ps, " |
1673 | "new clock %d kHz\n", pxafb_display_dma_period(var), | 1672 | "new clock %d kHz\n", pxafb_display_dma_period(var), |
1674 | policy->max); | 1673 | policy->max); |
diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 89dd7e02197f..dcf774c15889 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c | |||
@@ -1042,7 +1042,6 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val, | |||
1042 | 1042 | ||
1043 | switch (val) { | 1043 | switch (val) { |
1044 | case CPUFREQ_ADJUST: | 1044 | case CPUFREQ_ADJUST: |
1045 | case CPUFREQ_INCOMPATIBLE: | ||
1046 | dev_dbg(fbi->dev, "min dma period: %d ps, " | 1045 | dev_dbg(fbi->dev, "min dma period: %d ps, " |
1047 | "new clock %d kHz\n", sa1100fb_min_dma_period(fbi), | 1046 | "new clock %d kHz\n", sa1100fb_min_dma_period(fbi), |
1048 | policy->max); | 1047 | policy->max); |
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 59fc190f1e92..70fa438000af 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -560,11 +560,9 @@ static int __init xen_acpi_processor_init(void) | |||
560 | 560 | ||
561 | return 0; | 561 | return 0; |
562 | err_unregister: | 562 | err_unregister: |
563 | for_each_possible_cpu(i) { | 563 | for_each_possible_cpu(i) |
564 | struct acpi_processor_performance *perf; | 564 | acpi_processor_unregister_performance(i); |
565 | perf = per_cpu_ptr(acpi_perf_data, i); | 565 | |
566 | acpi_processor_unregister_performance(perf, i); | ||
567 | } | ||
568 | err_out: | 566 | err_out: |
569 | /* Freeing a NULL pointer is OK: alloc_percpu zeroes. */ | 567 | /* Freeing a NULL pointer is OK: alloc_percpu zeroes. */ |
570 | free_acpi_perf_data(); | 568 | free_acpi_perf_data(); |
@@ -579,11 +577,9 @@ static void __exit xen_acpi_processor_exit(void) | |||
579 | kfree(acpi_ids_done); | 577 | kfree(acpi_ids_done); |
580 | kfree(acpi_id_present); | 578 | kfree(acpi_id_present); |
581 | kfree(acpi_id_cst_present); | 579 | kfree(acpi_id_cst_present); |
582 | for_each_possible_cpu(i) { | 580 | for_each_possible_cpu(i) |
583 | struct acpi_processor_performance *perf; | 581 | acpi_processor_unregister_performance(i); |
584 | perf = per_cpu_ptr(acpi_perf_data, i); | 582 | |
585 | acpi_processor_unregister_performance(perf, i); | ||
586 | } | ||
587 | free_acpi_perf_data(); | 583 | free_acpi_perf_data(); |
588 | } | 584 | } |
589 | 585 | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 2c4e7a9c1725..ff5f135f16b1 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -228,10 +228,7 @@ extern int acpi_processor_preregister_performance(struct | |||
228 | 228 | ||
229 | extern int acpi_processor_register_performance(struct acpi_processor_performance | 229 | extern int acpi_processor_register_performance(struct acpi_processor_performance |
230 | *performance, unsigned int cpu); | 230 | *performance, unsigned int cpu); |
231 | extern void acpi_processor_unregister_performance(struct | 231 | extern void acpi_processor_unregister_performance(unsigned int cpu); |
232 | acpi_processor_performance | ||
233 | *performance, | ||
234 | unsigned int cpu); | ||
235 | 232 | ||
236 | /* note: this locks both the calling module and the processor module | 233 | /* note: this locks both the calling module and the processor module |
237 | if a _PPC object exists, rmmod is disallowed then */ | 234 | if a _PPC object exists, rmmod is disallowed then */ |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index bde1e567b3a9..6ff6a4d95eea 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -51,11 +51,9 @@ struct cpufreq_cpuinfo { | |||
51 | unsigned int transition_latency; | 51 | unsigned int transition_latency; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct cpufreq_real_policy { | 54 | struct cpufreq_user_policy { |
55 | unsigned int min; /* in kHz */ | 55 | unsigned int min; /* in kHz */ |
56 | unsigned int max; /* in kHz */ | 56 | unsigned int max; /* in kHz */ |
57 | unsigned int policy; /* see above */ | ||
58 | struct cpufreq_governor *governor; /* see below */ | ||
59 | }; | 57 | }; |
60 | 58 | ||
61 | struct cpufreq_policy { | 59 | struct cpufreq_policy { |
@@ -88,7 +86,7 @@ struct cpufreq_policy { | |||
88 | struct work_struct update; /* if update_policy() needs to be | 86 | struct work_struct update; /* if update_policy() needs to be |
89 | * called, but you're in IRQ context */ | 87 | * called, but you're in IRQ context */ |
90 | 88 | ||
91 | struct cpufreq_real_policy user_policy; | 89 | struct cpufreq_user_policy user_policy; |
92 | struct cpufreq_frequency_table *freq_table; | 90 | struct cpufreq_frequency_table *freq_table; |
93 | 91 | ||
94 | struct list_head policy_list; | 92 | struct list_head policy_list; |
@@ -369,11 +367,10 @@ static inline void cpufreq_resume(void) {} | |||
369 | 367 | ||
370 | /* Policy Notifiers */ | 368 | /* Policy Notifiers */ |
371 | #define CPUFREQ_ADJUST (0) | 369 | #define CPUFREQ_ADJUST (0) |
372 | #define CPUFREQ_INCOMPATIBLE (1) | 370 | #define CPUFREQ_NOTIFY (1) |
373 | #define CPUFREQ_NOTIFY (2) | 371 | #define CPUFREQ_START (2) |
374 | #define CPUFREQ_START (3) | 372 | #define CPUFREQ_CREATE_POLICY (3) |
375 | #define CPUFREQ_CREATE_POLICY (4) | 373 | #define CPUFREQ_REMOVE_POLICY (4) |
376 | #define CPUFREQ_REMOVE_POLICY (5) | ||
377 | 374 | ||
378 | #ifdef CONFIG_CPU_FREQ | 375 | #ifdef CONFIG_CPU_FREQ |
379 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); | 376 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); |