acpi-cpufreq.c 19.8 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
		return 0;
	}
}

129
static void wrport(u16 port, u8 bit_width, u32 value)
L
Linus Torvalds 已提交
130
{
131
	if (bit_width <= 8)
L
Linus Torvalds 已提交
132
		outb(value, port);
133
	else if (bit_width <= 16)
L
Linus Torvalds 已提交
134
		outw(value, port);
135
	else if (bit_width <= 32)
L
Linus Torvalds 已提交
136 137 138
		outl(value, port);
}

139
static void rdport(u16 port, u8 bit_width, u32 * ret)
L
Linus Torvalds 已提交
140 141
{
	*ret = 0;
142
	if (bit_width <= 8)
L
Linus Torvalds 已提交
143
		*ret = inb(port);
144
	else if (bit_width <= 16)
L
Linus Torvalds 已提交
145
		*ret = inw(port);
146
	else if (bit_width <= 32)
L
Linus Torvalds 已提交
147 148 149
		*ret = inl(port);
}

150 151 152 153
struct msr_addr {
	u32 reg;
};

154 155 156 157 158
struct io_addr {
	u16 port;
	u8 bit_width;
};

159 160 161 162 163
typedef union {
	struct msr_addr msr;
	struct io_addr io;
} drv_addr_union;

164
struct drv_cmd {
165
	unsigned int type;
166
	cpumask_t mask;
167
	drv_addr_union addr;
168 169 170 171
	u32 val;
};

static void do_drv_read(struct drv_cmd *cmd)
L
Linus Torvalds 已提交
172
{
173 174 175
	u32 h;

	switch (cmd->type) {
176
	case SYSTEM_INTEL_MSR_CAPABLE:
177 178
		rdmsr(cmd->addr.msr.reg, cmd->val, h);
		break;
179
	case SYSTEM_IO_CAPABLE:
180 181
		rdport(cmd->addr.io.port, cmd->addr.io.bit_width, &cmd->val);
		break;
182
	default:
183 184
		break;
	}
185
}
L
Linus Torvalds 已提交
186

187 188
static void do_drv_write(struct drv_cmd *cmd)
{
189 190 191
	u32 h = 0;

	switch (cmd->type) {
192
	case SYSTEM_INTEL_MSR_CAPABLE:
193 194
		wrmsr(cmd->addr.msr.reg, cmd->val, h);
		break;
195
	case SYSTEM_IO_CAPABLE:
196 197
		wrport(cmd->addr.io.port, cmd->addr.io.bit_width, cmd->val);
		break;
198
	default:
199 200
		break;
	}
201
}
L
Linus Torvalds 已提交
202

203
static void drv_read(struct drv_cmd *cmd)
204
{
205
	cpumask_t saved_mask = current->cpus_allowed;
206 207 208 209 210 211 212 213 214
	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)
{
215 216
	cpumask_t saved_mask = current->cpus_allowed;
	unsigned int i;
217 218 219 220

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

223 224 225
	set_cpus_allowed(current, saved_mask);
	return;
}
L
Linus Torvalds 已提交
226

227 228
static u32 get_cur_val(cpumask_t mask)
{
229 230
	struct acpi_processor_performance *perf;
	struct drv_cmd cmd;
L
Linus Torvalds 已提交
231

232 233
	if (unlikely(cpus_empty(mask)))
		return 0;
L
Linus Torvalds 已提交
234

235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
	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;
	}

250
	cmd.mask = mask;
L
Linus Torvalds 已提交
251

252
	drv_read(&cmd);
L
Linus Torvalds 已提交
253

