diff options
-rw-r--r-- | arch/powerpc/kernel/time.c | 39 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu.c | 48 | ||||
-rw-r--r-- | include/asm-powerpc/machdep.h | 13 |
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 | ||
633 | void 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 | |||
646 | void 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 */ | ||
655 | void 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 */ | ||
663 | void 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 |
633 | void __init smp_space_timers(unsigned int max_cpus) | 672 | void __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, | |||
197 | static int proc_write_options(struct file *file, const char __user *buffer, | 197 | static 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) | ||
201 | static 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 |
207 | struct adb_driver via_pmu_driver = { | 201 | struct 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 | /* | 2161 | static 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 | */ | ||
2177 | void 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 | ||
2201 | static int powerbook_sleep(suspend_state_t state) | 2173 | static 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 | /* | 2219 | static 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 | */ | ||
2253 | void 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 | ||
2283 | static int register_pmu_pm_ops(void) | 2243 | static 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 | ||
256 | extern void power4_idle(void); | 266 | extern 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 | ||
360 | void generic_suspend_disable_irqs(void); | ||
361 | void generic_suspend_enable_irqs(void); | ||
362 | |||
350 | #endif /* __KERNEL__ */ | 363 | #endif /* __KERNEL__ */ |
351 | #endif /* _ASM_POWERPC_MACHDEP_H */ | 364 | #endif /* _ASM_POWERPC_MACHDEP_H */ |