Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af09f1e4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq



* master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] Fix typos in powernow-k8 printk's.
  [CPUFREQ] Restore previously used governor on a hot-replugged CPU
  [CPUFREQ] bugfix cpufreq in combination with performance governor
  [CPUFREQ] powernow-k8 compile fix.
  [CPUFREQ] the overdue removal of X86_SPEEDSTEP_CENTRINO_ACPI
  [CPUFREQ] Longhaul - Option to disable ACPI C3 support

Fixed up arch/i386/kernel/cpu/cpufreq/powernow-k8.c due to revert that
got fixed differently in the cpufreq branch.

Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parents e030dbf9 9a60ddbc
Loading
Loading
Loading
Loading
+0 −22
Original line number Diff line number Diff line
@@ -196,28 +196,6 @@ Who: Adrian Bunk <bunk@stusta.de>

---------------------------

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 <venkatesh.pallipadi@intel.com>

---------------------------

What:	/sys/firmware/acpi/namespace
When:	2.6.21
Why:	The ACPI namespace is effectively the symbol list for
+2 −16
Original line number Diff line number Diff line
@@ -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,
+7 −0
Original line number Diff line number Diff line
@@ -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");

+19 −10
Original line number Diff line number Diff line
@@ -599,11 +599,14 @@ 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,
				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,
				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);
@@ -1322,16 +1325,22 @@ 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 (" VERSION ")\n", supported_cpus,
			boot_cpu_data.x86_model_id);
			"processors (%d cpu cores) (" VERSION ")\n",
			supported_cpus/booted_cores,
			boot_cpu_data.x86_model_id, supported_cpus);
		return cpufreq_register_driver(&cpufreq_amd64_driver);
	}

+16 −260
Original line number Diff line number Diff line
@@ -21,12 +21,6 @@
#include <linux/delay.h>
#include <linux/compiler.h>

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <acpi/processor.h>
#endif

#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>
@@ -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; i<p->state_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; i<p->state_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; i<p->state_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,7 +353,6 @@ 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;

@@ -589,7 +373,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
	if (centrino_cpu_init_table(policy)) {
		return -ENODEV;
	}
	}

	/* Check to see if Enhanced SpeedStep is enabled, and try to
	   enable it if not. */
@@ -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(&centrino_driver);
}

static void __exit centrino_exit(void)
{
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
	unsigned int j;
#endif
	
	cpufreq_unregister_driver(&centrino_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 <jeremy@goop.org>");
Loading