254 255 256 257
	dprintk("get_cur_val = %u\n", cmd.val);

	return cmd.val;
}
L
Linus Torvalds 已提交
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 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
/*
 * 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;
	}

323
	if (aperf_cur.split.lo && mperf_cur.split.lo)
324
		perf_percent = (aperf_cur.split.lo * 100) / mperf_cur.split.lo;
325
	else
326 327 328 329 330 331 332 333 334
		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;
	}

335
	if (aperf_cur.whole && mperf_cur.whole)
336
		perf_percent = (aperf_cur.whole * 100) / mperf_cur.whole;
337
	else
338 339 340 341 342 343 344 345 346 347 348 349 350
		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;
}

351 352
static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
{
353 354
	struct acpi_cpufreq_data *data = drv_data[cpu];
	unsigned int freq;
355 356 357 358

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

	if (unlikely(data == NULL ||
359
		     data->acpi_data == NULL || data->freq_table == NULL)) {
360
		return 0;
L
Linus Torvalds 已提交
361 362
	}

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

366
	return freq;
L
Linus Torvalds 已提交
367 368
}

369
static unsigned int check_freqs(cpumask_t mask, unsigned int freq,
370
				struct acpi_cpufreq_data *data)
371
{
372 373
	unsigned int cur_freq;
	unsigned int i;
L
Linus Torvalds 已提交
374

375
	for (i=0; i<100; i++) {
376 377 378 379 380 381 382 383 384
		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,
385
			       unsigned int target_freq, unsigned int relation)
L
Linus Torvalds 已提交
386
{
387 388 389 390 391 392 393 394 395 396
	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;
397 398 399 400

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

	if (unlikely(data == NULL ||
401
	     data->acpi_data == NULL || data->freq_table == NULL)) {
402 403
		return -ENODEV;
	}
L
Linus Torvalds 已提交
404

405
	perf = data->acpi_data;
L
Linus Torvalds 已提交
406
	result = cpufreq_frequency_table_target(policy,
407 408 409
						data->freq_table,
						target_freq,
						relation, &next_state);
410
	if (unlikely(result))
411
		return -ENODEV;
412

413
#ifdef CONFIG_HOTPLUG_CPU
414 415
	/* cpufreq holds the hotplug lock, so we are safe from here on */
	cpus_and(online_policy_cpus, cpu_online_map, policy->cpus);
416 417 418
#else
	online_policy_cpus = policy->cpus;
#endif
L
Linus Torvalds 已提交
419

420
	next_perf_state = data->freq_table[next_state].index;
421
	if (perf->state == next_perf_state) {
422
		if (unlikely(data->resume)) {
423 424
			dprintk("Called after resume, resetting to P%d\n",
				next_perf_state);
425 426
			data->resume = 0;
		} else {
427 428
			dprintk("Already at target state (P%d)\n",
				next_perf_state);
429 430
			return 0;
		}
431 432
	}

433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
	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;
	}
451

452
	cpus_clear(cmd.mask);
453

454 455 456 457
	if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
		cmd.mask = online_policy_cpus;
	else
		cpu_set(policy->cpu, cmd.mask);
458

459 460
	freqs.old = data->freq_table[perf->state].frequency;
	freqs.new = data->freq_table[next_perf_state].frequency;
461 462 463
	for_each_cpu_mask(i, cmd.mask) {
		freqs.cpu = i;
		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
464
	}
L
Linus Torvalds 已提交
465

466
	drv_write(&cmd);
467

468 469 470
	if (acpi_pstate_strict) {
		if (!check_freqs(cmd.mask, freqs.new, data)) {
			dprintk("acpi_cpufreq_target failed (%d)\n",
471
				policy->cpu);
472
			return -EAGAIN;
473 474 475
		}
	}

476 477 478 479 480 481 482
	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 已提交
483 484
}

485
static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
486
{
487
	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
L
Linus Torvalds 已提交
488 489 490

	dprintk("acpi_cpufreq_verify\n");

491
	return cpufreq_frequency_table_verify(policy, data->freq_table);
L
Linus Torvalds 已提交
492 493 494
}

static unsigned long
495
acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
L
Linus Torvalds 已提交
496
{
497
	struct acpi_processor_performance *perf = data->acpi_data;
498

L
Linus Torvalds 已提交
499 500 501 502
	if (cpu_khz) {
		/* search the closest match to cpu_khz */
		unsigned int i;
		unsigned long freq;
503
		unsigned long freqn = perf->states[0].core_frequency * 1000;
L
Linus Torvalds 已提交
504

505
		for (i=0; i<(perf->state_count-1); i++) {
L
Linus Torvalds 已提交
506
			freq = freqn;
507
			freqn = perf->states[i+1].core_frequency * 1000;
L
Linus Torvalds 已提交
508
			if ((2 * cpu_khz) > (freqn + freq)) {
509
				perf->state = i;
510
				return freq;
L
Linus Torvalds 已提交
511 512
			}
		}
513
		perf->state = perf->state_count-1;
514
		return freqn;
515
	} else {
L
Linus Torvalds 已提交
516
		/* assume CPU is at P0... */
517 518 519
		perf->state = 0;
		return perf->states[0].core_frequency * 1000;
	}
L
Linus Torvalds 已提交
520 521
}

522 523 524 525 526 527 528 529
/*
 * 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...
 */
