data->acpi_data->states[i].transition_latency * 1000;
}
}
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR;
policy->cur = acpi_cpufreq_get(policy->cpu);
printk(KERN_INFO "Current freq of CPU %u is %u\n", cpu, policy->cur);
drv_write(&cmd);
- if (!check_freqs(cmd.mask, freqs.new, data))
+ if (!check_freqs(cmd.mask, freqs.new, data)) {
+ printk(KERN_WARNING "Fail transfer to new freq %d\n", freqs.new);
return -EAGAIN;
+ }
for_each_cpu_mask(j, online_policy_cpus)
cpufreq_statistic_update(j, perf->state, next_perf_state);
policy->cpuinfo.transition_latency =
perf->states[i].transition_latency * 1000;
}
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR;
data->max_freq = perf->states[0].core_frequency * 1000;
/* table init */
/* Linux config option: propageted to domain0 */
/* xen_processor_pmbits: xen control Cx, Px, ... */
-unsigned int xen_processor_pmbits = 0;
+unsigned int xen_processor_pmbits = XEN_PROCESSOR_PM_PX;
/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
static unsigned int opt_dom0_vcpus_pin;
boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
-enum cpufreq_controller cpufreq_controller;
+/* set xen as default cpufreq */
+enum cpufreq_controller cpufreq_controller = FREQCTL_xen;
+struct cpufreq_governor *cpufreq_opt_governor;
+
static void __init setup_cpufreq_option(char *str)
{
char *arg;
return;
}
+ if ( !strcmp(str, "none") )
+ {
+ xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX;
+ cpufreq_controller = FREQCTL_none;
+ return;
+ }
+
if ( (arg = strpbrk(str, ",:")) != NULL )
*arg++ = '\0';
if ( !strcmp(str, "xen") )
- {
- xen_processor_pmbits |= XEN_PROCESSOR_PM_PX;
- cpufreq_controller = FREQCTL_xen;
if ( arg && *arg )
cpufreq_cmdline_parse(arg);
- }
}
custom_param("cpufreq", setup_cpufreq_option);
+static void __init setup_cpufreq_gov_option(char *str)
+{
+ if ( !strcmp(str, "userspace") )
+ cpufreq_opt_governor = &cpufreq_gov_userspace;
+ else if ( !strcmp(str, "performance") )
+ cpufreq_opt_governor = &cpufreq_gov_performance;
+ else if ( !strcmp(str, "powersave") )
+ cpufreq_opt_governor = &cpufreq_gov_powersave;
+ else if ( !strcmp(str, "ondemand") )
+ cpufreq_opt_governor = &cpufreq_gov_dbs;
+}
+custom_param("cpufreq_governor", setup_cpufreq_gov_option);
+
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
DEFINE_RCU_READ_LOCK(domlist_read_lock);
memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
policy->governor = NULL;
ret = __cpufreq_set_policy(policy, &new_policy);
- if (ret)
- goto err2;
+ if (ret) {
+ if (new_policy.governor == CPUFREQ_DEFAULT_GOVERNOR)
+ /* if default governor fail, cpufreq really meet troubles */
+ goto err2;
+ else {
+ /* grub option governor fail */
+ /* give one more chance to default gov */
+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+ new_policy.governor = CPUFREQ_DEFAULT_GOVERNOR;
+ ret = __cpufreq_set_policy(policy, &new_policy);
+ if (ret)
+ goto err2;
+ }
+ }
}
return 0;
/* start new governor */
data->governor = policy->governor;
if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
+ printk(KERN_WARNING "Fail change to %s governor\n",
+ data->governor->name);
+
/* new governor failed, so re-start old one */
if (old_gov) {
data->governor = old_gov;
__cpufreq_governor(data, CPUFREQ_GOV_START);
+ printk(KERN_WARNING "Still stay at %s governor\n",
+ data->governor->name);
}
return -EINVAL;
}
* published by the Free Software Foundation.
*/
+#ifndef __XEN_CPUFREQ_PM_H__
+#define __XEN_CPUFREQ_PM_H__
+
#include <xen/types.h>
#include <xen/list.h>
#include <xen/cpumask.h>
struct list_head governor_list;
};
+extern struct cpufreq_governor *cpufreq_opt_governor;
extern struct cpufreq_governor cpufreq_gov_dbs;
extern struct cpufreq_governor cpufreq_gov_userspace;
extern struct cpufreq_governor cpufreq_gov_performance;
extern int cpufreq_register_governor(struct cpufreq_governor *governor);
extern int cpufreq_unregister_governor(struct cpufreq_governor *governor);
extern struct cpufreq_governor *__find_governor(const char *governor);
-#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
/* pass a target to the cpufreq driver */
extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
uint32_t *up_threshold);
int write_ondemand_sampling_rate(unsigned int sampling_rate);
int write_ondemand_up_threshold(unsigned int up_threshold);
+#endif /* __XEN_CPUFREQ_PM_H__ */