|
@@ -353,6 +353,41 @@ void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
|
|
|
|
|
|
+void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
|
|
|
+ struct cpufreq_freqs *freqs)
|
|
|
+{
|
|
|
+wait:
|
|
|
+ wait_event(policy->transition_wait, !policy->transition_ongoing);
|
|
|
+
|
|
|
+ spin_lock(&policy->transition_lock);
|
|
|
+
|
|
|
+ if (unlikely(policy->transition_ongoing)) {
|
|
|
+ spin_unlock(&policy->transition_lock);
|
|
|
+ goto wait;
|
|
|
+ }
|
|
|
+
|
|
|
+ policy->transition_ongoing = true;
|
|
|
+
|
|
|
+ spin_unlock(&policy->transition_lock);
|
|
|
+
|
|
|
+ cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin);
|
|
|
+
|
|
|
+void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
|
|
|
+ struct cpufreq_freqs *freqs, int transition_failed)
|
|
|
+{
|
|
|
+ if (unlikely(WARN_ON(!policy->transition_ongoing)))
|
|
|
+ return;
|
|
|
+
|
|
|
+ cpufreq_notify_post_transition(policy, freqs, transition_failed);
|
|
|
+
|
|
|
+ policy->transition_ongoing = false;
|
|
|
+
|
|
|
+ wake_up(&policy->transition_wait);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(cpufreq_freq_transition_end);
|
|
|
+
|
|
|
|
|
|
/*********************************************************************
|
|
|
* SYSFS INTERFACE *
|
|
@@ -985,6 +1020,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
|
|
|
|
|
|
INIT_LIST_HEAD(&policy->policy_list);
|
|
|
init_rwsem(&policy->rwsem);
|
|
|
+ spin_lock_init(&policy->transition_lock);
|
|
|
+ init_waitqueue_head(&policy->transition_wait);
|
|
|
|
|
|
return policy;
|
|
|
|