530
static int acpi_cpufreq_early_init(void)
531
{
532 533 534
	struct acpi_processor_performance *data;
	cpumask_t covered;
	unsigned int i, j;
535 536 537

	dprintk("acpi_cpufreq_early_init\n");

A
Andrew Morton 已提交
538
	for_each_possible_cpu(i) {
539 540
		data = kzalloc(sizeof(struct acpi_processor_performance),
			       GFP_KERNEL);
541
		if (!data) {
542
			for_each_cpu_mask(j, covered) {
543 544 545
				kfree(acpi_perf_data[j]);
				acpi_perf_data[j] = NULL;
			}
546
			return -ENOMEM;
547 548
		}
		acpi_perf_data[i] = data;
549
		cpu_set(i, covered);
550 551 552
	}

	/* Do initialization in ACPI core */
553 554
	acpi_processor_preregister_performance(acpi_perf_data);
	return 0;
555 556
}

557
#ifdef CONFIG_SMP
558 559 560 561 562 563 564 565
/*
 * 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;

566
static int sw_any_bug_found(struct dmi_system_id *d)
567 568 569 570 571
{
	bios_with_sw_any_bug = 1;
	return 0;
}

572
static struct dmi_system_id sw_any_bug_dmi_table[] = {
573 574 575 576 577 578 579 580 581 582 583
	{
		.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"),
		},
	},
	{ }
};
584
#endif
585

586
static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
587
{
588 589 590 591 592 593 594
	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 已提交
595 596 597

	dprintk("acpi_cpufreq_cpu_init\n");

598
	if (!acpi_perf_data[cpu])
599
		return -ENODEV;
600

601
	data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
L
Linus Torvalds 已提交
602
	if (!data)
603
		return -ENOMEM;
L
Linus Torvalds 已提交
604

605
	data->acpi_data = acpi_perf_data[cpu];
606
	drv_data[cpu] = data;
L
Linus Torvalds 已提交
607

608
	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
609
		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
L
Linus Torvalds 已提交
610

611
	result = acpi_processor_register_performance(data->acpi_data, cpu);
L
Linus Torvalds 已提交
612 613 614
	if (result)
		goto err_free;

615 616
	perf = data->acpi_data;
	policy->shared_type = perf->shared_type;
617

618
	/*
619
	 * Will let policy->cpus know about dependency only when software
620 621 622
	 * coordination is required.
	 */
	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
623
	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
624
		policy->cpus = perf->shared_cpu_map;
625 626 627 628 629 630 631 632 633
	}

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

L
Linus Torvalds 已提交
635
	/* capability check */
636
	if (perf->state_count <= 1) {
L
Linus Torvalds 已提交
637 638 639 640
		dprintk("No P-States\n");
		result = -ENODEV;
		goto err_unreg;
	}
641

642 643 644 645 646 647
	if (perf->control_register.space_id != perf->status_register.space_id) {
		result = -ENODEV;
		goto err_unreg;
	}

	switch (perf->control_register.space_id) {
648
	case ACPI_ADR_SPACE_SYSTEM_IO:
649
		dprintk("SYSTEM IO addr space\n");
650 651
		data->cpu_feature = SYSTEM_IO_CAPABLE;
		break;
652
	case ACPI_ADR_SPACE_FIXED_HARDWARE:
653 654 655 656 657 658
		dprintk("HARDWARE addr space\n");
		if (!check_est_cpu(cpu)) {
			result = -ENODEV;
			goto err_unreg;
		}
		data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
659
		break;
660
	default:
661
		dprintk("Unknown addr space %d\n",
662
			(u32) (perf->control_register.space_id));
L
Linus Torvalds 已提交
663 664 665 666
		result = -ENODEV;
		goto err_unreg;
	}

667 668
	data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
		    (perf->state_count+1), GFP_KERNEL);
L
Linus Torvalds 已提交
669 670 671 672 673 674 675
	if (!data->freq_table) {
		result = -ENOMEM;
		goto err_unreg;
	}

	/* detect transition latency */
	policy->cpuinfo.transition_latency = 0;
676
	for (i=0; i<perf->state_count; i++) {
677 678 679 680
		if ((perf->states[i].transition_latency * 1000) >
		    policy->cpuinfo.transition_latency)
			policy->cpuinfo.transition_latency =
			    perf->states[i].transition_latency * 1000;
L
Linus Torvalds 已提交
681 682 683
	}
	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;

684
	data->max_freq = perf->states[0].core_frequency * 1000;
L
Linus Torvalds 已提交
685
	/* table init */
686 687 688
	for (i=0; i<perf->state_count; i++) {
		if (i>0 && perf->states[i].core_frequency ==
		    perf->states[i-1].core_frequency)
689 690 691 692
			continue;

		data->freq_table[valid_states].index = i;
		data->freq_table[valid_states].frequency =
693
		    perf->states[i].core_frequency * 1000;
694
		valid_states++;
L
Linus Torvalds 已提交
695
	}
