acpi-cpufreq.c 19.5 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
L
Linus Torvalds 已提交
3 4 5 6
 *
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
7
 *  Copyright (C) 2006       Denis Sadykov <denis.m.sadykov@intel.com>
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
31 32
#include <linux/smp.h>
#include <linux/sched.h>
L
Linus Torvalds 已提交
33
#include <linux/cpufreq.h>
34
#include <linux/compiler.h>
35
#include <linux/dmi.h>
L
Linus Torvalds 已提交
36 37 38 39

#include <linux/acpi.h>
#include <acpi/processor.h>

40
#include <asm/io.h>
41
#include <asm/msr.h>
42 43 44 45 46
#include <asm/processor.h>
#include <asm/cpufeature.h>
#include <asm/delay.h>
#include <asm/uaccess.h>

L
Linus Torvalds 已提交
47 48 49 50 51 52
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)

MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
MODULE_LICENSE("GPL");

53 54 55 56 57 58 59
enum {
	UNDEFINED_CAPABLE = 0,
	SYSTEM_INTEL_MSR_CAPABLE,
	SYSTEM_IO_CAPABLE,
};

#define INTEL_MSR_RANGE		(0xffff)
60
#define CPUID_6_ECX_APERFMPERF_CAPABILITY	(0x1)
61

62
struct acpi_cpufreq_data {
63 64
	struct acpi_processor_performance *acpi_data;
	struct cpufreq_frequency_table *freq_table;
65
	unsigned int max_freq;
66 67
	unsigned int resume;
	unsigned int cpu_feature;
L
Linus Torvalds 已提交
68 69
};

70 71
static struct acpi_cpufreq_data *drv_data[NR_CPUS];
static struct acpi_processor_performance *acpi_perf_data[NR_CPUS];
L
Linus Torvalds 已提交
72 73 74

static struct cpufreq_driver acpi_cpufreq_driver;

75 76
static unsigned int acpi_pstate_strict;

77 78 79 80 81
static int check_est_cpu(unsigned int cpuid)
{
	struct cpuinfo_x86 *cpu = &cpu_data[cpuid];

	if (cpu->x86_vendor != X86_VENDOR_INTEL ||
82
	    !cpu_has(cpu, X86_FEATURE_EST))
83 84 85 86 87 88
		return 0;

	return 1;
}

static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
89
{
90 91
	struct acpi_processor_performance *perf;
	int i;
92 93 94

	perf = data->acpi_data;

95
	for (i=0; i<perf->state_count; i++) {
96 97 98 99 100 101
		if (value == perf->states[i].status)
			return data->freq_table[i].frequency;
	}
	return 0;
}

102 103 104
static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
{
	int i;
105
	struct acpi_processor_performance *perf;
106 107

	msr &= INTEL_MSR_RANGE;
108 109
	perf = data->acpi_data;

110
	for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
111
		if (msr == perf->states[data->freq_table[i].index].status)
112 113 114 115 116 117 118 119
			return data->freq_table[i].frequency;
	}
	return data->freq_table[0].frequency;
}

static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
{
	switch (data->cpu_feature) {
120
	case SYSTEM_INTEL_MSR_CAPABLE:
121
		return extract_msr(val, data);
122
	case SYSTEM_IO_CAPABLE:
123
		return extract_io(val, data);
124
	default:
125 126 127 128 129 130 131 132
		return 0;
	}
}

struct msr_addr {
	u32 reg;
};

133 134 135 136 137
struct io_addr {
	u16 port;
	u8 bit_width;
};

138 139 140 141 142
typedef union {
	struct msr_addr msr;
	struct io_addr io;
} drv_addr_union;

143
struct drv_cmd {
144
	unsigned int type;
145
	cpumask_t mask;
146
	drv_addr_union addr;
147 148 149 150
	u32 val;
};

static void do_drv_read(struct drv_cmd *cmd)
L
Linus Torvalds 已提交
151
{
152 153 154
	u32 h;

	switch (cmd->type) {
155
	case SYSTEM_INTEL_MSR_CAPABLE:
156 157
		rdmsr(cmd->addr.msr.reg, cmd->val, h);
		break;
158
	case SYSTEM_IO_CAPABLE:
159 160 161
		acpi_os_read_port((acpi_io_address)cmd->addr.io.port,
				&cmd->val,
				(u32)cmd->addr.io.bit_width);
162
		break;
163
	default:
164 165
		break;
	}
166
}
L
Linus Torvalds 已提交
167

