aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-10-04 05:17:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:30 -0400
commitb4dfdbb3c707474a2254c5b4d7e62be31a4b7da9 (patch)
tree20558266428cb904c4ffc660647cfdb7e7abeae5 /drivers/cpufreq
parente6a92013ba458804161c0c5b6d134d82204dc233 (diff)
[PATCH] cpufreq: make the transition_notifier chain use SRCU
This patch (as762) changes the cpufreq_transition_notifier_list from a blocking_notifier_head to an srcu_notifier_head. This will prevent errors caused attempting to call down_read() to access the notifier chain at a time when interrupts must remain disabled, during system suspend. It's not clear to me whether this is really necessary; perhaps the chain could be made into an atomic_notifier. However a couple of the callout routines do use blocking operations, so this approach seems safer. The head of the notifier chain needs to be initialized before use; this is done by an __init routine at core_initcall time. If this turns out not to be a good choice, it can easily be changed. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Cc: "Paul E. McKenney" <paulmck@us.ibm.com> Cc: Jesse Brandeburg <jesse.brandeburg@gmail.com> Cc: Dave Jones <davej@codemonkey.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 2caaf71d80c8..86e69b7f9122 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -52,8 +52,14 @@ static void handle_update(void *data);
52 * The mutex locks both lists. 52 * The mutex locks both lists.
53 */ 53 */
54static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); 54static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
55static BLOCKING_NOTIFIER_HEAD(cpufreq_transition_notifier_list); 55static struct srcu_notifier_head cpufreq_transition_notifier_list;
56 56
57static int __init init_cpufreq_transition_notifier_list(void)
58{
59 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
60 return 0;
61}
62core_initcall(init_cpufreq_transition_notifier_list);
57 63
58static LIST_HEAD(cpufreq_governor_list); 64static LIST_HEAD(cpufreq_governor_list);
59static DEFINE_MUTEX (cpufreq_governor_mutex); 65static DEFINE_MUTEX (cpufreq_governor_mutex);
@@ -262,14 +268,14 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
262 freqs->old = policy->cur; 268 freqs->old = policy->cur;
263 } 269 }
264 } 270 }
265 blocking_notifier_call_chain(&cpufreq_transition_notifier_list, 271 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
266 CPUFREQ_PRECHANGE, freqs); 272 CPUFREQ_PRECHANGE, freqs);
267 adjust_jiffies(CPUFREQ_PRECHANGE, freqs); 273 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
268 break; 274 break;
269 275
270 case CPUFREQ_POSTCHANGE: 276 case CPUFREQ_POSTCHANGE:
271 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); 277 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
272 blocking_notifier_call_chain(&cpufreq_transition_notifier_list, 278 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
273 CPUFREQ_POSTCHANGE, freqs); 279 CPUFREQ_POSTCHANGE, freqs);
274 if (likely(policy) && likely(policy->cpu == freqs->cpu)) 280 if (likely(policy) && likely(policy->cpu == freqs->cpu))
275 policy->cur = freqs->new; 281 policy->cur = freqs->new;
@@ -1049,7 +1055,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
1049 freqs.old = cpu_policy->cur; 1055 freqs.old = cpu_policy->cur;
1050 freqs.new = cur_freq; 1056 freqs.new = cur_freq;
1051 1057
1052 blocking_notifier_call_chain(&cpufreq_transition_notifier_list, 1058 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
1053 CPUFREQ_SUSPENDCHANGE, &freqs); 1059 CPUFREQ_SUSPENDCHANGE, &freqs);
1054 adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); 1060 adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
1055 1061
@@ -1130,7 +1136,7 @@ static int cpufreq_resume(struct sys_device * sysdev)
1130 freqs.old = cpu_policy->cur; 1136 freqs.old = cpu_policy->cur;
1131 freqs.new = cur_freq; 1137 freqs.new = cur_freq;
1132 1138
1133 blocking_notifier_call_chain( 1139 srcu_notifier_call_chain(
1134 &cpufreq_transition_notifier_list, 1140 &cpufreq_transition_notifier_list,
1135 CPUFREQ_RESUMECHANGE, &freqs); 1141 CPUFREQ_RESUMECHANGE, &freqs);
1136 adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); 1142 adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
@@ -1176,7 +1182,7 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1176 1182
1177 switch (list) { 1183 switch (list) {
1178 case CPUFREQ_TRANSITION_NOTIFIER: 1184 case CPUFREQ_TRANSITION_NOTIFIER:
1179 ret = blocking_notifier_chain_register( 1185 ret = srcu_notifier_chain_register(
1180 &cpufreq_transition_notifier_list, nb); 1186 &cpufreq_transition_notifier_list, nb);
1181 break; 1187 break;
1182 case CPUFREQ_POLICY_NOTIFIER: 1188 case CPUFREQ_POLICY_NOTIFIER:
@@ -1208,7 +1214,7 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1208 1214
1209 switch (list) { 1215 switch (list) {
1210 case CPUFREQ_TRANSITION_NOTIFIER: 1216 case CPUFREQ_TRANSITION_NOTIFIER:
1211 ret = blocking_notifier_chain_unregister( 1217 ret = srcu_notifier_chain_unregister(
1212 &cpufreq_transition_notifier_list, nb); 1218 &cpufreq_transition_notifier_list, nb);
1213 break; 1219 break;
1214 case CPUFREQ_POLICY_NOTIFIER: 1220 case CPUFREQ_POLICY_NOTIFIER: