浏览代码

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq

* git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] state info wrong after resume
  [CPUFREQ] allow use of the powersave governor as the default one
  [CPUFREQ] document the currently undocumented parts of the sysfs interface
  [CPUFREQ] expose cpufreq coordination requirements regardless of coordination mechanism
Linus Torvalds 17 年之前
父节点
当前提交
44473d9913

+ 14 - 0
Documentation/cpu-freq/user-guide.txt

@@ -154,6 +154,11 @@ scaling_governor,		and by "echoing" the name of another
 				that some governors won't load - they only
 				that some governors won't load - they only
 				work on some specific architectures or
 				work on some specific architectures or
 				processors.
 				processors.
+
+cpuinfo_cur_freq :		Current speed of the CPU, in KHz.
+
+scaling_available_frequencies : List of available frequencies, in KHz.
+
 scaling_min_freq and
 scaling_min_freq and
 scaling_max_freq		show the current "policy limits" (in
 scaling_max_freq		show the current "policy limits" (in
 				kHz). By echoing new values into these
 				kHz). By echoing new values into these
@@ -162,6 +167,15 @@ scaling_max_freq		show the current "policy limits" (in
 				first set scaling_max_freq, then
 				first set scaling_max_freq, then
 				scaling_min_freq.
 				scaling_min_freq.
 
 
+affected_cpus :			List of CPUs that require software coordination
+				of frequency.
+
+related_cpus :			List of CPUs that need some sort of frequency
+				coordination, whether software or hardware.
+
+scaling_driver :		Hardware driver for cpufreq.
+
+scaling_cur_freq :		Current frequency of the CPU, in KHz.
 
 
 If you have selected the "userspace" governor which allows you to
 If you have selected the "userspace" governor which allows you to
 set the CPU operating frequency to a specific value, you can read out
 set the CPU operating frequency to a specific value, you can read out

+ 1 - 0
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c

@@ -601,6 +601,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
 	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
 		policy->cpus = perf->shared_cpu_map;
 		policy->cpus = perf->shared_cpu_map;
 	}
 	}
+	policy->related_cpus = perf->shared_cpu_map;
 
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 	dmi_check_system(sw_any_bug_dmi_table);
 	dmi_check_system(sw_any_bug_dmi_table);

+ 9 - 0
drivers/cpufreq/Kconfig

@@ -69,6 +69,15 @@ config CPU_FREQ_DEFAULT_GOV_PERFORMANCE
 	  the frequency statically to the highest frequency supported by
 	  the frequency statically to the highest frequency supported by
 	  the CPU.
 	  the CPU.
 
 
+config CPU_FREQ_DEFAULT_GOV_POWERSAVE
+	bool "powersave"
+	depends on EMBEDDED
+	select CPU_FREQ_GOV_POWERSAVE
+	help
+	  Use the CPUFreq governor 'powersave' as default. This sets
+	  the frequency statically to the lowest frequency supported by
+	  the CPU.
+
 config CPU_FREQ_DEFAULT_GOV_USERSPACE
 config CPU_FREQ_DEFAULT_GOV_USERSPACE
 	bool "userspace"
 	bool "userspace"
 	select CPU_FREQ_GOV_USERSPACE
 	select CPU_FREQ_GOV_USERSPACE

+ 24 - 5
drivers/cpufreq/cpufreq.c

@@ -583,15 +583,13 @@ out:
 	i += sprintf(&buf[i], "\n");
 	i += sprintf(&buf[i], "\n");
 	return i;
 	return i;
 }
 }