168 169
static void do_drv_write(struct drv_cmd *cmd)
{
170 171 172
	u32 h = 0;

	switch (cmd->type) {
173
	case SYSTEM_INTEL_MSR_CAPABLE:
174 175
		wrmsr(cmd->addr.msr.reg, cmd->val, h);
		break;
176
	case SYSTEM_IO_CAPABLE:
177 178 179
		acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
				cmd->val,
				(u32)cmd->addr.io.bit_width);
180
		break;
181
	default:
182 183
		break;
	}
184
}
L
Linus Torvalds 已提交
185

186
static void drv_read(struct drv_cmd *cmd)
187
{
188
	cpumask_t saved_mask = current->cpus_allowed;
189 190 191 192 193 194 195 196 197
	cmd->val = 0;

	set_cpus_allowed(current, cmd->mask);
	do_drv_read(cmd);
	set_cpus_allowed(current, saved_mask);
}

static void drv_write(struct drv_cmd *cmd)
{
198 199
	cpumask_t saved_mask = current->cpus_allowed;
	unsigned int i;
200 201 202 203

	for_each_cpu_mask(i, cmd->mask) {
		set_cpus_allowed(current, cpumask_of_cpu(i));
		do_drv_write(cmd);
L
Linus Torvalds 已提交
204 205
	}

206 207 208
	set_cpus_allowed(current, saved_mask);
	return;
}
L
Linus Torvalds 已提交
209

210 211
static u32 get_cur_val(cpumask_t mask)
{
212 213
	struct acpi_processor_performance *perf;
	struct drv_cmd cmd;
L
Linus Torvalds 已提交
214

215 216
	if (unlikely(cpus_empty(mask)))
		return 0;
L
Linus Torvalds 已提交
217

218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
	switch (drv_data[first_cpu(mask)]->cpu_feature) {
	case SYSTEM_INTEL_MSR_CAPABLE:
		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
		cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
		break;
	case SYSTEM_IO_CAPABLE:
		cmd.type = SYSTEM_IO_CAPABLE;
		perf = drv_data[first_cpu(mask)]->acpi_data;
		cmd.addr.io.port = perf->control_register.address;
		cmd.addr.io.bit_width = perf->control_register.bit_width;
		break;
	default:
		return 0;
	}

233
	cmd.mask = mask;
L
Linus Torvalds 已提交
234

235
	drv_read(&cmd);
L
Linus Torvalds 已提交
236

237 238 239 240
	dprintk("get_cur_val = %u\n", cmd.val);

	return cmd.val;
}
L
Linus Torvalds 已提交
241

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
/*
 * Return the measured active (C0) frequency on this CPU since last call
 * to this function.
 * Input: cpu number
 * Return: Average CPU frequency in terms of max frequency (zero on error)
 *
 * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
 * over a period of time, while CPU is in C0 state.
 * IA32_MPERF counts at the rate of max advertised frequency
 * IA32_APERF counts at the rate of actual CPU frequency
 * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
 * no meaning should be associated with absolute values of these MSRs.
 */
static unsigned int get_measured_perf(unsigned int cpu)
{
	union {
		struct {
			u32 lo;
			u32 hi;
		} split;
		u64 whole;
	} aperf_cur, mperf_cur;

	cpumask_t saved_mask;
	unsigned int perf_percent;
	unsigned int retval;

	saved_mask = current->cpus_allowed;
	set_cpus_allowed(current, cpumask_of_cpu(cpu));
	if (get_cpu() != cpu) {
		/* We were not able to run on requested processor */
		put_cpu();
		return 0;
	}

	rdmsr(MSR_IA32_APERF, aperf_cur.split.lo, aperf_cur.split.hi);
	rdmsr(MSR_IA32_MPERF, mperf_cur.split.lo, mperf_cur.split.hi);

	wrmsr(MSR_IA32_APERF, 0,0);
	wrmsr(MSR_IA32_MPERF, 0,0);

#ifdef __i386__
	/*
	 * We dont want to do 64 bit divide with 32 bit kernel
	 * Get an approximate value. Return failure in case we cannot get
	 * an approximate value.
	 */
	if (unlikely(aperf_cur.split.hi || mperf_cur.split.hi)) {
		int shift_count;
		u32 h;

		h = max_t(u32, aperf_cur.split.hi, mperf_cur.split.hi);
		shift_count = fls(h);

		aperf_cur.whole >>= shift_count;
		mperf_cur.whole >>= shift_count;
	}

	if (((unsigned long)(-1) / 100) < aperf_cur.split.lo) {
		int shift_count = 7;
		aperf_cur.split.lo >>= shift_count;
		mperf_cur.split.lo >>= shift_count;
	}

306
	if (aperf_cur.split.lo && mperf_cur.split.lo)
307
		perf_percent = (aperf_cur.split.lo * 100) / mperf_cur.split.lo;
308
	else
309 310 311 312 313 314 315 316 317
		perf_percent = 0;

#else
	if (unlikely(((unsigned long)(-1) / 100) < aperf_cur.whole)) {
		int shift_count = 7;
		aperf_cur.whole >>= shift_count;
		mperf_cur.whole >>= shift_count;
	}

318
	if (aperf_cur.whole && mperf_cur.whole)
319
		perf_percent = (aperf_cur.whole * 100) / mperf_cur.whole;
320
	else
321 322 323 324 325 326 327 328 329 330 331 332 333
		perf_percent = 0;

#endif

	retval = drv_data[cpu]->max_freq * perf_percent / 100;

	put_cpu();
	set_cpus_allowed(current, saved_mask);

	dprintk("cpu %d: performance percent %d\n", cpu, perf_percent);
	return retval;
}

