|
@@ -156,6 +156,7 @@ static void speedstep_set_state(unsigned int state)
|
|
|
return;
|
|
|
|
|
|
/* Disable IRQs */
|
|
|
+ preempt_disable();
|
|
|
local_irq_save(flags);
|
|
|
|
|
|
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
|
|
@@ -166,9 +167,19 @@ static void speedstep_set_state(unsigned int state)
|
|
|
|
|
|
do {
|
|
|
if (retry) {
|
|
|
+ /*
|
|
|
+ * We need to enable interrupts, otherwise the blockage
|
|
|
+ * won't resolve.
|
|
|
+ *
|
|
|
+ * We disable preemption so that other processes don't
|
|
|
+ * run. If other processes were running, they could
|
|
|
+ * submit more DMA requests, making the blockage worse.
|
|
|
+ */
|
|
|
pr_debug("retry %u, previous result %u, waiting...\n",
|
|
|
retry, result);
|
|
|
+ local_irq_enable();
|
|
|
mdelay(retry * 50);
|
|
|
+ local_irq_disable();
|
|
|
}
|
|
|
retry++;
|
|
|
__asm__ __volatile__(
|
|
@@ -185,6 +196,7 @@ static void speedstep_set_state(unsigned int state)
|
|
|
|
|
|
/* enable IRQs */
|
|
|
local_irq_restore(flags);
|
|
|
+ preempt_enable();
|
|
|
|
|
|
if (new_state == state)
|
|
|
pr_debug("change to %u MHz succeeded after %u tries "
|