From 905497c4b2e6715eebde97cbcb313354e14c2489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Bilski?= Date: Sun, 8 Jul 2007 21:51:26 +0200 Subject: [PATCH 1/6] [CPUFREQ] Longhaul - Option to disable ACPI C3 support On some motherboards ACPI C3 is available, but it isn't causing frequency transition on VIA Nehemiah. Longhaul wasn't working at all earlier, but due to scaling_cur_speed returning true CPU frequency now, it looks like CPU is getting stuck at highest frequency since 2.6.21. I didn't find a reason. Halt is causing frequency transition. Signed-off-by: Rafal Bilski Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 8eca59d4c8f4..ef8f0bc3fc71 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -75,6 +75,7 @@ static unsigned int longhaul_index; /* Module parameters */ static int scale_voltage; +static int disable_acpi_c3; #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) @@ -844,6 +845,9 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) if (cx->address > 0 && cx->latency <= 1000) longhaul_flags |= USE_ACPI_C3; } + /* Disable if it isn't working */ + if (disable_acpi_c3) + longhaul_flags &= ~USE_ACPI_C3; /* Check if northbridge is friendly */ if (enable_arbiter_disable()) longhaul_flags |= USE_NORTHBRIDGE; @@ -952,6 +956,9 @@ static void __exit longhaul_exit(void) kfree(longhaul_table); } +module_param (disable_acpi_c3, int, 0644); +MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); + module_param (scale_voltage, int, 0644); MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); From 68485695e5a84399da7b48b208ac42623fe22963 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 8 Jul 2007 23:39:14 +0200 Subject: [PATCH 2/6] [CPUFREQ] the overdue removal of X86_SPEEDSTEP_CENTRINO_ACPI This patch contains the overdue removal of X86_SPEEDSTEP_CENTRINO_ACPI. Signed-off-by: Adrian Bunk Acked-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- Documentation/feature-removal-schedule.txt | 22 -- arch/i386/kernel/cpu/cpufreq/Kconfig | 18 +- .../kernel/cpu/cpufreq/speedstep-centrino.c | 276 +----------------- arch/x86_64/kernel/cpufreq/Kconfig | 6 +- 4 files changed, 19 insertions(+), 303 deletions(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 0599a0c7c026..092c65dd35c2 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -196,28 +196,6 @@ Who: Adrian Bunk --------------------------- -What: ACPI hooks (X86_SPEEDSTEP_CENTRINO_ACPI) in speedstep-centrino driver -When: December 2006 -Why: Speedstep-centrino driver with ACPI hooks and acpi-cpufreq driver are - functionally very much similar. They talk to ACPI in same way. Only - difference between them is the way they do frequency transitions. - One uses MSRs and the other one uses IO ports. Functionaliy of - speedstep_centrino with ACPI hooks is now merged into acpi-cpufreq. - That means one common driver will support all Intel Enhanced Speedstep - capable CPUs. That means less confusion over name of - speedstep-centrino driver (with that driver supposed to be used on - non-centrino platforms). That means less duplication of code and - less maintenance effort and no possibility of these two drivers - going out of sync. - Current users of speedstep_centrino with ACPI hooks are requested to - switch over to acpi-cpufreq driver. speedstep-centrino will continue - to work using older non-ACPI static table based scheme even after this - date. - -Who: Venkatesh Pallipadi - ---------------------------- - What: /sys/firmware/acpi/namespace When: 2.6.21 Why: The ACPI namespace is effectively the symbol list for diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index e77754ca94b4..094118ba00da 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig @@ -116,7 +116,7 @@ config X86_GX_SUSPMOD config X86_SPEEDSTEP_CENTRINO tristate "Intel Enhanced SpeedStep" select CPU_FREQ_TABLE - select X86_SPEEDSTEP_CENTRINO_TABLE if (!X86_SPEEDSTEP_CENTRINO_ACPI) + select X86_SPEEDSTEP_CENTRINO_TABLE help This adds the CPUFreq driver for Enhanced SpeedStep enabled mobile CPUs. This means Intel Pentium M (Centrino) CPUs. However, @@ -128,20 +128,6 @@ config X86_SPEEDSTEP_CENTRINO If in doubt, say N. -config X86_SPEEDSTEP_CENTRINO_ACPI - bool "Use ACPI tables to decode valid frequency/voltage (deprecated)" - depends on X86_SPEEDSTEP_CENTRINO && ACPI_PROCESSOR - depends on !(X86_SPEEDSTEP_CENTRINO = y && ACPI_PROCESSOR = m) - help - This is deprecated and this functionality is now merged into - acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of - speedstep_centrino. - Use primarily the information provided in the BIOS ACPI tables - to determine valid CPU frequency and voltage pairings. It is - required for the driver to work on non-Banias CPUs. - - If in doubt, say Y. - config X86_SPEEDSTEP_CENTRINO_TABLE bool "Built-in tables for Banias CPUs" depends on X86_SPEEDSTEP_CENTRINO @@ -237,7 +223,7 @@ comment "shared options" config X86_ACPI_CPUFREQ_PROC_INTF bool "/proc/acpi/processor/../performance interface (deprecated)" depends on PROC_FS - depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI + depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI help This enables the deprecated /proc/acpi/processor/../performance interface. While it is helpful for debugging, the generic, diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 35489fd68852..6c5dc2c85aeb 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -21,12 +21,6 @@ #include #include -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI -#include -#include -#include -#endif - #include #include #include @@ -257,9 +251,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy) /* Matched a non-match */ dprintk("no table support for CPU model \"%s\"\n", cpu->x86_model_id); -#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - dprintk("try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n"); -#endif + dprintk("try using the acpi-cpufreq driver\n"); return -ENOENT; } @@ -346,213 +338,6 @@ static unsigned int get_cur_freq(unsigned int cpu) } -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - -static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; - -/* - * centrino_cpu_early_init_acpi - Do the preregistering with ACPI P-States - * library - * - * Before doing the actual init, we need to do _PSD related setup whenever - * supported by the BIOS. These are handled by this early_init routine. - */ -static int centrino_cpu_early_init_acpi(void) -{ - unsigned int i, j; - struct acpi_processor_performance *data; - - for_each_possible_cpu(i) { - data = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!data) { - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } - return (-ENOMEM); - } - acpi_perf_data[i] = data; - } - - acpi_processor_preregister_performance(acpi_perf_data); - return 0; -} - - -#ifdef CONFIG_SMP -/* - * Some BIOSes do SW_ANY coordination internally, either set it up in hw - * or do it in BIOS firmware and won't inform about it to OS. If not - * detected, this has a side effect of making CPU run at a different speed - * than OS intended it to run at. Detect it and handle it cleanly. - */ -static int bios_with_sw_any_bug; -static int sw_any_bug_found(struct dmi_system_id *d) -{ - bios_with_sw_any_bug = 1; - return 0; -} - -static struct dmi_system_id sw_any_bug_dmi_table[] = { - { - .callback = sw_any_bug_found, - .ident = "Supermicro Server X6DLP", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), - DMI_MATCH(DMI_BIOS_VERSION, "080010"), - DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"), - }, - }, - { } -}; -#endif - -/* - * centrino_cpu_init_acpi - register with ACPI P-States library - * - * Register with the ACPI P-States library (part of drivers/acpi/processor.c) - * in order to determine correct frequency and voltage pairings by reading - * the _PSS of the ACPI DSDT or SSDT tables. - */ -static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) -{ - unsigned long cur_freq; - int result = 0, i; - unsigned int cpu = policy->cpu; - struct acpi_processor_performance *p; - - p = acpi_perf_data[cpu]; - - /* register with ACPI core */ - if (acpi_processor_register_performance(p, cpu)) { - dprintk(PFX "obtaining ACPI data failed\n"); - return -EIO; - } - - policy->shared_type = p->shared_type; - /* - * Will let policy->cpus know about dependency only when software - * coordination is required. - */ - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || - policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { - policy->cpus = p->shared_cpu_map; - } - -#ifdef CONFIG_SMP - dmi_check_system(sw_any_bug_dmi_table); - if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) { - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - policy->cpus = cpu_core_map[cpu]; - } -#endif - - /* verify the acpi_data */ - if (p->state_count <= 1) { - dprintk("No P-States\n"); - result = -ENODEV; - goto err_unreg; - } - - if ((p->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || - (p->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { - dprintk("Invalid control/status registers (%x - %x)\n", - p->control_register.space_id, p->status_register.space_id); - result = -EIO; - goto err_unreg; - } - - for (i=0; istate_count; i++) { - if ((p->states[i].control & INTEL_MSR_RANGE) != - (p->states[i].status & INTEL_MSR_RANGE)) { - dprintk("Different MSR bits in control (%llu) and status (%llu)\n", - p->states[i].control, p->states[i].status); - result = -EINVAL; - goto err_unreg; - } - - if (!p->states[i].core_frequency) { - dprintk("Zero core frequency for state %u\n", i); - result = -EINVAL; - goto err_unreg; - } - - if (p->states[i].core_frequency > p->states[0].core_frequency) { - dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i, - p->states[i].core_frequency, p->states[0].core_frequency); - p->states[i].core_frequency = 0; - continue; - } - } - - centrino_model[cpu] = kzalloc(sizeof(struct cpu_model), GFP_KERNEL); - if (!centrino_model[cpu]) { - result = -ENOMEM; - goto err_unreg; - } - - centrino_model[cpu]->model_name=NULL; - centrino_model[cpu]->max_freq = p->states[0].core_frequency * 1000; - centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) * - (p->state_count + 1), GFP_KERNEL); - if (!centrino_model[cpu]->op_points) { - result = -ENOMEM; - goto err_kfree; - } - - for (i=0; istate_count; i++) { - centrino_model[cpu]->op_points[i].index = p->states[i].control & INTEL_MSR_RANGE; - centrino_model[cpu]->op_points[i].frequency = p->states[i].core_frequency * 1000; - dprintk("adding state %i with frequency %u and control value %04x\n", - i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index); - } - centrino_model[cpu]->op_points[p->state_count].frequency = CPUFREQ_TABLE_END; - - cur_freq = get_cur_freq(cpu); - - for (i=0; istate_count; i++) { - if (!p->states[i].core_frequency) { - dprintk("skipping state %u\n", i); - centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID; - continue; - } - - if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) != - (centrino_model[cpu]->op_points[i].frequency)) { - dprintk("Invalid encoded frequency (%u vs. %u)\n", - extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0), - centrino_model[cpu]->op_points[i].frequency); - result = -EINVAL; - goto err_kfree_all; - } - - if (cur_freq == centrino_model[cpu]->op_points[i].frequency) - p->state = i; - } - - /* notify BIOS that we exist */ - acpi_processor_notify_smm(THIS_MODULE); - printk("speedstep-centrino with X86_SPEEDSTEP_CENTRINO_ACPI " - "config is deprecated.\n " - "Use X86_ACPI_CPUFREQ (acpi-cpufreq) instead.\n" ); - - return 0; - - err_kfree_all: - kfree(centrino_model[cpu]->op_points); - err_kfree: - kfree(centrino_model[cpu]); - err_unreg: - acpi_processor_unregister_performance(p, cpu); - dprintk(PFX "invalid ACPI data\n"); - return (result); -} -#else -static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; } -static inline int centrino_cpu_early_init_acpi(void) { return 0; } -#endif - static int centrino_cpu_init(struct cpufreq_policy *policy) { struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu]; @@ -568,27 +353,25 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) centrino_driver.flags |= CPUFREQ_CONST_LOOPS; - if (centrino_cpu_init_acpi(policy)) { - if (policy->cpu != 0) - return -ENODEV; + if (policy->cpu != 0) + return -ENODEV; - for (i = 0; i < N_IDS; i++) - if (centrino_verify_cpu_id(cpu, &cpu_ids[i])) - break; + for (i = 0; i < N_IDS; i++) + if (centrino_verify_cpu_id(cpu, &cpu_ids[i])) + break; - if (i != N_IDS) - centrino_cpu[policy->cpu] = &cpu_ids[i]; + if (i != N_IDS) + centrino_cpu[policy->cpu] = &cpu_ids[i]; - if (!centrino_cpu[policy->cpu]) { - dprintk("found unsupported CPU with " - "Enhanced SpeedStep: send /proc/cpuinfo to " - MAINTAINER "\n"); - return -ENODEV; - } + if (!centrino_cpu[policy->cpu]) { + dprintk("found unsupported CPU with " + "Enhanced SpeedStep: send /proc/cpuinfo to " + MAINTAINER "\n"); + return -ENODEV; + } - if (centrino_cpu_init_table(policy)) { - return -ENODEV; - } + if (centrino_cpu_init_table(policy)) { + return -ENODEV; } /* Check to see if Enhanced SpeedStep is enabled, and try to @@ -634,20 +417,6 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) cpufreq_frequency_table_put_attr(cpu); -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - if (!centrino_model[cpu]->model_name) { - static struct acpi_processor_performance *p; - - if (acpi_perf_data[cpu]) { - p = acpi_perf_data[cpu]; - dprintk("unregistering and freeing ACPI data\n"); - acpi_processor_unregister_performance(p, cpu); - kfree(centrino_model[cpu]->op_points); - kfree(centrino_model[cpu]); - } - } -#endif - centrino_model[cpu] = NULL; return 0; @@ -849,25 +618,12 @@ static int __init centrino_init(void) if (!cpu_has(cpu, X86_FEATURE_EST)) return -ENODEV; - centrino_cpu_early_init_acpi(); - return cpufreq_register_driver(¢rino_driver); } static void __exit centrino_exit(void) { -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - unsigned int j; -#endif - cpufreq_unregister_driver(¢rino_driver); - -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } -#endif } MODULE_AUTHOR ("Jeremy Fitzhardinge "); diff --git a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig index c0749d2479f5..a3fd51926cbd 100644 --- a/arch/x86_64/kernel/cpufreq/Kconfig +++ b/arch/x86_64/kernel/cpufreq/Kconfig @@ -48,10 +48,6 @@ config X86_SPEEDSTEP_CENTRINO If in doubt, say N. -config X86_SPEEDSTEP_CENTRINO_ACPI - bool - depends on X86_SPEEDSTEP_CENTRINO - config X86_ACPI_CPUFREQ tristate "ACPI Processor P-States driver" select CPU_FREQ_TABLE @@ -73,7 +69,7 @@ comment "shared options" config X86_ACPI_CPUFREQ_PROC_INTF bool "/proc/acpi/processor/../performance interface (deprecated)" depends on PROC_FS - depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K8_ACPI + depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K8_ACPI help This enables the deprecated /proc/acpi/processor/../performance interface. While it is helpful for debugging, the generic, From aac22d0a79f51d7bd93145be36322baaa4b423f8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 9 Jul 2007 11:35:27 -0700 Subject: [PATCH 3/6] [CPUFREQ] powernow-k8 compile fix. Make it compile on UP. Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 977336834127..93192d7e2873 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1322,16 +1322,21 @@ static struct cpufreq_driver cpufreq_amd64_driver = { static int __cpuinit powernowk8_init(void) { unsigned int i, supported_cpus = 0; + unsigned int booted_cores = 1; for_each_online_cpu(i) { if (check_supported_cpu(i)) supported_cpus++; } +#ifdef CONFIG_SMP + booted_cores = cpu_data[0].booted_cores; +#endif + if (supported_cpus == num_online_cpus()) { printk(KERN_INFO PFX "Found %d %s " "processors (%d cpu cores) (" VERSION ")\n", - supported_cpus/cpu_data[0].booted_cores, + supported_cpus/booted_cores, boot_cpu_data.x86_model_id, supported_cpus); return cpufreq_register_driver(&cpufreq_amd64_driver); } From 91973de736bc97dc04156242c5a4b00993b6c902 Mon Sep 17 00:00:00 2001 From: Peter Oruba Date: Mon, 9 Jul 2007 11:35:27 -0700 Subject: [PATCH 4/6] [CPUFREQ] bugfix cpufreq in combination with performance governor There is a frequency scaling issue that I encountered with the performance governor in combination with CPU hotplug. In cpufreq.c CPU frequency is reduced to its minimum before the CPU gets unregistered and set offline. Does that have a particular reason? Since the (k8-)governor does not monitor CPU frequency that setting also applies then to the remaining CPU as well and lets the system run on the lowest frequency although performance is chose as the policy. Signed-off-by: Peter Oruba Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0db9e1bda322..99f9c3c23845 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1687,7 +1687,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, { unsigned int cpu = (unsigned long)hcpu; struct sys_device *sys_dev; - struct cpufreq_policy *policy; sys_dev = get_cpu_sysdev(cpu); if (sys_dev) { @@ -1701,11 +1700,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, if (unlikely(lock_policy_rwsem_write(cpu))) BUG(); - policy = cpufreq_cpu_data[cpu]; - if (policy) { - __cpufreq_driver_target(policy, policy->min, - CPUFREQ_RELATION_H); - } __cpufreq_remove_dev(sys_dev); break; case CPU_DOWN_FAILED: From 084f34939424161669467c19280dbcf637730314 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 9 Jul 2007 11:35:28 -0700 Subject: [PATCH 5/6] [CPUFREQ] Restore previously used governor on a hot-replugged CPU Negative side effect: needs NR_CPUs pointer array of memory in CONFIG_HOTPLUG_CPU case. Still needs userspace track keeping and rewriting of governors if governors change while a CPU is not active (always the governor at CPU remove time is restored). Move of policy->user_policy.governor assignment is just a minor cleanup. http://bugzilla.kernel.org/show_bug.cgi?id=8671 Signed-off-by: Thomas Renninger Signed-off-by: Mattia Dongili Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 99f9c3c23845..2f6a73c01b71 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -39,6 +39,10 @@ */ static struct cpufreq_driver *cpufreq_driver; static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; +#ifdef CONFIG_HOTPLUG_CPU +/* This one keeps track of the previously set governor of a removed CPU */ +static struct cpufreq_governor *cpufreq_cpu_governor[NR_CPUS]; +#endif static DEFINE_SPINLOCK(cpufreq_driver_lock); /* @@ -770,9 +774,17 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) } policy->user_policy.min = policy->cpuinfo.min_freq; policy->user_policy.max = policy->cpuinfo.max_freq; - policy->user_policy.governor = policy->governor; #ifdef CONFIG_SMP + +#ifdef CONFIG_HOTPLUG_CPU + if (cpufreq_cpu_governor[cpu]){ + policy->governor = cpufreq_cpu_governor[cpu]; + dprintk("Restoring governor %s for cpu %d\n", + policy->governor->name, cpu); + } +#endif + for_each_cpu_mask(j, policy->cpus) { if (cpu == j) continue; @@ -873,6 +885,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) /* set default policy */ ret = __cpufreq_set_policy(policy, &new_policy); policy->user_policy.policy = policy->policy; + policy->user_policy.governor = policy->governor; unlock_policy_rwsem_write(cpu); @@ -969,6 +982,11 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) } #ifdef CONFIG_SMP + +#ifdef CONFIG_HOTPLUG_CPU + cpufreq_cpu_governor[cpu] = data->governor; +#endif + /* if we have other CPUs still registered, we need to unlink them, * or else wait_for_completion below will lock up. Clean the * cpufreq_cpu_data[] while holding the lock, and remove the sysfs @@ -989,6 +1007,9 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) if (j == cpu) continue; dprintk("removing link for cpu %u\n", j); +#ifdef CONFIG_HOTPLUG_CPU + cpufreq_cpu_governor[j] = data->governor; +#endif cpu_sys_dev = get_cpu_sysdev(j); sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); cpufreq_cpu_put(data); From 9a60ddbcb710ff78cd8c772681723a04e3f5aba3 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 13 Jul 2007 01:34:10 -0400 Subject: [PATCH 6/6] [CPUFREQ] Fix typos in powernow-k8 printk's. Based on a patch from Joachim which didn't apply, so I fixed it up by hand, and also corrected the surrounding indentation a little. Signed-off-by: Joachim.Deguara Acked-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 93192d7e2873..34ed53a06730 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -599,14 +599,17 @@ static void print_basics(struct powernow_k8_data *data) for (j = 0; j < data->numps; j++) { if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { if (cpu_family == CPU_HW_PSTATE) { - printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, - (data->powernow_table[j].index & 0xff0000) >> 16, - data->powernow_table[j].frequency/1000); + printk(KERN_INFO PFX " %d : fid 0x%x did 0x%x (%d MHz)\n", + j, + (data->powernow_table[j].index & 0xff00) >> 8, + (data->powernow_table[j].index & 0xff0000) >> 16, + data->powernow_table[j].frequency/1000); } else { - printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", j, - data->powernow_table[j].index & 0xff, - data->powernow_table[j].frequency/1000, - data->powernow_table[j].index >> 8); + printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", + j, + data->powernow_table[j].index & 0xff, + data->powernow_table[j].frequency/1000, + data->powernow_table[j].index >> 8); } } } @@ -1086,7 +1089,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi if (cpu_family == CPU_HW_PSTATE) dprintk("targ: curr fid 0x%x, did 0x%x\n", - data->currfid, data->currvid); + data->currfid, data->currdid); else { dprintk("targ: curr fid 0x%x, vid 0x%x\n", data->currfid, data->currvid);