334 335
static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
{
336 337
	struct acpi_cpufreq_data *data = drv_data[cpu];
	unsigned int freq;
338 339 340 341

	dprintk("get_cur_freq_on_cpu (%d)\n", cpu);

	if (unlikely(data == NULL ||
342
		     data->acpi_data == NULL || data->freq_table == NULL)) {
343
		return 0;
L
Linus Torvalds 已提交
344 345
	}

346 347
	freq = extract_freq(get_cur_val(cpumask_of_cpu(cpu)), data);
	dprintk("cur freq = %u\n", freq);
L
Linus Torvalds 已提交
348

349
	return freq;
L
Linus Torvalds 已提交
350 351
}

352
static unsigned int check_freqs(cpumask_t mask, unsigned int freq,
353
				struct acpi_cpufreq_data *data)
354
{
355 356
	unsigned int cur_freq;
	unsigned int i;
L
Linus Torvalds 已提交
357

358
	for (i=0; i<100; i++) {
359 360 361 362 363 364 365 366 367
		cur_freq = extract_freq(get_cur_val(mask), data);
		if (cur_freq == freq)
			return 1;
		udelay(10);
	}
	return 0;
}

static int acpi_cpufreq_target(struct cpufreq_policy *policy,
368
			       unsigned int target_freq, unsigned int relation)
L
Linus Torvalds 已提交
369
{
370 371 372 373 374 375 376 377 378 379
	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
	struct acpi_processor_performance *perf;
	struct cpufreq_freqs freqs;
	cpumask_t online_policy_cpus;
	struct drv_cmd cmd;
	unsigned int msr;
	unsigned int next_state = 0;
	unsigned int next_perf_state = 0;
	unsigned int i;
	int result = 0;
380 381 382 383

	dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);

	if (unlikely(data == NULL ||
384
	     data->acpi_data == NULL || data->freq_table == NULL)) {
385 386
		return -ENODEV;
	}
L
Linus Torvalds 已提交
387

388
	perf = data->acpi_data;
L
Linus Torvalds 已提交
389
	result = cpufreq_frequency_table_target(policy,
390 391 392
						data->freq_table,
						target_freq,
						relation, &next_state);
393
	if (unlikely(result))
394
		return -ENODEV;
395

396
#ifdef CONFIG_HOTPLUG_CPU
397 398
	/* cpufreq holds the hotplug lock, so we are safe from here on */
	cpus_and(online_policy_cpus, cpu_online_map, policy->cpus);
399 400 401
#else
	online_policy_cpus = policy->cpus;
#endif
L
Linus Torvalds 已提交
402

403
	next_perf_state = data->freq_table[next_state].index;
404
	if (perf->state == next_perf_state) {
405
		if (unlikely(data->resume)) {
406 407
			dprintk("Called after resume, resetting to P%d\n",
				next_perf_state);
408 409
			data->resume = 0;
		} else {
410 411
			dprintk("Already at target state (P%d)\n",
				next_perf_state);
412 413
			return 0;
		}
414 415
	}

