struct drv_cmd *cmd;
cmd = (struct drv_cmd *) drvcmd;
- if (cmd->turbo != CPUFREQ_TURBO_UNSUPPORTED) {
+
+ wrmsrl(MSR_PSTATE_CTRL, cmd->val);
+}
+
+static void update_cpb(void *data)
+{
+ struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
+
+ if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED) {
uint64_t msr_content;
+
rdmsrl(MSR_K8_HWCR, msr_content);
- if (cmd->turbo == CPUFREQ_TURBO_ENABLED)
+
+ if (policy->turbo == CPUFREQ_TURBO_ENABLED)
msr_content &= ~MSR_HWCR_CPBDIS_MASK;
else
msr_content |= MSR_HWCR_CPBDIS_MASK;
+
wrmsrl(MSR_K8_HWCR, msr_content);
}
- wrmsrl(MSR_PSTATE_CTRL, cmd->val);
+}
+
+static int powernow_cpufreq_update (int cpuid,
+ struct cpufreq_policy *policy)
+{
+ if (!cpumask_test_cpu(cpuid, &cpu_online_map))
+ return -EINVAL;
+
+ on_selected_cpus(cpumask_of(cpuid), update_cpb, policy, 1);
+
+ return 0;
}
static int powernow_cpufreq_target(struct cpufreq_policy *policy,
.verify = powernow_cpufreq_verify,
.target = powernow_cpufreq_target,
.init = powernow_cpufreq_cpu_init,
- .exit = powernow_cpufreq_cpu_exit
+ .exit = powernow_cpufreq_cpu_exit,
+ .update = powernow_cpufreq_update
};
unsigned int __init powernow_register_driver()
case XEN_SYSCTL_pm_op_enable_turbo:
{
- cpufreq_enable_turbo(op->cpuid);
+ ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
break;
}
case XEN_SYSCTL_pm_op_disable_turbo:
{
- cpufreq_disable_turbo(op->cpuid);
+ ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
break;
}
return policy->cur;
}
-void cpufreq_enable_turbo(int cpuid)
+int cpufreq_update_turbo(int cpuid, int new_state)
{
struct cpufreq_policy *policy;
+ int curr_state;
+ int ret = 0;
+
+ if (new_state != CPUFREQ_TURBO_ENABLED &&
+ new_state != CPUFREQ_TURBO_DISABLED)
+ return -EINVAL;
policy = per_cpu(cpufreq_cpu_policy, cpuid);
- if (policy && policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
- policy->turbo = CPUFREQ_TURBO_ENABLED;
-}
+ if (!policy)
+ return -EACCES;
-void cpufreq_disable_turbo(int cpuid)
-{
- struct cpufreq_policy *policy;
+ if (policy->turbo == CPUFREQ_TURBO_UNSUPPORTED)
+ return -EOPNOTSUPP;
- policy = per_cpu(cpufreq_cpu_policy, cpuid);
- if (policy && policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
- policy->turbo = CPUFREQ_TURBO_DISABLED;
+ curr_state = policy->turbo;
+ if (curr_state == new_state)
+ return 0;
+
+ policy->turbo = new_state;
+ if (cpufreq_driver->update)
+ {
+ ret = cpufreq_driver->update(cpuid, policy);
+ if (ret)
+ policy->turbo = curr_state;
+ }
+
+ return ret;
}
+
int cpufreq_get_turbo_status(int cpuid)
{
struct cpufreq_policy *policy;
#define CPUFREQ_TURBO_UNSUPPORTED 0
#define CPUFREQ_TURBO_ENABLED 1
-extern void cpufreq_enable_turbo(int cpuid);
-extern void cpufreq_disable_turbo(int cpuid);
+extern int cpufreq_update_turbo(int cpuid, int new_state);
extern int cpufreq_get_turbo_status(int cpuid);
static __inline__ int
char name[CPUFREQ_NAME_LEN];
int (*init)(struct cpufreq_policy *policy);
int (*verify)(struct cpufreq_policy *policy);
+ int (*update)(int cpuid, struct cpufreq_policy *policy);
int (*target)(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);