-/**
- * show_affected_cpus - show the CPUs affected by each transition
- */
-static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
+
+static ssize_t show_cpus(cpumask_t mask, char *buf)
 {
 {
 	ssize_t i = 0;
 	ssize_t i = 0;
 	unsigned int cpu;
 	unsigned int cpu;
 
 
-	for_each_cpu_mask(cpu, policy->cpus) {
+	for_each_cpu_mask(cpu, mask) {
 		if (i)
 		if (i)
 			i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
 			i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
 		i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
 		i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
@@ -602,6 +600,25 @@ static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
 	return i;
 	return i;
 }
 }
 
 
+/**
+ * show_related_cpus - show the CPUs affected by each transition even if
+ * hw coordination is in use
+ */
+static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
+{
+	if (cpus_empty(policy->related_cpus))
+		return show_cpus(policy->cpus, buf);
+	return show_cpus(policy->related_cpus, buf);
+}
+
+/**
+ * show_affected_cpus - show the CPUs affected by each transition
+ */
+static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
+{
+	return show_cpus(policy->cpus, buf);
+}
+
 static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
 static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
@@ -646,6 +663,7 @@ define_one_ro(cpuinfo_max_freq);
 define_one_ro(scaling_available_governors);
 define_one_ro(scaling_available_governors);
 define_one_ro(scaling_driver);
 define_one_ro(scaling_driver);
 define_one_ro(scaling_cur_freq);
 define_one_ro(scaling_cur_freq);
+define_one_ro(related_cpus);
 define_one_ro(affected_cpus);
 define_one_ro(affected_cpus);
 define_one_rw(scaling_min_freq);
 define_one_rw(scaling_min_freq);
 define_one_rw(scaling_max_freq);
 define_one_rw(scaling_max_freq);
@@ -658,6 +676,7 @@ static struct attribute *default_attrs[] = {
 	&scaling_min_freq.attr,
 	&scaling_min_freq.attr,
 	&scaling_max_freq.attr,
 	&scaling_max_freq.attr,
 	&affected_cpus.attr,
 	&affected_cpus.attr,
+	&related_cpus.attr,
 	&scaling_governor.attr,
 	&scaling_governor.attr,
 	&scaling_driver.attr,
 	&scaling_driver.attr,
 	&scaling_available_governors.attr,
 	&scaling_available_governors.attr,

+ 6 - 2
drivers/cpufreq/cpufreq_powersave.c

@@ -35,12 +35,12 @@ static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
 	return 0;
 	return 0;
 }
 }
 
 
-static struct cpufreq_governor cpufreq_gov_powersave = {
+struct cpufreq_governor cpufreq_gov_powersave = {
 	.name		= "powersave",
 	.name		= "powersave",
 	.governor	= cpufreq_governor_powersave,
 	.governor	= cpufreq_governor_powersave,
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 };
 };
-
+EXPORT_SYMBOL(cpufreq_gov_powersave);
 
 
 static int __init cpufreq_gov_powersave_init(void)
 static int __init cpufreq_gov_powersave_init(void)
 {
 {
@@ -58,5 +58,9 @@ MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'");
 MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE
+fs_initcall(cpufreq_gov_powersave_init);
+#else
 module_init(cpufreq_gov_powersave_init);
 module_init(cpufreq_gov_powersave_init);
+#endif
 module_exit(cpufreq_gov_powersave_exit);
 module_exit(cpufreq_gov_powersave_exit);

+ 1 - 1
drivers/cpufreq/cpufreq_stats.c

@@ -288,7 +288,7 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
 	if (!stat)
 	if (!stat)
 		return 0;
 		return 0;
 
 
-	old_index = freq_table_get_index(stat, freq->old);
+	old_index = stat->last_index;
 	new_index = freq_table_get_index(stat, freq->new);
 	new_index = freq_table_get_index(stat, freq->new);
 
 
 	cpufreq_stats_update(freq->cpu);
 	cpufreq_stats_update(freq->cpu);

+ 5 - 1
include/linux/cpufreq.h

@@ -83,7 +83,8 @@ struct cpufreq_real_policy {
 };
 };
 
 
 struct cpufreq_policy {
 struct cpufreq_policy {
-	cpumask_t		cpus;	/* affected CPUs */
+	cpumask_t		cpus;	/* CPUs requiring sw coordination */
+	cpumask_t		related_cpus; /* CPUs with any coordination */
 	unsigned int		shared_type; /* ANY or ALL affected CPUs
 	unsigned int		shared_type; /* ANY or ALL affected CPUs
 						should set cpufreq */
 						should set cpufreq */
 	unsigned int		cpu;    /* cpu nr of registered CPU */
 	unsigned int		cpu;    /* cpu nr of registered CPU */
@@ -307,6 +308,9 @@ extern struct cpufreq_governor cpufreq_gov_performance;
 #endif
 #endif
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
 #define CPUFREQ_DEFAULT_GOVERNOR	(&cpufreq_gov_performance)
 #define CPUFREQ_DEFAULT_GOVERNOR	(&cpufreq_gov_performance)
+#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE)
+extern struct cpufreq_governor cpufreq_gov_powersave;
+#define CPUFREQ_DEFAULT_GOVERNOR	(&cpufreq_gov_powersave)
 #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
 #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
 extern struct cpufreq_governor cpufreq_gov_userspace;
 extern struct cpufreq_governor cpufreq_gov_userspace;
 #define CPUFREQ_DEFAULT_GOVERNOR	(&cpufreq_gov_userspace)
 #define CPUFREQ_DEFAULT_GOVERNOR	(&cpufreq_gov_userspace)