416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
	switch (data->cpu_feature) {
	case SYSTEM_INTEL_MSR_CAPABLE:
		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
		cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
		msr =
		    (u32) perf->states[next_perf_state].
		    control & INTEL_MSR_RANGE;
		cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr;
		break;
	case SYSTEM_IO_CAPABLE:
		cmd.type = SYSTEM_IO_CAPABLE;
		cmd.addr.io.port = perf->control_register.address;
		cmd.addr.io.bit_width = perf->control_register.bit_width;
		cmd.val = (u32) perf->states[next_perf_state].control;
		break;
	default:
		return -ENODEV;
	}
434

435
	cpus_clear(cmd.mask);
436

437 438 439 440
	if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
		cmd.mask = online_policy_cpus;
	else
		cpu_set(policy->cpu, cmd.mask);
441

442 443
	freqs.old = data->freq_table[perf->state].frequency;
	freqs.new = data->freq_table[next_perf_state].frequency;
444 445 446
	for_each_cpu_mask(i, cmd.mask) {
		freqs.cpu = i;
		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
447
	}
L
Linus Torvalds 已提交
448

449
	drv_write(&cmd);
450

451 452 453
	if (acpi_pstate_strict) {
		if (!check_freqs(cmd.mask, freqs.new, data)) {
			dprintk("acpi_cpufreq_target failed (%d)\n",
454
				policy->cpu);
455
			return -EAGAIN;
456 457 458
		}
	}

459 460 461 462 463 464 465
	for_each_cpu_mask(i, cmd.mask) {
		freqs.cpu = i;
		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
	}
	perf->state = next_perf_state;

	return result;
L
Linus Torvalds 已提交
466 467
}

468
static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
469
{
470
	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
L
Linus Torvalds 已提交
471 472 473

	dprintk("acpi_cpufreq_verify\n");

474
	return cpufreq_frequency_table_verify(policy, data->freq_table);
L
Linus Torvalds 已提交
475 476 477
}

static unsigned long
478
acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
L
Linus Torvalds 已提交
479
{
480
	struct acpi_processor_performance *perf = data->acpi_data;
481

L
Linus Torvalds 已提交
482 483 484 485
	if (cpu_khz) {
		/* search the closest match to cpu_khz */
		unsigned int i;
		unsigned long freq;
486
		unsigned long freqn = perf->states[0].core_frequency * 1000;
L
Linus Torvalds 已提交
487

488
		for (i=0; i<(perf->state_count-1); i++) {
L
Linus Torvalds 已提交
489
			freq = freqn;
490
			freqn = perf->states[i+1].core_frequency * 1000;
L
Linus Torvalds 已提交
491
			if ((2 * cpu_khz) > (freqn + freq)) {
492
				perf->state = i;
493
				return freq;
L
Linus Torvalds 已提交
494 495
			}
		}
496
		perf->state = perf->state_count-1;
497
		return freqn;
498
	} else {
L
Linus Torvalds 已提交
499
		/* assume CPU is at P0... */
500 501 502
		perf->state = 0;
		return perf->states[0].core_frequency * 1000;
	}
L
Linus Torvalds 已提交
503 504
}

505 506 507 508 509 510 511 512
/*
 * acpi_cpufreq_early_init - initialize ACPI P-States library
 *
 * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c)
 * in order to determine correct frequency and voltage pairings. We can
 * do _PDC and _PSD and find out the processor dependency for the
 * actual init that will happen later...
 */
513
static int acpi_cpufreq_early_init(void)
514
{
515 516 517
	struct acpi_processor_performance *data;
	cpumask_t covered;
	unsigned int i, j;
518 519 520

	dprintk("acpi_cpufreq_early_init\n");

A
Andrew Morton 已提交
521
	for_each_possible_cpu(i) {
522 523
		data = kzalloc(sizeof(struct acpi_processor_performance),
			       GFP_KERNEL);
524
		if (!data) {
525
			for_each_cpu_mask(j, covered) {
526 527 528
				kfree(acpi_perf_data[j]);
				acpi_perf_data[j] = NULL;
			}
529
			return -ENOMEM;
530 531
		}
		acpi_perf_data[i] = data;
532
		cpu_set(i, covered);
533 534 535
	}

	/* Do initialization in ACPI core */
536 537
	acpi_processor_preregister_performance(acpi_perf_data);
	return 0;
538 539
}

