- /* switch to physical CPU where state is to be changed*/
- cpus_allowed = current->cpus_allowed;
-
- /* only run on CPU to be set, or on its sibling */
- affected_cpu_map = cpumask_of_cpu(cpu);
-#ifdef CONFIG_X86_HT
- hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2));
- if (hyperthreading) {
- sibling = cpu_sibling_map[cpu];
- cpu_set(sibling, affected_cpu_map);
- }
-#endif
- set_cpus_allowed(current, affected_cpu_map);
- BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map));
-
- /* get current state */
- rdmsr(MSR_IA32_THERM_CONTROL, l, h);
- if (l & 0x10) {
- l = l >> 1;
- l &= 0x7;
- } else
- l = DC_DISABLE;
-
- if (l == newstate) {
- set_cpus_allowed(current, cpus_allowed);
- return 0;
- } else if (l == DC_RESV) {
- printk(KERN_ERR PFX "BIG FAT WARNING: currently in invalid setting\n");
- }
-
- /* notifiers */
- freqs.old = stock_freq * l / 8;
- freqs.new = stock_freq * newstate / 8;
- freqs.cpu = cpu;
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- if (hyperthreading) {
- freqs.cpu = sibling;
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- }
-