aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-05-13 19:01:46 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-05-30 08:34:17 -0400
commita92604b419f47e1c5098632742d8e031f6e8fab1 (patch)
treeac817b44523f5d789c11a0e4f6e3be7ce46ea9d0 /drivers/cpufreq/cpufreq.c
parent16de72b9f4d07e393bea7b1221898b3be718a296 (diff)
cpufreq: Split cpufreq_governor() into simpler functions
The cpufreq_governor() routine is used by the cpufreq core to invoke the current governor's ->governor() callback with appropriate arguments and do some housekeeping related to that. Unfortunately, the way it mixes different governor events in one code path makes it rather hard to follow the code. For this reason, split cpufreq_governor() into five simpler functions that each will handle just one specific governor event and put all of the code related to the given event into its own function. This change is a prerequisite for a redesign of the cpufreq governor API that will be done subsequently. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c113
1 files changed, 70 insertions, 43 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a5f1d016d473..268566e40684 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -74,19 +74,12 @@ static inline bool has_target(void)
74} 74}
75 75
76/* internal prototypes */ 76/* internal prototypes */
77static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
78static unsigned int __cpufreq_get(struct cpufreq_policy *policy); 77static unsigned int __cpufreq_get(struct cpufreq_policy *policy);
78static int cpufreq_init_governor(struct cpufreq_policy *policy);
79static void cpufreq_exit_governor(struct cpufreq_policy *policy);
79static int cpufreq_start_governor(struct cpufreq_policy *policy); 80static int cpufreq_start_governor(struct cpufreq_policy *policy);
80 81static void cpufreq_stop_governor(struct cpufreq_policy *policy);
81static inline void cpufreq_exit_governor(struct cpufreq_policy *policy) 82static void cpufreq_governor_limits(struct cpufreq_policy *policy);
82{
83 (void)cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
84}
85
86static inline void cpufreq_stop_governor(struct cpufreq_policy *policy)
87{
88 (void)cpufreq_governor(policy, CPUFREQ_GOV_STOP);
89}
90 83
91/** 84/**
92 * Two notifier lists: the "policy" list is involved in the 85 * Two notifier lists: the "policy" list is involved in the
@@ -1997,7 +1990,7 @@ __weak struct cpufreq_governor *cpufreq_fallback_governor(void)
1997 return NULL; 1990 return NULL;
1998} 1991}
1999 1992
2000static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) 1993static int cpufreq_init_governor(struct cpufreq_policy *policy)
2001{ 1994{
2002 int ret; 1995 int ret;
2003 1996
@@ -2011,57 +2004,91 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
2011 if (!policy->governor) 2004 if (!policy->governor)
2012 return -EINVAL; 2005 return -EINVAL;
2013 2006
2014 if (event == CPUFREQ_GOV_POLICY_INIT) { 2007 if (policy->governor->max_transition_latency &&
2015 if (policy->governor->max_transition_latency && 2008 policy->cpuinfo.transition_latency >
2016 policy->cpuinfo.transition_latency > 2009 policy->governor->max_transition_latency) {
2017 policy->governor->max_transition_latency) { 2010 struct cpufreq_governor *gov = cpufreq_fallback_governor();
2018 struct cpufreq_governor *gov = cpufreq_fallback_governor();
2019
2020 if (gov) {
2021 pr_warn("%s governor failed, too long transition latency of HW, fallback to %s governor\n",
2022 policy->governor->name, gov->name);
2023 policy->governor = gov;
2024 } else {
2025 return -EINVAL;
2026 }
2027 }
2028 2011
2029 if (!try_module_get(policy->governor->owner)) 2012 if (gov) {
2013 pr_warn("%s governor failed, too long transition latency of HW, fallback to %s governor\n",
2014 policy->governor->name, gov->name);
2015 policy->governor = gov;
2016 } else {
2030 return -EINVAL; 2017 return -EINVAL;
2018 }
2031 } 2019 }
2032 2020
2033 pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); 2021 if (!try_module_get(policy->governor->owner))
2022 return -EINVAL;
2034 2023
2035 ret = policy->governor->governor(policy, event); 2024 pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
2036 2025
2037 if (event == CPUFREQ_GOV_POLICY_INIT) { 2026 ret = policy->governor->governor(policy, CPUFREQ_GOV_POLICY_INIT);
2038 if (ret) 2027 if (ret) {
2039 module_put(policy->governor->owner);
2040 else
2041 policy->governor->initialized++;
2042 } else if (event == CPUFREQ_GOV_POLICY_EXIT) {
2043 policy->governor->initialized--;
2044 module_put(policy->governor->owner); 2028 module_put(policy->governor->owner);
2029 return ret;
2045 } 2030 }
2046 2031
2047 return ret; 2032 policy->governor->initialized++;
2033 return 0;
2034}
2035
2036static void cpufreq_exit_governor(struct cpufreq_policy *policy)
2037{
2038 if (cpufreq_suspended || !policy->governor)
2039 return;
2040
2041 pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
2042
2043 policy->governor->governor(policy, CPUFREQ_GOV_POLICY_EXIT);
2044
2045 policy->governor->initialized--;
2046 module_put(policy->governor->owner);
2048} 2047}
2049 2048
2050static int cpufreq_start_governor(struct cpufreq_policy *policy) 2049static int cpufreq_start_governor(struct cpufreq_policy *policy)
2051{ 2050{
2052 int ret; 2051 int ret;
2053 2052
2053 if (cpufreq_suspended)
2054 return 0;
2055
2056 if (!policy->governor)
2057 return -EINVAL;
2058
2059 pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
2060
2054 if (cpufreq_driver->get && !cpufreq_driver->setpolicy) 2061 if (cpufreq_driver->get && !cpufreq_driver->setpolicy)
2055 cpufreq_update_current_freq(policy); 2062 cpufreq_update_current_freq(policy);
2056 2063
2057 ret = cpufreq_governor(policy, CPUFREQ_GOV_START); 2064 ret = policy->governor->governor(policy, CPUFREQ_GOV_START);
2058 if (ret) 2065 if (ret)
2059 return ret; 2066 return ret;
2060 2067
2061 cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); 2068 policy->governor->governor(policy, CPUFREQ_GOV_LIMITS);
2062 return 0; 2069 return 0;
2063} 2070}
2064 2071
2072static void cpufreq_stop_governor(struct cpufreq_policy *policy)
2073{
2074 if (cpufreq_suspended || !policy->governor)
2075 return;
2076
2077 pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
2078
2079 policy->governor->governor(policy, CPUFREQ_GOV_STOP);
2080}
2081
2082static void cpufreq_governor_limits(struct cpufreq_policy *policy)
2083{
2084 if (cpufreq_suspended || !policy->governor)
2085 return;
2086
2087 pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
2088
2089 policy->governor->governor(policy, CPUFREQ_GOV_LIMITS);
2090}
2091
2065int cpufreq_register_governor(struct cpufreq_governor *governor) 2092int cpufreq_register_governor(struct cpufreq_governor *governor)
2066{ 2093{
2067 int err; 2094 int err;
@@ -2200,7 +2227,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
2200 2227
2201 if (new_policy->governor == policy->governor) { 2228 if (new_policy->governor == policy->governor) {
2202 pr_debug("cpufreq: governor limits update\n"); 2229 pr_debug("cpufreq: governor limits update\n");
2203 cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); 2230 cpufreq_governor_limits(policy);
2204 return 0; 2231 return 0;
2205 } 2232 }
2206 2233
@@ -2216,7 +2243,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
2216 2243
2217 /* start new governor */ 2244 /* start new governor */
2218 policy->governor = new_policy->governor; 2245 policy->governor = new_policy->governor;
2219 ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); 2246 ret = cpufreq_init_governor(policy);
2220 if (!ret) { 2247 if (!ret) {
2221 ret = cpufreq_start_governor(policy); 2248 ret = cpufreq_start_governor(policy);
2222 if (!ret) { 2249 if (!ret) {
@@ -2230,7 +2257,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
2230 pr_debug("starting governor %s failed\n", policy->governor->name); 2257 pr_debug("starting governor %s failed\n", policy->governor->name);
2231 if (old_gov) { 2258 if (old_gov) {
2232 policy->governor = old_gov; 2259 policy->governor = old_gov;
2233 if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) 2260 if (cpufreq_init_governor(policy))
2234 policy->governor = NULL; 2261 policy->governor = NULL;
2235 else 2262 else
2236 cpufreq_start_governor(policy); 2263 cpufreq_start_governor(policy);
@@ -2328,7 +2355,7 @@ static int cpufreq_boost_set_sw(int state)
2328 2355
2329 down_write(&policy->rwsem); 2356 down_write(&policy->rwsem);
2330 policy->user_policy.max = policy->max; 2357 policy->user_policy.max = policy->max;
2331 cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); 2358 cpufreq_governor_limits(policy);
2332 up_write(&policy->rwsem); 2359 up_write(&policy->rwsem);
2333 } 2360 }
2334 } 2361 }