540
#ifdef CONFIG_SMP
541 542 543 544 545 546 547 548
/*
 * 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;

549
static int sw_any_bug_found(struct dmi_system_id *d)
550 551 552 553 554
{
	bios_with_sw_any_bug = 1;
	return 0;
}

555
static struct dmi_system_id sw_any_bug_dmi_table[] = {
556 557 558 559 560 561 562 563 564 565 566
	{
		.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"),
		},
	},
	{ }
};
567
#endif
568

569
static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
570
{
571 572 573 574 575 576 577
	unsigned int i;
	unsigned int valid_states = 0;
	unsigned int cpu = policy->cpu;
	struct acpi_cpufreq_data *data;
	unsigned int result = 0;
	struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
	struct acpi_processor_performance *perf;
L
Linus Torvalds 已提交
578 579 580

	dprintk("acpi_cpufreq_cpu_init\n");

581
	if (!acpi_perf_data[cpu])
582
		return -ENODEV;
583

584
	data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
L
Linus Torvalds 已提交
585
	if (!data)
586
		return -ENOMEM;
L
Linus Torvalds 已提交
587

588
	data->acpi_data = acpi_perf_data[cpu];
589
	drv_data[cpu] = data;
L
Linus Torvalds 已提交
590

591
	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
592
		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
L
Linus Torvalds 已提交
593

594
	result = acpi_processor_register_performance(data->acpi_data, cpu);
L
Linus Torvalds 已提交
595 596 597
	if (result)
		goto err_free;

598 599
	perf = data->acpi_data;
	policy->shared_type = perf->shared_type;
600

601
	/*
602
	 * Will let policy->cpus know about dependency only when software
603 604 605
	 * coordination is required.
	 */
	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
606
	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
607
		policy->cpus = perf->shared_cpu_map;
608 609 610 611 612 613 614 615 616
	}

#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
617

L
Linus Torvalds 已提交
618
	/* capability check */
619
	if (perf->state_count <= 1) {
L
Linus Torvalds 已提交
620 621 622 623
		dprintk("No P-States\n");
		result = -ENODEV;
		goto err_unreg;
	}
624

625 626 627 628 629 630
	if (perf->control_register.space_id != perf->status_register.space_id) {
		result = -ENODEV;
		goto err_unreg;
	}

	switch (perf->control_register.space_id) {
631
	case ACPI_ADR_SPACE_SYSTEM_IO:
632
		dprintk("SYSTEM IO addr space\n");
633 634
		data->cpu_feature = SYSTEM_IO_CAPABLE;
		break;
635
	case ACPI_ADR_SPACE_FIXED_HARDWARE:
636 637 638 639 640 641
		dprintk("HARDWARE addr space\n");
		if (!check_est_cpu(cpu)) {
			result = -ENODEV;
			goto err_unreg;
		}
		data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
642
		break;
643
	default:
644
		dprintk("Unknown addr space %d\n",
645
			(u32) (perf->control_register.space_id));
L
Linus Torvalds 已提交
646 647 648 649
		result = -ENODEV;
		goto err_unreg;
	}

650 651
	data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
		    (perf->state_count+1), GFP_KERNEL);
L
Linus Torvalds 已提交
652 653 654 655 656 657 658
	if (!data->freq_table) {
		result = -ENOMEM;
		goto err_unreg;
	}

	/* detect transition latency */
	policy->cpuinfo.transition_latency = 0;
659
	for (i=0; i<perf->state_count; i++) {
660 661 662 663
		if ((perf->states[i].transition_latency * 1000) >
		    policy->cpuinfo.transition_latency)
			policy->cpuinfo.transition_latency =
			    perf->states[i].transition_latency * 1000;
L
Linus Torvalds 已提交
664 665 666
	}
	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;

667
	data->max_freq = perf->states[0].core_frequency * 1000;
L
Linus Torvalds 已提交
668
	/* table init */
669 670 671
	for (i=0; i<perf->state_count; i++) {
		if (i>0 && perf->states[i].core_frequency ==
		    perf->states[i-1].core_frequency)
672 673 674 675
			continue;

		data->freq_table[valid_states].index = i;
		data->freq_table[valid_states].frequency =
676
		    perf->states[i].core_frequency * 1000;
677
		valid_states++;
L
Linus Torvalds 已提交
678
	}
679
	data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
L
Linus Torvalds 已提交
680 681

	result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
682
	if (result)
L
Linus Torvalds 已提交
683 684
		goto err_freqfree;

685
	switch (data->cpu_feature) {
686
	case ACPI_ADR_SPACE_SYSTEM_IO:
687 688 689
		/* Current speed is unknown and not detectable by IO port */
		policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
		break;
690
	case ACPI_ADR_SPACE_FIXED_HARDWARE:
691
		acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
692 693
		get_cur_freq_on_cpu(cpu);
		break;
694
	default:
695 696 697
		break;
	}

