aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-05-27 15:53:02 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-28 14:14:01 -0400
commitb16eeb47292597a8bf3ad53fdaf1f727f57bd8e4 (patch)
tree93325bd2b4dd53e3064408c997f626b565c4423f
parent49f384b82b03416dd7e4fc77847a959fe3247362 (diff)
[PATCH] ppc32: Fix cpufreq vs. sleep issue
Recent kernels occasionally trigger a PMU timeout on some mac laptops, typically on wakeup from sleep. This seem to be caused by either a too big latency caused by the cpufreq switch on wakeup from sleep or by an interrupt beeing lost due to the reset of the interrupt controller done during wakeup. This patch makes that code more robust by stopping PMU auto poll activity around cpufreq changes on machines that use the PMU for such changes (long latency switching involving a CPU hard reset and flush of all caches) and by removing the reset of the open pic interrupt controller on wakeup (that can cause the loss of an interrupt and Darwin doesn't do it, so it must not be necessary). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c4
-rw-r--r--arch/ppc/syslib/open_pic.c4
-rw-r--r--drivers/macintosh/via-pmu.c8
3 files changed, 9 insertions, 7 deletions
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index 48e482c8bd0d..937f46df711e 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -271,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
271#ifdef DEBUG_FREQ 271#ifdef DEBUG_FREQ
272 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); 272 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
273#endif 273#endif
274 pmu_suspend();
275
274 /* Disable all interrupt sources on openpic */ 276 /* Disable all interrupt sources on openpic */
275 pic_prio = openpic_get_priority(); 277 pic_prio = openpic_get_priority();
276 openpic_set_priority(0xf); 278 openpic_set_priority(0xf);
@@ -345,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
345 debug_calc_bogomips(); 347 debug_calc_bogomips();
346#endif 348#endif
347 349
350 pmu_resume();
351
348 preempt_enable(); 352 preempt_enable();
349 353
350 return 0; 354 return 0;
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 9d4ed68b5804..000ba47c67cb 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void)
275} 275}
276#endif 276#endif
277 277
278#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM) 278#if defined(CONFIG_EPIC_SERIAL_MODE)
279static void openpic_reset(void) 279static void openpic_reset(void)
280{ 280{
281 openpic_setfield(&OpenPIC->Global.Global_Configuration0, 281 openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -993,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev)
993 return 0; 993 return 0;
994 } 994 }
995 995
996 openpic_reset();
997
998 /* OpenPIC sometimes seem to need some time to be fully back up... */ 996 /* OpenPIC sometimes seem to need some time to be fully back up... */
999 do { 997 do {
1000 openpic_set_spurious(OPENPIC_VEC_SPURIOUS); 998 openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index e654aa5eecd4..bb9f4044c74d 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2421,7 +2421,7 @@ pmac_wakeup_devices(void)
2421 2421
2422 /* Re-enable local CPU interrupts */ 2422 /* Re-enable local CPU interrupts */
2423 local_irq_enable(); 2423 local_irq_enable();
2424 mdelay(100); 2424 mdelay(10);
2425 preempt_enable(); 2425 preempt_enable();
2426 2426
2427 /* Re-enable clock spreading on some machines */ 2427 /* Re-enable clock spreading on some machines */
@@ -2549,7 +2549,9 @@ powerbook_sleep_Core99(void)
2549 return ret; 2549 return ret;
2550 } 2550 }
2551 2551
2552 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); 2552 /* Stop environment and ADB interrupts */
2553 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
2554 pmu_wait_complete(&req);
2553 2555
2554 /* Tell PMU what events will wake us up */ 2556 /* Tell PMU what events will wake us up */
2555 pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, 2557 pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS,
@@ -2611,8 +2613,6 @@ powerbook_sleep_Core99(void)
2611 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); 2613 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
2612 pmu_wait_complete(&req); 2614 pmu_wait_complete(&req);
2613 2615
2614 printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
2615
2616 pmac_wakeup_devices(); 2616 pmac_wakeup_devices();
2617 2617
2618 return 0; 2618 return 0;