696
	data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
L
Linus Torvalds 已提交
697 698

	result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
699
	if (result)
L
Linus Torvalds 已提交
700 701
		goto err_freqfree;

702
	switch (data->cpu_feature) {
703
	case ACPI_ADR_SPACE_SYSTEM_IO:
704 705 706
		/* Current speed is unknown and not detectable by IO port */
		policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
		break;
707
	case ACPI_ADR_SPACE_FIXED_HARDWARE:
708
		acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
709 710
		get_cur_freq_on_cpu(cpu);
		break;
711
	default:
712 713 714
		break;
	}

L
Linus Torvalds 已提交
715 716 717
	/* notify BIOS that we exist */
	acpi_processor_notify_smm(THIS_MODULE);

718 719 720 721
	/* 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);
722
		if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
723 724 725
			acpi_cpufreq_driver.getavg = get_measured_perf;
	}

726
	dprintk("CPU%u - ACPI performance management activated.\n", cpu);
727
	for (i = 0; i < perf->state_count; i++)
L
Linus Torvalds 已提交
728
		dprintk("     %cP%d: %d MHz, %d mW, %d uS\n",
729
			(i == perf->state ? '*' : ' '), i,
730 731 732
			(u32) perf->states[i].core_frequency,
			(u32) perf->states[i].power,
			(u32) perf->states[i].transition_latency);
L
Linus Torvalds 已提交
733 734

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

736 737 738 739 740
	/*
	 * the first call to ->target() should result in us actually
	 * writing something to the appropriate registers.
	 */
	data->resume = 1;
741

742
	return result;
L
Linus Torvalds 已提交
743

744
err_freqfree:
L
Linus Torvalds 已提交
745
	kfree(data->freq_table);
746
err_unreg:
747
	acpi_processor_unregister_performance(perf, cpu);
748
err_free:
L
Linus Torvalds 已提交
749
	kfree(data);
750
	drv_data[cpu] = NULL;
L
Linus Torvalds 已提交
751

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

755
static int acpi_cpufreq_cpu_exit(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_cpu_exit\n");

	if (data) {
		cpufreq_frequency_table_put_attr(policy->cpu);
763
		drv_data[policy->cpu] = NULL;
764 765
		acpi_processor_unregister_performance(data->acpi_data,
						      policy->cpu);
L
Linus Torvalds 已提交
766 767 768
		kfree(data);
	}

769
	return 0;
L
Linus Torvalds 已提交
770 771
}

772
static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
L
Linus Torvalds 已提交
773
{
774
	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
L
Linus Torvalds 已提交
775 776 777 778 779

	dprintk("acpi_cpufreq_resume\n");

	data->resume = 1;

780
	return 0;
L
Linus Torvalds 已提交
781 782
}

783
static struct freq_attr *acpi_cpufreq_attr[] = {
L
Linus Torvalds 已提交
784 785 786 787 788
	&cpufreq_freq_attr_scaling_available_freqs,
	NULL,
};

static struct cpufreq_driver acpi_cpufreq_driver = {
789 790 791 792 793 794 795 796
	.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 已提交
797 798
};

799
static int __init acpi_cpufreq_init(void)
L
Linus Torvalds 已提交
800 801 802
{
	dprintk("acpi_cpufreq_init\n");

803
	acpi_cpufreq_early_init();
804

805
	return cpufreq_register_driver(&acpi_cpufreq_driver);
L
Linus Torvalds 已提交
806 807
}

808
static void __exit acpi_cpufreq_exit(void)
L
Linus Torvalds 已提交
809
{
810
	unsigned int i;
L
Linus Torvalds 已提交
811 812 813 814
	dprintk("acpi_cpufreq_exit\n");

	cpufreq_unregister_driver(&acpi_cpufreq_driver);

A
Andrew Morton 已提交
815
	for_each_possible_cpu(i) {
816 817 818
		kfree(acpi_perf_data[i]);
		acpi_perf_data[i] = NULL;
	}
L
Linus Torvalds 已提交
819 820 821
	return;
}

822
module_param(acpi_pstate_strict, uint, 0644);
823
MODULE_PARM_DESC(acpi_pstate_strict,
824 825
	"value 0 or non-zero. non-zero -> strict ACPI checks are "
	"performed during frequency changes.");
L
Linus Torvalds 已提交
826 827 828 829 830

late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit);

MODULE_ALIAS("acpi");