diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-03-10 14:46:03 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-03-10 14:46:03 -0500 |
commit | a5acbfbd70bc6a0cd4c8ca8f4f5e52ac3ee7dca4 (patch) | |
tree | 5e4560aaaaf2dec73a25bf448e0dd73ded4f9117 /drivers/cpufreq/cpufreq.c | |
parent | edd4a893e097d744e8069acf585f8b02dbbc9134 (diff) | |
parent | adaf9fcd136970e480d7ca834c0cf25ce922ea74 (diff) |
Merge branch 'pm-cpufreq-governor' into pm-cpufreq
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 165 |
1 files changed, 67 insertions, 98 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index abca44c2e4e3..4c7825856eab 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -64,7 +64,6 @@ static LIST_HEAD(cpufreq_governor_list); | |||
64 | static struct cpufreq_driver *cpufreq_driver; | 64 | static struct cpufreq_driver *cpufreq_driver; |
65 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | 65 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
66 | static DEFINE_RWLOCK(cpufreq_driver_lock); | 66 | static DEFINE_RWLOCK(cpufreq_driver_lock); |
67 | DEFINE_MUTEX(cpufreq_governor_lock); | ||
68 | 67 | ||
69 | /* Flag to suspend/resume CPUFreq governors */ | 68 | /* Flag to suspend/resume CPUFreq governors */ |
70 | static bool cpufreq_suspended; | 69 | static bool cpufreq_suspended; |
@@ -75,10 +74,8 @@ static inline bool has_target(void) | |||
75 | } | 74 | } |
76 | 75 | ||
77 | /* internal prototypes */ | 76 | /* internal prototypes */ |
78 | static int __cpufreq_governor(struct cpufreq_policy *policy, | 77 | static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); |
79 | unsigned int event); | ||
80 | static unsigned int __cpufreq_get(struct cpufreq_policy *policy); | 78 | static unsigned int __cpufreq_get(struct cpufreq_policy *policy); |
81 | static void handle_update(struct work_struct *work); | ||
82 | 79 | ||
83 | /** | 80 | /** |
84 | * Two notifier lists: the "policy" list is involved in the | 81 | * Two notifier lists: the "policy" list is involved in the |
@@ -955,30 +952,38 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp | |||
955 | if (cpumask_test_cpu(cpu, policy->cpus)) | 952 | if (cpumask_test_cpu(cpu, policy->cpus)) |
956 | return 0; | 953 | return 0; |
957 | 954 | ||
955 | down_write(&policy->rwsem); | ||
958 | if (has_target()) { | 956 | if (has_target()) { |
959 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 957 | ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
960 | if (ret) { | 958 | if (ret) { |
961 | pr_err("%s: Failed to stop governor\n", __func__); | 959 | pr_err("%s: Failed to stop governor\n", __func__); |
962 | return ret; | 960 | goto unlock; |
963 | } | 961 | } |
964 | } | 962 | } |
965 | 963 | ||
966 | down_write(&policy->rwsem); | ||
967 | cpumask_set_cpu(cpu, policy->cpus); | 964 | cpumask_set_cpu(cpu, policy->cpus); |
968 | up_write(&policy->rwsem); | ||
969 | 965 | ||
970 | if (has_target()) { | 966 | if (has_target()) { |
971 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); | 967 | ret = cpufreq_governor(policy, CPUFREQ_GOV_START); |
972 | if (!ret) | 968 | if (!ret) |
973 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 969 | ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); |
974 | 970 | ||
975 | if (ret) { | 971 | if (ret) |
976 | pr_err("%s: Failed to start governor\n", __func__); | 972 | pr_err("%s: Failed to start governor\n", __func__); |
977 | return ret; | ||
978 | } | ||
979 | } | 973 | } |
980 | 974 | ||
981 | return 0; | 975 | unlock: |
976 | up_write(&policy->rwsem); | ||
977 | return ret; | ||
978 | } | ||
979 | |||
980 | static void handle_update(struct work_struct *work) | ||
981 | { | ||
982 | struct cpufreq_policy *policy = | ||
983 | container_of(work, struct cpufreq_policy, update); | ||
984 | unsigned int cpu = policy->cpu; | ||
985 | pr_debug("handle_update for cpu %u called\n", cpu); | ||
986 | cpufreq_update_policy(cpu); | ||
982 | } | 987 | } |
983 | 988 | ||
984 | static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) | 989 | static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) |
@@ -1267,9 +1272,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1267 | return ret; | 1272 | return ret; |
1268 | } | 1273 | } |
1269 | 1274 | ||
1270 | static void cpufreq_offline_prepare(unsigned int cpu) | 1275 | static void cpufreq_offline(unsigned int cpu) |
1271 | { | 1276 | { |
1272 | struct cpufreq_policy *policy; | 1277 | struct cpufreq_policy *policy; |
1278 | int ret; | ||
1273 | 1279 | ||
1274 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); | 1280 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); |
1275 | 1281 | ||
@@ -1279,13 +1285,13 @@ static void cpufreq_offline_prepare(unsigned int cpu) | |||
1279 | return; | 1285 | return; |
1280 | } | 1286 | } |
1281 | 1287 | ||
1288 | down_write(&policy->rwsem); | ||
1282 | if (has_target()) { | 1289 | if (has_target()) { |
1283 | int ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 1290 | ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
1284 | if (ret) | 1291 | if (ret) |
1285 | pr_err("%s: Failed to stop governor\n", __func__); | 1292 | pr_err("%s: Failed to stop governor\n", __func__); |
1286 | } | 1293 | } |
1287 | 1294 | ||
1288 | down_write(&policy->rwsem); | ||
1289 | cpumask_clear_cpu(cpu, policy->cpus); | 1295 | cpumask_clear_cpu(cpu, policy->cpus); |
1290 | 1296 | ||
1291 | if (policy_is_inactive(policy)) { | 1297 | if (policy_is_inactive(policy)) { |
@@ -1298,39 +1304,27 @@ static void cpufreq_offline_prepare(unsigned int cpu) | |||
1298 | /* Nominate new CPU */ | 1304 | /* Nominate new CPU */ |
1299 | policy->cpu = cpumask_any(policy->cpus); | 1305 | policy->cpu = cpumask_any(policy->cpus); |
1300 | } | 1306 | } |
1301 | up_write(&policy->rwsem); | ||
1302 | 1307 | ||
1303 | /* Start governor again for active policy */ | 1308 | /* Start governor again for active policy */ |
1304 | if (!policy_is_inactive(policy)) { | 1309 | if (!policy_is_inactive(policy)) { |
1305 | if (has_target()) { | 1310 | if (has_target()) { |
1306 | int ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); | 1311 | ret = cpufreq_governor(policy, CPUFREQ_GOV_START); |
1307 | if (!ret) | 1312 | if (!ret) |
1308 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 1313 | ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); |
1309 | 1314 | ||
1310 | if (ret) | 1315 | if (ret) |
1311 | pr_err("%s: Failed to start governor\n", __func__); | 1316 | pr_err("%s: Failed to start governor\n", __func__); |
1312 | } | 1317 | } |
1313 | } else if (cpufreq_driver->stop_cpu) { | ||
1314 | cpufreq_driver->stop_cpu(policy); | ||
1315 | } | ||
1316 | } | ||
1317 | 1318 | ||
1318 | static void cpufreq_offline_finish(unsigned int cpu) | 1319 | goto unlock; |
1319 | { | ||
1320 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1321 | |||
1322 | if (!policy) { | ||
1323 | pr_debug("%s: No cpu_data found\n", __func__); | ||
1324 | return; | ||
1325 | } | 1320 | } |
1326 | 1321 | ||
1327 | /* Only proceed for inactive policies */ | 1322 | if (cpufreq_driver->stop_cpu) |
1328 | if (!policy_is_inactive(policy)) | 1323 | cpufreq_driver->stop_cpu(policy); |
1329 | return; | ||
1330 | 1324 | ||
1331 | /* If cpu is last user of policy, free policy */ | 1325 | /* If cpu is last user of policy, free policy */ |
1332 | if (has_target()) { | 1326 | if (has_target()) { |
1333 | int ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); | 1327 | ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); |
1334 | if (ret) | 1328 | if (ret) |
1335 | pr_err("%s: Failed to exit governor\n", __func__); | 1329 | pr_err("%s: Failed to exit governor\n", __func__); |
1336 | } | 1330 | } |
@@ -1344,6 +1338,9 @@ static void cpufreq_offline_finish(unsigned int cpu) | |||
1344 | cpufreq_driver->exit(policy); | 1338 | cpufreq_driver->exit(policy); |
1345 | policy->freq_table = NULL; | 1339 | policy->freq_table = NULL; |
1346 | } | 1340 | } |
1341 | |||
1342 | unlock: | ||
1343 | up_write(&policy->rwsem); | ||
1347 | } | 1344 | } |
1348 | 1345 | ||
1349 | /** | 1346 | /** |
@@ -1359,10 +1356,8 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | |||
1359 | if (!policy) | 1356 | if (!policy) |
1360 | return; | 1357 | return; |
1361 | 1358 | ||
1362 | if (cpu_online(cpu)) { | 1359 | if (cpu_online(cpu)) |
1363 | cpufreq_offline_prepare(cpu); | 1360 | cpufreq_offline(cpu); |
1364 | cpufreq_offline_finish(cpu); | ||
1365 | } | ||
1366 | 1361 | ||
1367 | cpumask_clear_cpu(cpu, policy->real_cpus); | 1362 | cpumask_clear_cpu(cpu, policy->real_cpus); |
1368 | remove_cpu_dev_symlink(policy, cpu); | 1363 | remove_cpu_dev_symlink(policy, cpu); |
@@ -1371,15 +1366,6 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | |||
1371 | cpufreq_policy_free(policy, true); | 1366 | cpufreq_policy_free(policy, true); |
1372 | } | 1367 | } |
1373 | 1368 | ||
1374 | static void handle_update(struct work_struct *work) | ||
1375 | { | ||
1376 | struct cpufreq_policy *policy = | ||
1377 | container_of(work, struct cpufreq_policy, update); | ||
1378 | unsigned int cpu = policy->cpu; | ||
1379 | pr_debug("handle_update for cpu %u called\n", cpu); | ||
1380 | cpufreq_update_policy(cpu); | ||
1381 | } | ||
1382 | |||
1383 | /** | 1369 | /** |
1384 | * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're | 1370 | * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're |
1385 | * in deep trouble. | 1371 | * in deep trouble. |
@@ -1542,6 +1528,7 @@ EXPORT_SYMBOL(cpufreq_generic_suspend); | |||
1542 | void cpufreq_suspend(void) | 1528 | void cpufreq_suspend(void) |
1543 | { | 1529 | { |
1544 | struct cpufreq_policy *policy; | 1530 | struct cpufreq_policy *policy; |
1531 | int ret; | ||
1545 | 1532 | ||
1546 | if (!cpufreq_driver) | 1533 | if (!cpufreq_driver) |
1547 | return; | 1534 | return; |
@@ -1552,7 +1539,11 @@ void cpufreq_suspend(void) | |||
1552 | pr_debug("%s: Suspending Governors\n", __func__); | 1539 | pr_debug("%s: Suspending Governors\n", __func__); |
1553 | 1540 | ||
1554 | for_each_active_policy(policy) { | 1541 | for_each_active_policy(policy) { |
1555 | if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) | 1542 | down_write(&policy->rwsem); |
1543 | ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); | ||
1544 | up_write(&policy->rwsem); | ||
1545 | |||
1546 | if (ret) | ||
1556 | pr_err("%s: Failed to stop governor for policy: %p\n", | 1547 | pr_err("%s: Failed to stop governor for policy: %p\n", |
1557 | __func__, policy); | 1548 | __func__, policy); |
1558 | else if (cpufreq_driver->suspend | 1549 | else if (cpufreq_driver->suspend |
@@ -1574,6 +1565,7 @@ suspend: | |||
1574 | void cpufreq_resume(void) | 1565 | void cpufreq_resume(void) |
1575 | { | 1566 | { |
1576 | struct cpufreq_policy *policy; | 1567 | struct cpufreq_policy *policy; |
1568 | int ret; | ||
1577 | 1569 | ||
1578 | if (!cpufreq_driver) | 1570 | if (!cpufreq_driver) |
1579 | return; | 1571 | return; |
@@ -1586,13 +1578,20 @@ void cpufreq_resume(void) | |||
1586 | pr_debug("%s: Resuming Governors\n", __func__); | 1578 | pr_debug("%s: Resuming Governors\n", __func__); |
1587 | 1579 | ||
1588 | for_each_active_policy(policy) { | 1580 | for_each_active_policy(policy) { |
1589 | if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) | 1581 | if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { |
1590 | pr_err("%s: Failed to resume driver: %p\n", __func__, | 1582 | pr_err("%s: Failed to resume driver: %p\n", __func__, |
1591 | policy); | 1583 | policy); |
1592 | else if (__cpufreq_governor(policy, CPUFREQ_GOV_START) | 1584 | } else { |
1593 | || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) | 1585 | down_write(&policy->rwsem); |
1594 | pr_err("%s: Failed to start governor for policy: %p\n", | 1586 | ret = cpufreq_governor(policy, CPUFREQ_GOV_START); |
1595 | __func__, policy); | 1587 | if (!ret) |
1588 | cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | ||
1589 | up_write(&policy->rwsem); | ||
1590 | |||
1591 | if (ret) | ||
1592 | pr_err("%s: Failed to start governor for policy: %p\n", | ||
1593 | __func__, policy); | ||
1594 | } | ||
1596 | } | 1595 | } |
1597 | 1596 | ||
1598 | /* | 1597 | /* |
@@ -1878,8 +1877,7 @@ __weak struct cpufreq_governor *cpufreq_fallback_governor(void) | |||
1878 | return NULL; | 1877 | return NULL; |
1879 | } | 1878 | } |
1880 | 1879 | ||
1881 | static int __cpufreq_governor(struct cpufreq_policy *policy, | 1880 | static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) |
1882 | unsigned int event) | ||
1883 | { | 1881 | { |
1884 | int ret; | 1882 | int ret; |
1885 | 1883 | ||
@@ -1913,21 +1911,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1913 | 1911 | ||
1914 | pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); | 1912 | pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); |
1915 | 1913 | ||
1916 | mutex_lock(&cpufreq_governor_lock); | ||
1917 | if ((policy->governor_enabled && event == CPUFREQ_GOV_START) | ||
1918 | || (!policy->governor_enabled | ||
1919 | && (event == CPUFREQ_GOV_LIMITS || event == CPUFREQ_GOV_STOP))) { | ||
1920 | mutex_unlock(&cpufreq_governor_lock); | ||
1921 | return -EBUSY; | ||
1922 | } | ||
1923 | |||
1924 | if (event == CPUFREQ_GOV_STOP) | ||
1925 | policy->governor_enabled = false; | ||
1926 | else if (event == CPUFREQ_GOV_START) | ||
1927 | policy->governor_enabled = true; | ||
1928 | |||
1929 | mutex_unlock(&cpufreq_governor_lock); | ||
1930 | |||
1931 | ret = policy->governor->governor(policy, event); | 1914 | ret = policy->governor->governor(policy, event); |
1932 | 1915 | ||
1933 | if (!ret) { | 1916 | if (!ret) { |
@@ -1935,14 +1918,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1935 | policy->governor->initialized++; | 1918 | policy->governor->initialized++; |
1936 | else if (event == CPUFREQ_GOV_POLICY_EXIT) | 1919 | else if (event == CPUFREQ_GOV_POLICY_EXIT) |
1937 | policy->governor->initialized--; | 1920 | policy->governor->initialized--; |
1938 | } else { | ||
1939 | /* Restore original values */ | ||
1940 | mutex_lock(&cpufreq_governor_lock); | ||
1941 | if (event == CPUFREQ_GOV_STOP) | ||
1942 | policy->governor_enabled = true; | ||
1943 | else if (event == CPUFREQ_GOV_START) | ||
1944 | policy->governor_enabled = false; | ||
1945 | mutex_unlock(&cpufreq_governor_lock); | ||
1946 | } | 1921 | } |
1947 | 1922 | ||
1948 | if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || | 1923 | if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || |
@@ -2097,7 +2072,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2097 | old_gov = policy->governor; | 2072 | old_gov = policy->governor; |
2098 | /* end old governor */ | 2073 | /* end old governor */ |
2099 | if (old_gov) { | 2074 | if (old_gov) { |
2100 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 2075 | ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
2101 | if (ret) { | 2076 | if (ret) { |
2102 | /* This can happen due to race with other operations */ | 2077 | /* This can happen due to race with other operations */ |
2103 | pr_debug("%s: Failed to Stop Governor: %s (%d)\n", | 2078 | pr_debug("%s: Failed to Stop Governor: %s (%d)\n", |
@@ -2105,10 +2080,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2105 | return ret; | 2080 | return ret; |
2106 | } | 2081 | } |
2107 | 2082 | ||
2108 | up_write(&policy->rwsem); | 2083 | ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); |
2109 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); | ||
2110 | down_write(&policy->rwsem); | ||
2111 | |||
2112 | if (ret) { | 2084 | if (ret) { |
2113 | pr_err("%s: Failed to Exit Governor: %s (%d)\n", | 2085 | pr_err("%s: Failed to Exit Governor: %s (%d)\n", |
2114 | __func__, old_gov->name, ret); | 2086 | __func__, old_gov->name, ret); |
@@ -2118,32 +2090,30 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2118 | 2090 | ||
2119 | /* start new governor */ | 2091 | /* start new governor */ |
2120 | policy->governor = new_policy->governor; | 2092 | policy->governor = new_policy->governor; |
2121 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); | 2093 | ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); |
2122 | if (!ret) { | 2094 | if (!ret) { |
2123 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); | 2095 | ret = cpufreq_governor(policy, CPUFREQ_GOV_START); |
2124 | if (!ret) | 2096 | if (!ret) |
2125 | goto out; | 2097 | goto out; |
2126 | 2098 | ||
2127 | up_write(&policy->rwsem); | 2099 | cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); |
2128 | __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); | ||
2129 | down_write(&policy->rwsem); | ||
2130 | } | 2100 | } |
2131 | 2101 | ||
2132 | /* new governor failed, so re-start old one */ | 2102 | /* new governor failed, so re-start old one */ |
2133 | pr_debug("starting governor %s failed\n", policy->governor->name); | 2103 | pr_debug("starting governor %s failed\n", policy->governor->name); |
2134 | if (old_gov) { | 2104 | if (old_gov) { |
2135 | policy->governor = old_gov; | 2105 | policy->governor = old_gov; |
2136 | if (__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) | 2106 | if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) |
2137 | policy->governor = NULL; | 2107 | policy->governor = NULL; |
2138 | else | 2108 | else |
2139 | __cpufreq_governor(policy, CPUFREQ_GOV_START); | 2109 | cpufreq_governor(policy, CPUFREQ_GOV_START); |
2140 | } | 2110 | } |
2141 | 2111 | ||
2142 | return ret; | 2112 | return ret; |
2143 | 2113 | ||
2144 | out: | 2114 | out: |
2145 | pr_debug("governor: change or update limits\n"); | 2115 | pr_debug("governor: change or update limits\n"); |
2146 | return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 2116 | return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); |
2147 | } | 2117 | } |
2148 | 2118 | ||
2149 | /** | 2119 | /** |
@@ -2210,11 +2180,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
2210 | break; | 2180 | break; |
2211 | 2181 | ||
2212 | case CPU_DOWN_PREPARE: | 2182 | case CPU_DOWN_PREPARE: |
2213 | cpufreq_offline_prepare(cpu); | 2183 | cpufreq_offline(cpu); |
2214 | break; | ||
2215 | |||
2216 | case CPU_POST_DEAD: | ||
2217 | cpufreq_offline_finish(cpu); | ||
2218 | break; | 2184 | break; |
2219 | 2185 | ||
2220 | case CPU_DOWN_FAILED: | 2186 | case CPU_DOWN_FAILED: |
@@ -2247,8 +2213,11 @@ static int cpufreq_boost_set_sw(int state) | |||
2247 | __func__); | 2213 | __func__); |
2248 | break; | 2214 | break; |
2249 | } | 2215 | } |
2216 | |||
2217 | down_write(&policy->rwsem); | ||
2250 | policy->user_policy.max = policy->max; | 2218 | policy->user_policy.max = policy->max; |
2251 | __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 2219 | cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); |
2220 | up_write(&policy->rwsem); | ||
2252 | } | 2221 | } |
2253 | } | 2222 | } |
2254 | 2223 | ||