diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-06-13 17:33:17 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-06-13 17:33:17 -0400 |
commit | bb4b9933e2bc0554cf4db37aa07b19ff69a85f8f (patch) | |
tree | 92ec230e0292874d6a53ff33534e8637fa315479 /drivers/cpufreq/cpufreq.c | |
parent | 5edb56491d4812c42175980759da53388e5d86f5 (diff) | |
parent | f6709b8aa78fb6765c443ad6b70fdaf48b89d95d (diff) |
Merge back earlier cpufreq changes for v4.8.
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 186 |
1 files changed, 102 insertions, 84 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 9009295f5134..9ae58a18ccb9 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 */ |
77 | static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); | ||
78 | static unsigned int __cpufreq_get(struct cpufreq_policy *policy); | 77 | static unsigned int __cpufreq_get(struct cpufreq_policy *policy); |
78 | static int cpufreq_init_governor(struct cpufreq_policy *policy); | ||
79 | static void cpufreq_exit_governor(struct cpufreq_policy *policy); | ||
79 | static int cpufreq_start_governor(struct cpufreq_policy *policy); | 80 | static int cpufreq_start_governor(struct cpufreq_policy *policy); |
80 | 81 | static void cpufreq_stop_governor(struct cpufreq_policy *policy); | |
81 | static inline void cpufreq_exit_governor(struct cpufreq_policy *policy) | 82 | static void cpufreq_governor_limits(struct cpufreq_policy *policy); |
82 | { | ||
83 | (void)cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); | ||
84 | } | ||
85 | |||
86 | static 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 |
@@ -133,15 +126,6 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy) | |||
133 | } | 126 | } |
134 | EXPORT_SYMBOL_GPL(get_governor_parent_kobj); | 127 | EXPORT_SYMBOL_GPL(get_governor_parent_kobj); |
135 | 128 | ||
136 | struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) | ||
137 | { | ||
138 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
139 | |||
140 | return policy && !policy_is_inactive(policy) ? | ||
141 | policy->freq_table : NULL; | ||
142 | } | ||
143 | EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); | ||
144 | |||
145 | static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) | 129 | static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) |
146 | { | 130 | { |
147 | u64 idle_time; | 131 | u64 idle_time; |
@@ -354,6 +338,7 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, | |||
354 | pr_debug("FREQ: %lu - CPU: %lu\n", | 338 | pr_debug("FREQ: %lu - CPU: %lu\n", |
355 | (unsigned long)freqs->new, (unsigned long)freqs->cpu); | 339 | (unsigned long)freqs->new, (unsigned long)freqs->cpu); |
356 | trace_cpu_frequency(freqs->new, freqs->cpu); | 340 | trace_cpu_frequency(freqs->new, freqs->cpu); |
341 | cpufreq_stats_record_transition(policy, freqs->new); | ||
357 | srcu_notifier_call_chain(&cpufreq_transition_notifier_list, | 342 | srcu_notifier_call_chain(&cpufreq_transition_notifier_list, |
358 | CPUFREQ_POSTCHANGE, freqs); | 343 | CPUFREQ_POSTCHANGE, freqs); |
359 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) | 344 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) |
@@ -1115,6 +1100,7 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy, bool notify) | |||
1115 | CPUFREQ_REMOVE_POLICY, policy); | 1100 | CPUFREQ_REMOVE_POLICY, policy); |
1116 | 1101 | ||
1117 | down_write(&policy->rwsem); | 1102 | down_write(&policy->rwsem); |
1103 | cpufreq_stats_free_table(policy); | ||
1118 | cpufreq_remove_dev_symlink(policy); | 1104 | cpufreq_remove_dev_symlink(policy); |
1119 | kobj = &policy->kobj; | 1105 | kobj = &policy->kobj; |
1120 | cmp = &policy->kobj_unregister; | 1106 | cmp = &policy->kobj_unregister; |
@@ -1265,13 +1251,12 @@ static int cpufreq_online(unsigned int cpu) | |||
1265 | } | 1251 | } |
1266 | } | 1252 | } |
1267 | 1253 | ||
1268 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | ||
1269 | CPUFREQ_START, policy); | ||
1270 | |||
1271 | if (new_policy) { | 1254 | if (new_policy) { |
1272 | ret = cpufreq_add_dev_interface(policy); | 1255 | ret = cpufreq_add_dev_interface(policy); |
1273 | if (ret) | 1256 | if (ret) |
1274 | goto out_exit_policy; | 1257 | goto out_exit_policy; |
1258 | |||
1259 | cpufreq_stats_create_table(policy); | ||
1275 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1260 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1276 | CPUFREQ_CREATE_POLICY, policy); | 1261 | CPUFREQ_CREATE_POLICY, policy); |
1277 | 1262 | ||
@@ -1280,6 +1265,9 @@ static int cpufreq_online(unsigned int cpu) | |||
1280 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1265 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1281 | } | 1266 | } |
1282 | 1267 | ||
1268 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | ||
1269 | CPUFREQ_START, policy); | ||
1270 | |||
1283 | ret = cpufreq_init_policy(policy); | 1271 | ret = cpufreq_init_policy(policy); |
1284 | if (ret) { | 1272 | if (ret) { |
1285 | pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n", | 1273 | pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n", |
@@ -1864,14 +1852,17 @@ static int __target_intermediate(struct cpufreq_policy *policy, | |||
1864 | return ret; | 1852 | return ret; |
1865 | } | 1853 | } |
1866 | 1854 | ||
1867 | static int __target_index(struct cpufreq_policy *policy, | 1855 | static int __target_index(struct cpufreq_policy *policy, int index) |
1868 | struct cpufreq_frequency_table *freq_table, int index) | ||
1869 | { | 1856 | { |
1870 | struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0}; | 1857 | struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0}; |
1871 | unsigned int intermediate_freq = 0; | 1858 | unsigned int intermediate_freq = 0; |
1859 | unsigned int newfreq = policy->freq_table[index].frequency; | ||
1872 | int retval = -EINVAL; | 1860 | int retval = -EINVAL; |
1873 | bool notify; | 1861 | bool notify; |
1874 | 1862 | ||
1863 | if (newfreq == policy->cur) | ||
1864 | return 0; | ||
1865 | |||
1875 | notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION); | 1866 | notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION); |
1876 | if (notify) { | 1867 | if (notify) { |
1877 | /* Handle switching to intermediate frequency */ | 1868 | /* Handle switching to intermediate frequency */ |
@@ -1886,7 +1877,7 @@ static int __target_index(struct cpufreq_policy *policy, | |||
1886 | freqs.old = freqs.new; | 1877 | freqs.old = freqs.new; |
1887 | } | 1878 | } |
1888 | 1879 | ||
1889 | freqs.new = freq_table[index].frequency; | 1880 | freqs.new = newfreq; |
1890 | pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", | 1881 | pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", |
1891 | __func__, policy->cpu, freqs.old, freqs.new); | 1882 | __func__, policy->cpu, freqs.old, freqs.new); |
1892 | 1883 | ||
@@ -1923,17 +1914,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1923 | unsigned int relation) | 1914 | unsigned int relation) |
1924 | { | 1915 | { |
1925 | unsigned int old_target_freq = target_freq; | 1916 | unsigned int old_target_freq = target_freq; |
1926 | struct cpufreq_frequency_table *freq_table; | 1917 | int index; |
1927 | int index, retval; | ||
1928 | 1918 | ||
1929 | if (cpufreq_disabled()) | 1919 | if (cpufreq_disabled()) |
1930 | return -ENODEV; | 1920 | return -ENODEV; |
1931 | 1921 | ||
1932 | /* Make sure that target_freq is within supported range */ | 1922 | /* Make sure that target_freq is within supported range */ |
1933 | if (target_freq > policy->max) | 1923 | target_freq = clamp_val(target_freq, policy->min, policy->max); |
1934 | target_freq = policy->max; | ||
1935 | if (target_freq < policy->min) | ||
1936 | target_freq = policy->min; | ||
1937 | 1924 | ||
1938 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", | 1925 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", |
1939 | policy->cpu, target_freq, relation, old_target_freq); | 1926 | policy->cpu, target_freq, relation, old_target_freq); |
@@ -1956,23 +1943,9 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1956 | if (!cpufreq_driver->target_index) | 1943 | if (!cpufreq_driver->target_index) |
1957 | return -EINVAL; | 1944 | return -EINVAL; |
1958 | 1945 | ||
1959 | freq_table = cpufreq_frequency_get_table(policy->cpu); | 1946 | index = cpufreq_frequency_table_target(policy, target_freq, relation); |
1960 | if (unlikely(!freq_table)) { | ||
1961 | pr_err("%s: Unable to find freq_table\n", __func__); | ||
1962 | return -EINVAL; | ||
1963 | } | ||
1964 | |||
1965 | retval = cpufreq_frequency_table_target(policy, freq_table, target_freq, | ||
1966 | relation, &index); | ||
1967 | if (unlikely(retval)) { | ||
1968 | pr_err("%s: Unable to find matching freq\n", __func__); | ||
1969 | return retval; | ||
1970 | } | ||
1971 | |||
1972 | if (freq_table[index].frequency == policy->cur) | ||
1973 | return 0; | ||
1974 | 1947 | ||
1975 | return __target_index(policy, freq_table, index); | 1948 | return __target_index(policy, index); |
1976 | } | 1949 | } |
1977 | EXPORT_SYMBOL_GPL(__cpufreq_driver_target); | 1950 | EXPORT_SYMBOL_GPL(__cpufreq_driver_target); |
1978 | 1951 | ||
@@ -1997,7 +1970,7 @@ __weak struct cpufreq_governor *cpufreq_fallback_governor(void) | |||
1997 | return NULL; | 1970 | return NULL; |
1998 | } | 1971 | } |
1999 | 1972 | ||
2000 | static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) | 1973 | static int cpufreq_init_governor(struct cpufreq_policy *policy) |
2001 | { | 1974 | { |
2002 | int ret; | 1975 | int ret; |
2003 | 1976 | ||
@@ -2025,36 +1998,82 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) | |||
2025 | } | 1998 | } |
2026 | } | 1999 | } |
2027 | 2000 | ||
2028 | if (event == CPUFREQ_GOV_POLICY_INIT) | 2001 | if (!try_module_get(policy->governor->owner)) |
2029 | if (!try_module_get(policy->governor->owner)) | 2002 | return -EINVAL; |
2030 | return -EINVAL; | ||
2031 | |||
2032 | pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); | ||
2033 | 2003 | ||
2034 | ret = policy->governor->governor(policy, event); | 2004 | pr_debug("%s: for CPU %u\n", __func__, policy->cpu); |
2035 | 2005 | ||
2036 | if (event == CPUFREQ_GOV_POLICY_INIT) { | 2006 | if (policy->governor->init) { |
2037 | if (ret) | 2007 | ret = policy->governor->init(policy); |
2008 | if (ret) { | ||
2038 | module_put(policy->governor->owner); | 2009 | module_put(policy->governor->owner); |
2039 | else | 2010 | return ret; |
2040 | policy->governor->initialized++; | 2011 | } |
2041 | } else if (event == CPUFREQ_GOV_POLICY_EXIT) { | ||
2042 | policy->governor->initialized--; | ||
2043 | module_put(policy->governor->owner); | ||
2044 | } | 2012 | } |
2045 | 2013 | ||
2046 | return ret; | 2014 | return 0; |
2015 | } | ||
2016 | |||
2017 | static void cpufreq_exit_governor(struct cpufreq_policy *policy) | ||
2018 | { | ||
2019 | if (cpufreq_suspended || !policy->governor) | ||
2020 | return; | ||
2021 | |||
2022 | pr_debug("%s: for CPU %u\n", __func__, policy->cpu); | ||
2023 | |||
2024 | if (policy->governor->exit) | ||
2025 | policy->governor->exit(policy); | ||
2026 | |||
2027 | module_put(policy->governor->owner); | ||
2047 | } | 2028 | } |
2048 | 2029 | ||
2049 | static int cpufreq_start_governor(struct cpufreq_policy *policy) | 2030 | static int cpufreq_start_governor(struct cpufreq_policy *policy) |
2050 | { | 2031 | { |
2051 | int ret; | 2032 | int ret; |
2052 | 2033 | ||
2034 | if (cpufreq_suspended) | ||
2035 | return 0; | ||
2036 | |||
2037 | if (!policy->governor) | ||
2038 | return -EINVAL; | ||
2039 | |||
2040 | pr_debug("%s: for CPU %u\n", __func__, policy->cpu); | ||
2041 | |||
2053 | if (cpufreq_driver->get && !cpufreq_driver->setpolicy) | 2042 | if (cpufreq_driver->get && !cpufreq_driver->setpolicy) |
2054 | cpufreq_update_current_freq(policy); | 2043 | cpufreq_update_current_freq(policy); |
2055 | 2044 | ||
2056 | ret = cpufreq_governor(policy, CPUFREQ_GOV_START); | 2045 | if (policy->governor->start) { |
2057 | return ret ? ret : cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 2046 | ret = policy->governor->start(policy); |
2047 | if (ret) | ||
2048 | return ret; | ||
2049 | } | ||
2050 | |||
2051 | if (policy->governor->limits) | ||
2052 | policy->governor->limits(policy); | ||
2053 | |||
2054 | return 0; | ||
2055 | } | ||
2056 | |||
2057 | static void cpufreq_stop_governor(struct cpufreq_policy *policy) | ||
2058 | { | ||
2059 | if (cpufreq_suspended || !policy->governor) | ||
2060 | return; | ||
2061 | |||
2062 | pr_debug("%s: for CPU %u\n", __func__, policy->cpu); | ||
2063 | |||
2064 | if (policy->governor->stop) | ||
2065 | policy->governor->stop(policy); | ||
2066 | } | ||
2067 | |||
2068 | static void cpufreq_governor_limits(struct cpufreq_policy *policy) | ||
2069 | { | ||
2070 | if (cpufreq_suspended || !policy->governor) | ||
2071 | return; | ||
2072 | |||
2073 | pr_debug("%s: for CPU %u\n", __func__, policy->cpu); | ||
2074 | |||
2075 | if (policy->governor->limits) | ||
2076 | policy->governor->limits(policy); | ||
2058 | } | 2077 | } |
2059 | 2078 | ||
2060 | int cpufreq_register_governor(struct cpufreq_governor *governor) | 2079 | int cpufreq_register_governor(struct cpufreq_governor *governor) |
@@ -2069,7 +2088,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) | |||
2069 | 2088 | ||
2070 | mutex_lock(&cpufreq_governor_mutex); | 2089 | mutex_lock(&cpufreq_governor_mutex); |
2071 | 2090 | ||
2072 | governor->initialized = 0; | ||
2073 | err = -EBUSY; | 2091 | err = -EBUSY; |
2074 | if (!find_governor(governor->name)) { | 2092 | if (!find_governor(governor->name)) { |
2075 | err = 0; | 2093 | err = 0; |
@@ -2195,7 +2213,8 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2195 | 2213 | ||
2196 | if (new_policy->governor == policy->governor) { | 2214 | if (new_policy->governor == policy->governor) { |
2197 | pr_debug("cpufreq: governor limits update\n"); | 2215 | pr_debug("cpufreq: governor limits update\n"); |
2198 | return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 2216 | cpufreq_governor_limits(policy); |
2217 | return 0; | ||
2199 | } | 2218 | } |
2200 | 2219 | ||
2201 | pr_debug("governor switch\n"); | 2220 | pr_debug("governor switch\n"); |
@@ -2210,7 +2229,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2210 | 2229 | ||
2211 | /* start new governor */ | 2230 | /* start new governor */ |
2212 | policy->governor = new_policy->governor; | 2231 | policy->governor = new_policy->governor; |
2213 | ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); | 2232 | ret = cpufreq_init_governor(policy); |
2214 | if (!ret) { | 2233 | if (!ret) { |
2215 | ret = cpufreq_start_governor(policy); | 2234 | ret = cpufreq_start_governor(policy); |
2216 | if (!ret) { | 2235 | if (!ret) { |
@@ -2224,7 +2243,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2224 | pr_debug("starting governor %s failed\n", policy->governor->name); | 2243 | pr_debug("starting governor %s failed\n", policy->governor->name); |
2225 | if (old_gov) { | 2244 | if (old_gov) { |
2226 | policy->governor = old_gov; | 2245 | policy->governor = old_gov; |
2227 | if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) | 2246 | if (cpufreq_init_governor(policy)) |
2228 | policy->governor = NULL; | 2247 | policy->governor = NULL; |
2229 | else | 2248 | else |
2230 | cpufreq_start_governor(policy); | 2249 | cpufreq_start_governor(policy); |
@@ -2305,26 +2324,25 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = { | |||
2305 | *********************************************************************/ | 2324 | *********************************************************************/ |
2306 | static int cpufreq_boost_set_sw(int state) | 2325 | static int cpufreq_boost_set_sw(int state) |
2307 | { | 2326 | { |
2308 | struct cpufreq_frequency_table *freq_table; | ||
2309 | struct cpufreq_policy *policy; | 2327 | struct cpufreq_policy *policy; |
2310 | int ret = -EINVAL; | 2328 | int ret = -EINVAL; |
2311 | 2329 | ||
2312 | for_each_active_policy(policy) { | 2330 | for_each_active_policy(policy) { |
2313 | freq_table = cpufreq_frequency_get_table(policy->cpu); | 2331 | if (!policy->freq_table) |
2314 | if (freq_table) { | 2332 | continue; |
2315 | ret = cpufreq_frequency_table_cpuinfo(policy, | 2333 | |
2316 | freq_table); | 2334 | ret = cpufreq_frequency_table_cpuinfo(policy, |
2317 | if (ret) { | 2335 | policy->freq_table); |
2318 | pr_err("%s: Policy frequency update failed\n", | 2336 | if (ret) { |
2319 | __func__); | 2337 | pr_err("%s: Policy frequency update failed\n", |
2320 | break; | 2338 | __func__); |
2321 | } | 2339 | break; |
2322 | |||
2323 | down_write(&policy->rwsem); | ||
2324 | policy->user_policy.max = policy->max; | ||
2325 | cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | ||
2326 | up_write(&policy->rwsem); | ||
2327 | } | 2340 | } |
2341 | |||
2342 | down_write(&policy->rwsem); | ||
2343 | policy->user_policy.max = policy->max; | ||
2344 | cpufreq_governor_limits(policy); | ||
2345 | up_write(&policy->rwsem); | ||
2328 | } | 2346 | } |
2329 | 2347 | ||
2330 | return ret; | 2348 | return ret; |