21 #include <linux/kernel.h>
22 #include <linux/module.h>
25 #include <linux/pci.h>
26 #include <linux/sched.h>
38 static struct pci_dev *speedstep_chipset_dev;
63 static int speedstep_find_register(
void)
65 if (!speedstep_chipset_dev)
69 pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
70 if (!(pmbase & 0x01)) {
71 printk(
KERN_ERR "speedstep-ich: could not find speedstep register\n");
77 printk(
KERN_ERR "speedstep-ich: could not find speedstep register\n");
81 pr_debug(
"pmbase is 0x%x\n", pmbase);
92 static void speedstep_set_state(
unsigned int state)
105 value =
inb(pmbase + 0x50);
107 pr_debug(
"read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
113 pr_debug(
"writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase);
116 pm2_blk =
inb(pmbase + 0x20);
118 outb(pm2_blk, (pmbase + 0x20));
121 outb(value, (pmbase + 0x50));
125 outb(pm2_blk, (pmbase + 0x20));
128 value =
inb(pmbase + 0x50);
133 pr_debug(
"read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
135 if (state == (value & 0x1))
136 pr_debug(
"change to %u MHz succeeded\n",
145 static void _speedstep_set_state(
void *_state)
147 speedstep_set_state(*(
unsigned int *)_state);
156 static int speedstep_activate(
void)
160 if (!speedstep_chipset_dev)
163 pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value);
164 if (!(value & 0x08)) {
166 pr_debug(
"activating SpeedStep (TM) registers\n");
167 pci_write_config_word(speedstep_chipset_dev, 0x00A0, value);
182 static unsigned int speedstep_detect_chipset(
void)
188 if (speedstep_chipset_dev)
195 if (speedstep_chipset_dev)
203 if (speedstep_chipset_dev) {
208 static struct pci_dev *hostbridge;
219 pr_debug(
"hostbridge does not support speedstep\n");
220 speedstep_chipset_dev =
NULL;
232 static void get_freq_data(
void *_speed)
234 unsigned int *
speed = _speed;
239 static unsigned int speedstep_get(
unsigned int cpu)
247 pr_debug(
"detected %u kHz as current frequency\n", speed);
261 unsigned int target_freq,
262 unsigned int relation)
264 unsigned int newstate = 0, policy_cpu;
269 target_freq, relation, &newstate))
273 freqs.old = speedstep_get(policy_cpu);
274 freqs.new = speedstep_freqs[newstate].
frequency;
275 freqs.cpu = policy->
cpu;
277 pr_debug(
"transiting from %u to %u kHz\n", freqs.old, freqs.new);
280 if (freqs.old == freqs.new)
317 static void get_freqs_on_cpu(
void *_get_freqs)
325 &get_freqs->
policy->cpuinfo.transition_latency,
326 &speedstep_set_state);
332 unsigned int policy_cpu, speed;
337 cpumask_copy(policy->
cpus, cpu_sibling_mask(policy->
cpu));
348 speed = speedstep_get(policy_cpu);
352 pr_debug(
"currently at %s speed setting - %i MHz\n",
376 static struct freq_attr *speedstep_attr[] = {
383 .name =
"speedstep-ich",
384 .verify = speedstep_verify,
385 .target = speedstep_target,
386 .init = speedstep_cpu_init,
387 .exit = speedstep_cpu_exit,
388 .get = speedstep_get,
390 .attr = speedstep_attr,
393 static const struct x86_cpu_id ss_smi_ids[] = {
411 static int __init speedstep_init(
void)
419 pr_debug(
"Intel(R) SpeedStep(TM) capable processor "
425 if (!speedstep_detect_chipset()) {
426 pr_debug(
"Intel(R) SpeedStep(TM) for this chipset not "
427 "(yet) available.\n");
432 if (speedstep_activate()) {
437 if (speedstep_find_register())
449 static void __exit speedstep_exit(
void)
459 "with ICH-M southbridges.");