aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/cpufreq.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a517da996aaf..bfe82b63875f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -365,6 +365,18 @@ static void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
365void cpufreq_freq_transition_begin(struct cpufreq_policy *policy, 365void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
366 struct cpufreq_freqs *freqs) 366 struct cpufreq_freqs *freqs)
367{ 367{
368
369 /*
370 * Catch double invocations of _begin() which lead to self-deadlock.
371 * ASYNC_NOTIFICATION drivers are left out because the cpufreq core
372 * doesn't invoke _begin() on their behalf, and hence the chances of
373 * double invocations are very low. Moreover, there are scenarios
374 * where these checks can emit false-positive warnings in these
375 * drivers; so we avoid that by skipping them altogether.
376 */
377 WARN_ON(!(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION)
378 && current == policy->transition_task);
379
368wait: 380wait:
369 wait_event(policy->transition_wait, !policy->transition_ongoing); 381 wait_event(policy->transition_wait, !policy->transition_ongoing);
370 382
@@ -376,6 +388,7 @@ wait:
376 } 388 }
377 389
378 policy->transition_ongoing = true; 390 policy->transition_ongoing = true;
391 policy->transition_task = current;
379 392
380 spin_unlock(&policy->transition_lock); 393 spin_unlock(&policy->transition_lock);
381 394
@@ -392,6 +405,7 @@ void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
392 cpufreq_notify_post_transition(policy, freqs, transition_failed); 405 cpufreq_notify_post_transition(policy, freqs, transition_failed);
393 406
394 policy->transition_ongoing = false; 407 policy->transition_ongoing = false;
408 policy->transition_task = NULL;
395 409
396 wake_up(&policy->transition_wait); 410 wake_up(&policy->transition_wait);
397} 411}