From 944e9a0316e60bc5bc122e46c1fde36e5f6e9f56 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 16 May 2013 05:09:57 +0000 Subject: cpufreq: governors: Move get_governor_parent_kobj() to cpufreq.c get_governor_parent_kobj() can be used by any governor, generic cpufreq governors or platform specific ones and so must be present in cpufreq.c instead of cpufreq_governor.c. This patch moves it to cpufreq.c. This also adds EXPORT_SYMBOL_GPL(get_governor_parent_kobj) so that modules can use this function too. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 037d36ae63e5..dd1a5d41357b 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -340,6 +340,7 @@ const char *cpufreq_get_current_driver(void); int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); int cpufreq_update_policy(unsigned int cpu); bool have_governor_per_policy(void); +struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy); #ifdef CONFIG_CPU_FREQ /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */ -- cgit v1.2.3 From 72a4ce340a7ebf39e1c6fdc8f5feb4f974d6c635 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 17 May 2013 11:26:32 +0000 Subject: cpufreq: Move get_cpu_idle_time() to cpufreq.c Governors other than ondemand and conservative can also use get_cpu_idle_time() and they aren't required to compile cpufreq_governor.c. So, move these independent routines to cpufreq.c instead. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index dd1a5d41357b..fbf392aaa02e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -337,6 +337,7 @@ const char *cpufreq_get_current_driver(void); /********************************************************************* * CPUFREQ 2.6. INTERFACE * *********************************************************************/ +u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy); int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); int cpufreq_update_policy(unsigned int cpu); bool have_governor_per_policy(void); -- cgit v1.2.3 From 2361be23666232dbb4851a527f466c4cbf5340fc Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 17 May 2013 16:09:09 +0530 Subject: cpufreq: Don't create empty /sys/devices/system/cpu/cpufreq directory When we don't have any file in cpu/cpufreq directory we shouldn't create it. Specially with the introduction of per-policy governor instance patchset, even governors are moved to cpu/cpu*/cpufreq/governor-name directory and so this directory is just not required. Lets have it only when required. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index fbf392aaa02e..1b5b5efa3e3a 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -71,6 +71,10 @@ struct cpufreq_governor; /* /sys/devices/system/cpu/cpufreq: entry point for global variables */ extern struct kobject *cpufreq_global_kobject; +int cpufreq_get_global_kobject(void); +void cpufreq_put_global_kobject(void); +int cpufreq_sysfs_create_file(const struct attribute *attr); +void cpufreq_sysfs_remove_file(const struct attribute *attr); #define CPUFREQ_ETERNAL (-1) struct cpufreq_cpuinfo { -- cgit v1.2.3 From 5070158804b5339c71809f5e673cea1cfacd804d Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sat, 30 Mar 2013 16:25:15 +0530 Subject: cpufreq: rename index as driver_data in cpufreq_frequency_table The "index" field of struct cpufreq_frequency_table was never an index and isn't used at all by the cpufreq core. It only is useful for cpufreq drivers for their internal purposes. Many people nowadays blindly set it in ascending order with the assumption that the core will use it, which is a mistake. Rename it to "driver_data" as that's what its purpose is. All of its users are updated accordingly. [rjw: Changelog] Signed-off-by: Viresh Kumar Acked-by: Simon Horman Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 1b5b5efa3e3a..d93905633dc7 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -410,7 +410,7 @@ extern struct cpufreq_governor cpufreq_gov_conservative; #define CPUFREQ_TABLE_END ~1 struct cpufreq_frequency_table { - unsigned int index; /* any */ + unsigned int driver_data; /* driver specific data, not used by core */ unsigned int frequency; /* kHz - doesn't need to be in ascending * order */ }; -- cgit v1.2.3 From 95731ebb114c5f0c028459388560fc2a72fe5049 Mon Sep 17 00:00:00 2001 From: Xiaoguang Chen Date: Wed, 19 Jun 2013 15:00:07 +0800 Subject: cpufreq: Fix governor start/stop race condition Cpufreq governors' stop and start operations should be carried out in sequence. Otherwise, there will be unexpected behavior, like in the example below. Suppose there are 4 CPUs and policy->cpu=CPU0, CPU1/2/3 are linked to CPU0. The normal sequence is: 1) Current governor is userspace. An application tries to set the governor to ondemand. It will call __cpufreq_set_policy() in which it will stop the userspace governor and then start the ondemand governor. 2) Current governor is userspace. The online of CPU3 runs on CPU0. It will call cpufreq_add_policy_cpu() in which it will first stop the userspace governor, and then start it again. If the sequence of the above two cases interleaves, it becomes: 1) Application stops userspace governor 2) Hotplug stops userspace governor which is a problem, because the governor shouldn't be stopped twice in a row. What happens next is: 3) Application starts ondemand governor 4) Hotplug starts a governor In step 4, the hotplug is supposed to start the userspace governor, but now the governor has been changed by the application to ondemand, so the ondemand governor is started once again, which is incorrect. The solution is to prevent policy governors from being stopped multiple times in a row. A governor should only be stopped once for one policy. After it has been stopped, no more governor stop operations should be executed. Also add a mutex to serialize governor operations. [rjw: Changelog. And you owe me a beverage of my choice.] Signed-off-by: Xiaoguang Chen Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index d93905633dc7..125719d41285 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -111,6 +111,7 @@ struct cpufreq_policy { unsigned int policy; /* see above */ struct cpufreq_governor *governor; /* see below */ void *governor_data; + bool governor_enabled; /* governor start/stop flag */ struct work_struct update; /* if update_policy() needs to be * called, but you're in IRQ context */ -- cgit v1.2.3 From bb176f7d038fee4d46b3293e64e173bfb05ab7b5 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 19 Jun 2013 14:19:33 +0530 Subject: cpufreq: Fix minor formatting issues There were a few noticeable formatting issues in core cpufreq code. This cleans them up to make code look better. The changes include: - Whitespace cleanup. - Rearrangements of code. - Multiline comments fixes. - Formatting changes to fit 80 columns. Copyright information in cpufreq.c is also updated to include my name for 2013. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 125719d41285..3c7ee2f90370 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -1,8 +1,8 @@ /* - * linux/include/linux/cpufreq.h + * linux/include/linux/cpufreq.h * - * Copyright (C) 2001 Russell King - * (C) 2002 - 2003 Dominik Brodowski + * Copyright (C) 2001 Russell King + * (C) 2002 - 2003 Dominik Brodowski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,7 +26,6 @@ /* Print length for names. Extra 1 space for accomodating '\n' in prints */ #define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1) - /********************************************************************* * CPUFREQ NOTIFIER INTERFACE * *********************************************************************/ @@ -153,17 +152,18 @@ struct cpufreq_freqs { u8 flags; /* flags of cpufreq_driver, see below. */ }; - /** - * cpufreq_scale - "old * mult / div" calculation for large values (32-bit-arch safe) + * cpufreq_scale - "old * mult / div" calculation for large values (32-bit-arch + * safe) * @old: old value * @div: divisor * @mult: multiplier * * - * new = old * mult / div + * new = old * mult / div */ -static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mult) +static inline unsigned long cpufreq_scale(unsigned long old, u_int div, + u_int mult) { #if BITS_PER_LONG == 32 @@ -216,14 +216,12 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); - extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu); int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); - /********************************************************************* * CPUFREQ DRIVER INTERFACE * *********************************************************************/ @@ -234,7 +232,7 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor); struct freq_attr; struct cpufreq_driver { - struct module *owner; + struct module *owner; char name[CPUFREQ_NAME_LEN]; u8 flags; /* @@ -282,11 +280,11 @@ struct cpufreq_driver { int cpufreq_register_driver(struct cpufreq_driver *driver_data); int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); - void cpufreq_notify_transition(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs, unsigned int state); -static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned int min, unsigned int max) +static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, + unsigned int min, unsigned int max) { if (policy->min < min) policy->min = min; @@ -349,7 +347,9 @@ bool have_governor_per_policy(void); struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy); #ifdef CONFIG_CPU_FREQ -/* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */ +/* + * query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it + */ unsigned int cpufreq_get(unsigned int cpu); #else static inline unsigned int cpufreq_get(unsigned int cpu) @@ -358,7 +358,9 @@ static inline unsigned int cpufreq_get(unsigned int cpu) } #endif -/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */ +/* + * query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it + */ #ifdef CONFIG_CPU_FREQ unsigned int cpufreq_quick_get(unsigned int cpu); unsigned int cpufreq_quick_get_max(unsigned int cpu); @@ -373,16 +375,14 @@ static inline unsigned int cpufreq_quick_get_max(unsigned int cpu) } #endif - /********************************************************************* * CPUFREQ DEFAULT GOVERNOR * *********************************************************************/ - /* - Performance governor is fallback governor if any other gov failed to - auto load due latency restrictions -*/ + * Performance governor is fallback governor if any other gov failed to auto + * load due latency restrictions + */ #ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE extern struct cpufreq_governor cpufreq_gov_performance; #endif @@ -402,7 +402,6 @@ extern struct cpufreq_governor cpufreq_gov_conservative; #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative) #endif - /********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ -- cgit v1.2.3 From 7c30ed532cf798a8d924562f2f44d03d7652f7a7 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 19 Jun 2013 10:16:55 +0530 Subject: cpufreq: make sure frequency transitions are serialized Whenever we are changing frequency of a cpu, we are calling PRECHANGE and POSTCHANGE notifiers. They must be serialized. i.e. PRECHANGE or POSTCHANGE shouldn't be called twice contiguously. This can happen due to bugs in users of __cpufreq_driver_target() or actual cpufreq drivers who are sending these notifiers. This patch adds some protection against this. Now, we keep track of the last transaction and see if something went wrong. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 3c7ee2f90370..c0bc7374445e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -119,6 +119,7 @@ struct cpufreq_policy { struct kobject kobj; struct completion kobj_unregister; + bool transition_ongoing; /* Tracks transition status */ }; #define CPUFREQ_ADJUST (0) -- cgit v1.2.3 From f4fd3797848aa04e72e942c855fd279840a47fe4 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Thu, 27 Jun 2013 15:08:54 +0800 Subject: acpi-cpufreq: Add new sysfs attribute freqdomain_cpus Commits fcf8058 (cpufreq: Simplify cpufreq_add_dev()) and aa77a52 (cpufreq: acpi-cpufreq: Don't set policy->related_cpus from .init()) changed the contents of the "related_cpus" sysfs attribute on systems where acpi-cpufreq is used and user space can't get the list of CPUs which are in the same hardware coordination CPU domain (provided by the ACPI AML method _PSD) via "related_cpus" any more. To make up for that loss add a new sysfs attribute "freqdomian_cpus" for the acpi-cpufreq driver which exposes the list of CPUs in the same domain regardless of whether it is coordinated by hardware or software. [rjw: Changelog, documentation] References: https://bugzilla.kernel.org/show_bug.cgi?id=58761 Reported-by: Jean-Philippe Halimi Signed-off-by: Lan Tianyu Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index c0bc7374445e..4d7390bc1727 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -439,4 +439,7 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); void cpufreq_frequency_table_put_attr(unsigned int cpu); + +ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf); + #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3 From 266c13d767be61a17d8e6f2310b9b7c46278273b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 2 Jul 2013 16:36:28 +0530 Subject: cpufreq: Fix serialization of frequency transitions Commit 7c30ed ("cpufreq: make sure frequency transitions are serialized") interacts poorly with systems that have a single core freqency for all cores. On such systems we have a single policy for all cores with several CPUs. When we do a frequency transition the governor calls the pre and post change notifiers which causes cpufreq_notify_transition() per CPU. Since the policy is the same for all of them all CPUs after the first and the warnings added are generated by checking a per-policy flag the warnings will be triggered for all cores after the first. Fix this by allowing notifier to be called for n times. Where n is the number of cpus in policy->cpus. Reported-and-tested-by: Mark Brown Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/cpufreq.h') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 4d7390bc1727..90d5a15120d5 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -119,7 +119,7 @@ struct cpufreq_policy { struct kobject kobj; struct completion kobj_unregister; - bool transition_ongoing; /* Tracks transition status */ + int transition_ongoing; /* Tracks transition status */ }; #define CPUFREQ_ADJUST (0) -- cgit v1.2.3