aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/time.c39
-rw-r--r--drivers/macintosh/via-pmu.c48
-rw-r--r--include/asm-powerpc/machdep.h13
3 files changed, 58 insertions, 42 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 85cf317c9069..5cd3db5cae41 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -629,6 +629,45 @@ void wakeup_decrementer(void)
629 set_dec(ticks); 629 set_dec(ticks);
630} 630}
631 631
632#ifdef CONFIG_SUSPEND
633void generic_suspend_disable_irqs(void)
634{
635 preempt_disable();
636
637 /* Disable the decrementer, so that it doesn't interfere
638 * with suspending.
639 */
640
641 set_dec(0x7fffffff);
642 local_irq_disable();
643 set_dec(0x7fffffff);
644}
645
646void generic_suspend_enable_irqs(void)
647{
648 wakeup_decrementer();
649
650 local_irq_enable();
651 preempt_enable();
652}
653
654/* Overrides the weak version in kernel/power/main.c */
655void arch_suspend_disable_irqs(void)
656{
657 if (ppc_md.suspend_disable_irqs)
658 ppc_md.suspend_disable_irqs();
659 generic_suspend_disable_irqs();
660}
661
662/* Overrides the weak version in kernel/power/main.c */
663void arch_suspend_enable_irqs(void)
664{
665 generic_suspend_enable_irqs();
666 if (ppc_md.suspend_enable_irqs)
667 ppc_md.suspend_enable_irqs();
668}
669#endif
670
632#ifdef CONFIG_SMP 671#ifdef CONFIG_SMP
633void __init smp_space_timers(unsigned int max_cpus) 672void __init smp_space_timers(unsigned int max_cpus)
634{ 673{
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 8f98257e6a15..7e77ac7e3705 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -197,12 +197,6 @@ static int proc_read_options(char *page, char **start, off_t off,
197static int proc_write_options(struct file *file, const char __user *buffer, 197static int proc_write_options(struct file *file, const char __user *buffer,
198 unsigned long count, void *data); 198 unsigned long count, void *data);
199 199
200#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
201static void powerbook_sleep_init_3400(void);
202#else
203#define powerbook_sleep_init_3400() do { } while (0)
204#endif
205
206#ifdef CONFIG_ADB 200#ifdef CONFIG_ADB
207struct adb_driver via_pmu_driver = { 201struct adb_driver via_pmu_driver = {
208 "PMU", 202 "PMU",
@@ -450,10 +444,6 @@ static int __init via_pmu_start(void)
450 pmu_poll(); 444 pmu_poll();
451 } while (pmu_state != idle); 445 } while (pmu_state != idle);
452 446
453 /* Do allocations and ioremaps that will be needed for sleep */
454 if (pmu_kind == PMU_OHARE_BASED)
455 powerbook_sleep_init_3400();
456
457 return 0; 447 return 0;
458} 448}
459 449
@@ -2168,13 +2158,7 @@ pmu_release(struct inode *inode, struct file *file)
2168} 2158}
2169 2159
2170#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) 2160#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2171/* 2161static void pmac_suspend_disable_irqs(void)
2172 * overrides the weak arch_suspend_disable_irqs in kernel/power/main.c
2173 *
2174 * XXX: Once Scott Wood's patch is merged, this needs to use the ppc_md
2175 * hooks that patch adds!
2176 */
2177void arch_suspend_disable_irqs(void)
2178{ 2162{
2179#ifdef CONFIG_PMAC_BACKLIGHT 2163#ifdef CONFIG_PMAC_BACKLIGHT
2180 /* Tell backlight code not to muck around with the chip anymore */ 2164 /* Tell backlight code not to muck around with the chip anymore */
@@ -2184,18 +2168,6 @@ void arch_suspend_disable_irqs(void)
2184 /* Call platform functions marked "on sleep" */ 2168 /* Call platform functions marked "on sleep" */
2185 pmac_pfunc_i2c_suspend(); 2169 pmac_pfunc_i2c_suspend();
2186 pmac_pfunc_base_suspend(); 2170 pmac_pfunc_base_suspend();
2187
2188 /* Stop preemption */
2189 preempt_disable();
2190
2191 /* Make sure the decrementer won't interrupt us */
2192 asm volatile("mtdec %0" : : "r" (0x7fffffff));
2193 /* Make sure any pending DEC interrupt occurring while we did
2194 * the above didn't re-enable the DEC */
2195 mb();
2196 asm volatile("mtdec %0" : : "r" (0x7fffffff));
2197
2198 local_irq_disable();
2199} 2171}
2200 2172
2201static int powerbook_sleep(suspend_state_t state) 2173static int powerbook_sleep(suspend_state_t state)
@@ -2244,25 +2216,13 @@ static int powerbook_sleep(suspend_state_t state)
2244 return 0; 2216 return 0;
2245} 2217}
2246 2218
2247/* 2219static void pmac_suspend_enable_irqs(void)
2248 * overrides the weak arch_suspend_enable_irqs in kernel/power/main.c
2249 *
2250 * XXX: Once Scott Wood's patch is merged, this needs to use the ppc_md
2251 * hooks that patch adds!
2252 */
2253void arch_suspend_enable_irqs(void)
2254{ 2220{
2255 /* Force a poll of ADB interrupts */ 2221 /* Force a poll of ADB interrupts */
2256 adb_int_pending = 1; 2222 adb_int_pending = 1;
2257 via_pmu_interrupt(0, NULL); 2223 via_pmu_interrupt(0, NULL);
2258 2224
2259 /* Restart jiffies & scheduling */
2260 wakeup_decrementer();
2261
2262 /* Re-enable local CPU interrupts */
2263 local_irq_enable();
2264 mdelay(10); 2225 mdelay(10);
2265 preempt_enable();
2266 2226
2267 /* Call platform functions marked "on wake" */ 2227 /* Call platform functions marked "on wake" */
2268 pmac_pfunc_base_resume(); 2228 pmac_pfunc_base_resume();
@@ -2282,6 +2242,10 @@ static struct platform_suspend_ops pmu_pm_ops = {
2282 2242
2283static int register_pmu_pm_ops(void) 2243static int register_pmu_pm_ops(void)
2284{ 2244{
2245 if (pmu_kind == PMU_OHARE_BASED)
2246 powerbook_sleep_init_3400();
2247 ppc_md.suspend_disable_irqs = pmac_suspend_disable_irqs;
2248 ppc_md.suspend_enable_irqs = pmac_suspend_enable_irqs;
2285 suspend_set_ops(&pmu_pm_ops); 2249 suspend_set_ops(&pmu_pm_ops);
2286 2250
2287 return 0; 2251 return 0;
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 79c704ed5381..0872ec228c1e 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -251,6 +251,16 @@ struct machdep_calls {
251 */ 251 */
252 void (*machine_kexec)(struct kimage *image); 252 void (*machine_kexec)(struct kimage *image);
253#endif /* CONFIG_KEXEC */ 253#endif /* CONFIG_KEXEC */
254
255#ifdef CONFIG_SUSPEND
256 /* These are called to disable and enable, respectively, IRQs when
257 * entering a suspend state. If NULL, then the generic versions
258 * will be called. The generic versions disable/enable the
259 * decrementer along with interrupts.
260 */
261 void (*suspend_disable_irqs)(void);
262 void (*suspend_enable_irqs)(void);
263#endif
254}; 264};
255 265
256extern void power4_idle(void); 266extern void power4_idle(void);
@@ -347,5 +357,8 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
347#define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7) 357#define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7)
348#define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s) 358#define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s)
349 359
360void generic_suspend_disable_irqs(void);
361void generic_suspend_enable_irqs(void);
362
350#endif /* __KERNEL__ */ 363#endif /* __KERNEL__ */
351#endif /* _ASM_POWERPC_MACHDEP_H */ 364#endif /* _ASM_POWERPC_MACHDEP_H */