diff options
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index bb63347f6af1..d8fc395af773 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -250,6 +250,51 @@ void cpufreq_cpu_put(struct cpufreq_policy *policy) | |||
| 250 | } | 250 | } |
| 251 | EXPORT_SYMBOL_GPL(cpufreq_cpu_put); | 251 | EXPORT_SYMBOL_GPL(cpufreq_cpu_put); |
| 252 | 252 | ||
| 253 | /** | ||
| 254 | * cpufreq_cpu_release - Unlock a policy and decrement its usage counter. | ||
| 255 | * @policy: cpufreq policy returned by cpufreq_cpu_acquire(). | ||
| 256 | */ | ||
| 257 | static void cpufreq_cpu_release(struct cpufreq_policy *policy) | ||
| 258 | { | ||
| 259 | if (WARN_ON(!policy)) | ||
| 260 | return; | ||
| 261 | |||
| 262 | lockdep_assert_held(&policy->rwsem); | ||
| 263 | |||
| 264 | up_write(&policy->rwsem); | ||
| 265 | |||
| 266 | cpufreq_cpu_put(policy); | ||
| 267 | } | ||
| 268 | |||
| 269 | /** | ||
| 270 | * cpufreq_cpu_acquire - Find policy for a CPU, mark it as busy and lock it. | ||
| 271 | * @cpu: CPU to find the policy for. | ||
| 272 | * | ||
| 273 | * Call cpufreq_cpu_get() to get a reference on the cpufreq policy for @cpu and | ||
| 274 | * if the policy returned by it is not NULL, acquire its rwsem for writing. | ||
| 275 | * Return the policy if it is active or release it and return NULL otherwise. | ||
| 276 | * | ||
| 277 | * The policy returned by this function has to be released with the help of | ||
| 278 | * cpufreq_cpu_release() in order to release its rwsem and balance its usage | ||
| 279 | * counter properly. | ||
| 280 | */ | ||
| 281 | static struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu) | ||
| 282 | { | ||
| 283 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | ||
| 284 | |||
| 285 | if (!policy) | ||
| 286 | return NULL; | ||
| 287 | |||
| 288 | down_write(&policy->rwsem); | ||
| 289 | |||
| 290 | if (policy_is_inactive(policy)) { | ||
| 291 | cpufreq_cpu_release(policy); | ||
| 292 | return NULL; | ||
| 293 | } | ||
| 294 | |||
| 295 | return policy; | ||
| 296 | } | ||
| 297 | |||
| 253 | /********************************************************************* | 298 | /********************************************************************* |
| 254 | * EXTERNALLY AFFECTING FREQUENCY CHANGES * | 299 | * EXTERNALLY AFFECTING FREQUENCY CHANGES * |
| 255 | *********************************************************************/ | 300 | *********************************************************************/ |
| @@ -2337,17 +2382,12 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
| 2337 | */ | 2382 | */ |
| 2338 | void cpufreq_update_policy(unsigned int cpu) | 2383 | void cpufreq_update_policy(unsigned int cpu) |
| 2339 | { | 2384 | { |
| 2340 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | 2385 | struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu); |
| 2341 | struct cpufreq_policy new_policy; | 2386 | struct cpufreq_policy new_policy; |
| 2342 | 2387 | ||
| 2343 | if (!policy) | 2388 | if (!policy) |
| 2344 | return; | 2389 | return; |
| 2345 | 2390 | ||
| 2346 | down_write(&policy->rwsem); | ||
| 2347 | |||
| 2348 | if (policy_is_inactive(policy)) | ||
| 2349 | goto unlock; | ||
| 2350 | |||
| 2351 | /* | 2391 | /* |
| 2352 | * BIOS might change freq behind our back | 2392 | * BIOS might change freq behind our back |
| 2353 | * -> ask driver for current freq and notify governors about a change | 2393 | * -> ask driver for current freq and notify governors about a change |
| @@ -2364,9 +2404,7 @@ void cpufreq_update_policy(unsigned int cpu) | |||
| 2364 | cpufreq_set_policy(policy, &new_policy); | 2404 | cpufreq_set_policy(policy, &new_policy); |
| 2365 | 2405 | ||
| 2366 | unlock: | 2406 | unlock: |
| 2367 | up_write(&policy->rwsem); | 2407 | cpufreq_cpu_release(policy); |
| 2368 | |||
| 2369 | cpufreq_cpu_put(policy); | ||
| 2370 | } | 2408 | } |
| 2371 | EXPORT_SYMBOL(cpufreq_update_policy); | 2409 | EXPORT_SYMBOL(cpufreq_update_policy); |
| 2372 | 2410 | ||
