diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-11-28 04:51:02 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-11-28 08:31:06 -0500 |
commit | 4d66ddf28dd6e0582eeca0266651d1f5f5db431e (patch) | |
tree | ad11d758060d18ab815d6fa7b4218c60afd7663e /drivers/cpufreq/acpi-cpufreq.c | |
parent | 7a3ba767f6bf9d98f1c823417908719af4a22a65 (diff) |
cpufreq: acpi-cpufreq: Convert to hotplug state machine
Install the callbacks via the state machine.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/acpi-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 297e9128fe9f..52b25f2356f2 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -536,46 +536,33 @@ static void free_acpi_perf_data(void) | |||
536 | free_percpu(acpi_perf_data); | 536 | free_percpu(acpi_perf_data); |
537 | } | 537 | } |
538 | 538 | ||
539 | static int boost_notify(struct notifier_block *nb, unsigned long action, | 539 | static int cpufreq_boost_online(unsigned int cpu) |
540 | void *hcpu) | ||
541 | { | 540 | { |
542 | unsigned cpu = (long)hcpu; | ||
543 | const struct cpumask *cpumask; | 541 | const struct cpumask *cpumask; |
544 | 542 | ||
545 | cpumask = get_cpu_mask(cpu); | 543 | cpumask = get_cpu_mask(cpu); |
546 | |||
547 | /* | 544 | /* |
548 | * Clear the boost-disable bit on the CPU_DOWN path so that | 545 | * On the CPU_UP path we simply keep the boost-disable flag |
549 | * this cpu cannot block the remaining ones from boosting. On | 546 | * in sync with the current global state. |
550 | * the CPU_UP path we simply keep the boost-disable flag in | ||
551 | * sync with the current global state. | ||
552 | */ | 547 | */ |
548 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask); | ||
549 | return 0; | ||
550 | } | ||
553 | 551 | ||
554 | switch (action) { | 552 | static int cpufreq_boost_down_prep(unsigned int cpu) |
555 | case CPU_DOWN_FAILED: | 553 | { |
556 | case CPU_DOWN_FAILED_FROZEN: | 554 | const struct cpumask *cpumask; |
557 | case CPU_ONLINE: | ||
558 | case CPU_ONLINE_FROZEN: | ||
559 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask); | ||
560 | break; | ||
561 | |||
562 | case CPU_DOWN_PREPARE: | ||
563 | case CPU_DOWN_PREPARE_FROZEN: | ||
564 | boost_set_msrs(1, cpumask); | ||
565 | break; | ||
566 | 555 | ||
567 | default: | 556 | cpumask = get_cpu_mask(cpu); |
568 | break; | ||
569 | } | ||
570 | 557 | ||
571 | return NOTIFY_OK; | 558 | /* |
559 | * Clear the boost-disable bit on the CPU_DOWN path so that | ||
560 | * this cpu cannot block the remaining ones from boosting. | ||
561 | */ | ||
562 | boost_set_msrs(1, cpumask); | ||
563 | return 0; | ||
572 | } | 564 | } |
573 | 565 | ||
574 | |||
575 | static struct notifier_block boost_nb = { | ||
576 | .notifier_call = boost_notify, | ||
577 | }; | ||
578 | |||
579 | /* | 566 | /* |
580 | * acpi_cpufreq_early_init - initialize ACPI P-States library | 567 | * acpi_cpufreq_early_init - initialize ACPI P-States library |
581 | * | 568 | * |
@@ -922,37 +909,48 @@ static struct cpufreq_driver acpi_cpufreq_driver = { | |||
922 | .attr = acpi_cpufreq_attr, | 909 | .attr = acpi_cpufreq_attr, |
923 | }; | 910 | }; |
924 | 911 | ||
912 | static enum cpuhp_state acpi_cpufreq_online; | ||
913 | |||
925 | static void __init acpi_cpufreq_boost_init(void) | 914 | static void __init acpi_cpufreq_boost_init(void) |
926 | { | 915 | { |
927 | if (boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)) { | 916 | int ret; |
928 | msrs = msrs_alloc(); | ||
929 | |||
930 | if (!msrs) | ||
931 | return; | ||
932 | 917 | ||
933 | acpi_cpufreq_driver.set_boost = set_boost; | 918 | if (!(boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA))) |
934 | acpi_cpufreq_driver.boost_enabled = boost_state(0); | 919 | return; |
935 | 920 | ||
936 | cpu_notifier_register_begin(); | 921 | msrs = msrs_alloc(); |
937 | 922 | ||
938 | /* Force all MSRs to the same value */ | 923 | if (!msrs) |
939 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, | 924 | return; |
940 | cpu_online_mask); | ||
941 | 925 | ||
942 | __register_cpu_notifier(&boost_nb); | 926 | acpi_cpufreq_driver.set_boost = set_boost; |
927 | acpi_cpufreq_driver.boost_enabled = boost_state(0); | ||
943 | 928 | ||
944 | cpu_notifier_register_done(); | 929 | /* |
930 | * This calls the online callback on all online cpu and forces all | ||
931 | * MSRs to the same value. | ||
932 | */ | ||
933 | ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "cpufreq/acpi:online", | ||
934 | cpufreq_boost_online, cpufreq_boost_down_prep); | ||
935 | if (ret < 0) { | ||
936 | pr_err("acpi_cpufreq: failed to register hotplug callbacks\n"); | ||
937 | msrs_free(msrs); | ||
938 | msrs = NULL; | ||
939 | return; | ||
945 | } | 940 | } |
941 | acpi_cpufreq_online = ret; | ||
946 | } | 942 | } |
947 | 943 | ||
948 | static void acpi_cpufreq_boost_exit(void) | 944 | static void acpi_cpufreq_boost_exit(void) |
949 | { | 945 | { |
950 | if (msrs) { | 946 | if (!msrs) |
951 | unregister_cpu_notifier(&boost_nb); | 947 | return; |
952 | 948 | ||
953 | msrs_free(msrs); | 949 | if (acpi_cpufreq_online >= 0) |
954 | msrs = NULL; | 950 | cpuhp_remove_state_nocalls(acpi_cpufreq_online); |
955 | } | 951 | |
952 | msrs_free(msrs); | ||
953 | msrs = NULL; | ||
956 | } | 954 | } |
957 | 955 | ||
958 | static int __init acpi_cpufreq_init(void) | 956 | static int __init acpi_cpufreq_init(void) |