L
Linus Torvalds 已提交
698 699 700
	/* notify BIOS that we exist */
	acpi_processor_notify_smm(THIS_MODULE);

701 702 703 704
	/* Check for APERF/MPERF support in hardware */
	if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) {
		unsigned int ecx;
		ecx = cpuid_ecx(6);
705
		if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
706 707 708
			acpi_cpufreq_driver.getavg = get_measured_perf;
	}

709
	dprintk("CPU%u - ACPI performance management activated.\n", cpu);
710
	for (i = 0; i < perf->state_count; i++)
L
Linus Torvalds 已提交
711
		dprintk("     %cP%d: %d MHz, %d mW, %d uS\n",
712
			(i == perf->state ? '*' : ' '), i,
713 714 715
			(u32) perf->states[i].core_frequency,
			(u32) perf->states[i].power,
			(u32) perf->states[i].transition_latency);
L
Linus Torvalds 已提交
716 717

	cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
718

719 720 721 722 723
	/*
	 * the first call to ->target() should result in us actually
	 * writing something to the appropriate registers.
	 */
	data->resume = 1;
724

725
	return result;
L
Linus Torvalds 已提交
726

727
err_freqfree:
L
Linus Torvalds 已提交
728
	kfree(data->freq_table);
729
err_unreg:
730
	acpi_processor_unregister_performance(perf, cpu);
731
err_free:
L
Linus Torvalds 已提交
732
	kfree(data);
733
	drv_data[cpu] = NULL;
L
Linus Torvalds 已提交
734

735
	return result;
L
Linus Torvalds 已提交
736 737
}

738
static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
739
{
740
	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
L
Linus Torvalds 已提交
741 742 743 744 745

	dprintk("acpi_cpufreq_cpu_exit\n");

	if (data) {
		cpufreq_frequency_table_put_attr(policy->cpu);
746
		drv_data[policy->cpu] = NULL;
747 748
		acpi_processor_unregister_performance(data->acpi_data,
						      policy->cpu);
L
Linus Torvalds 已提交
749 750 751
		kfree(data);
	}

752
	return 0;
L
Linus Torvalds 已提交
753 754
}

755
static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
756
{
757
	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
L
Linus Torvalds 已提交
758 759 760 761 762

	dprintk("acpi_cpufreq_resume\n");

	data->resume = 1;

763
	return 0;
L
Linus Torvalds 已提交
764 765
}

766
static struct freq_attr *acpi_cpufreq_attr[] = {
L
Linus Torvalds 已提交
767 768 769 770 771
	&cpufreq_freq_attr_scaling_available_freqs,
	NULL,
};

static struct cpufreq_driver acpi_cpufreq_driver = {
772 773 774 775 776 777 778 779
	.verify = acpi_cpufreq_verify,
	.target = acpi_cpufreq_target,
	.init = acpi_cpufreq_cpu_init,
	.exit = acpi_cpufreq_cpu_exit,
	.resume = acpi_cpufreq_resume,
	.name = "acpi-cpufreq",
	.owner = THIS_MODULE,
	.attr = acpi_cpufreq_attr,
L
Linus Torvalds 已提交
780 781
};

782
static int __init acpi_cpufreq_init(void)
L
Linus Torvalds 已提交
783 784 785
{
	dprintk("acpi_cpufreq_init\n");

786
	acpi_cpufreq_early_init();
787

788
	return cpufreq_register_driver(&acpi_cpufreq_driver);
L
Linus Torvalds 已提交
789 790
}

791
static void __exit acpi_cpufreq_exit(void)
L
Linus Torvalds 已提交
792
{
793
	unsigned int i;
L
Linus Torvalds 已提交
794 795 796 797
	dprintk("acpi_cpufreq_exit\n");

	cpufreq_unregister_driver(&acpi_cpufreq_driver);

A
Andrew Morton 已提交
798
	for_each_possible_cpu(i) {
799 800 801
		kfree(acpi_perf_data[i]);
		acpi_perf_data[i] = NULL;
	}
L
Linus Torvalds 已提交
802 803 804
	return;
}

805
module_param(acpi_pstate_strict, uint, 0644);
806
MODULE_PARM_DESC(acpi_pstate_strict,
807 808
	"value 0 or non-zero. non-zero -> strict ACPI checks are "
	"performed during frequency changes.");
L
Linus Torvalds 已提交
809 810 811 812 813

late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit);

MODULE_ALIAS("acpi");