aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/speedstep-smi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/speedstep-smi.c')
-rw-r--r--drivers/cpufreq/speedstep-smi.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index 5fc96d5d656b..819229e824fb 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -156,6 +156,7 @@ static void speedstep_set_state(unsigned int state)
156 return; 156 return;
157 157
158 /* Disable IRQs */ 158 /* Disable IRQs */
159 preempt_disable();
159 local_irq_save(flags); 160 local_irq_save(flags);
160 161
161 command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); 162 command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
@@ -166,9 +167,19 @@ static void speedstep_set_state(unsigned int state)
166 167
167 do { 168 do {
168 if (retry) { 169 if (retry) {
170 /*
171 * We need to enable interrupts, otherwise the blockage
172 * won't resolve.
173 *
174 * We disable preemption so that other processes don't
175 * run. If other processes were running, they could
176 * submit more DMA requests, making the blockage worse.
177 */
169 pr_debug("retry %u, previous result %u, waiting...\n", 178 pr_debug("retry %u, previous result %u, waiting...\n",
170 retry, result); 179 retry, result);
180 local_irq_enable();
171 mdelay(retry * 50); 181 mdelay(retry * 50);
182 local_irq_disable();
172 } 183 }
173 retry++; 184 retry++;
174 __asm__ __volatile__( 185 __asm__ __volatile__(
@@ -185,6 +196,7 @@ static void speedstep_set_state(unsigned int state)
185 196
186 /* enable IRQs */ 197 /* enable IRQs */
187 local_irq_restore(flags); 198 local_irq_restore(flags);
199 preempt_enable();
188 200
189 if (new_state == state) 201 if (new_state == state)
190 pr_debug("change to %u MHz succeeded after %u tries " 202 pr_debug("change to %u MHz succeeded after %u tries "