[PATCH 1/3] Implement arch disable/enable irq hooks.

Subsystems: linux for powerpc (32-bit and 64-bit), the rest

STALE6937d

4 messages, 3 authors, 2007-09-12 · open the first message on its own page

[PATCH 1/3] Implement arch disable/enable irq hooks.

From: Scott Wood <hidden>
Date: 2007-09-05 22:06:16

These hooks ensure that a decrementer interrupt is not pending when
suspending; otherwise, problems may occur.  For example, with deep sleep
on the 831x, a pending decrementer will cause a system freeze because the
SoC thinks the decrementer interrupt would have woken the system, but the
core must have interrupts disabled due to the setup required for deep
sleep.

Signed-off-by: Scott Wood <redacted>
---
 arch/powerpc/kernel/time.c    |   41 +++++++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/machdep.h |   13 +++++++++++++
 2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index b5944d8..bf7c4d3 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -728,6 +728,47 @@ void wakeup_decrementer(void)
 	set_dec(ticks);
 }
 
+#ifdef CONFIG_SUSPEND
+void generic_suspend_disable_irqs(void)
+{
+	preempt_disable();
+
+	/* Disable the decrementer, so that it doesn't interfere
+	 * with suspending.
+	 */
+
+	set_dec(0x7fffffff);
+	local_irq_disable();
+	set_dec(0x7fffffff);
+}
+
+void generic_suspend_enable_irqs(void)
+{
+	wakeup_decrementer();
+
+	local_irq_enable();
+	preempt_enable();
+}
+
+/* Overrides the weak version in kernel/power/main.c */
+void arch_suspend_disable_irqs(void)
+{
+	if (ppc_md.suspend_disable_irqs)
+		ppc_md.suspend_disable_irqs();
+	else
+		generic_suspend_disable_irqs();
+}
+
+/* Overrides the weak version in kernel/power/main.c */
+void arch_suspend_enable_irqs(void)
+{
+	if (ppc_md.suspend_enable_irqs)
+		ppc_md.suspend_enable_irqs();
+	else
+		generic_suspend_enable_irqs();
+}
+#endif
+
 #ifdef CONFIG_SMP
 void __init smp_space_timers(unsigned int max_cpus)
 {
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 71c6e7e..7d6d2cb 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -253,6 +253,16 @@ struct machdep_calls {
 	 */
 	void (*machine_kexec)(struct kimage *image);
 #endif /* CONFIG_KEXEC */
+
+#ifdef CONFIG_SUSPEND
+	/* These are called to disable and enable, respectively, IRQs when
+	 * entering a suspend state.  If NULL, then the generic versions
+	 * will be called.  The generic versions disable/enable the
+	 * decrementer along with interrupts.
+	 */
+	void (*suspend_disable_irqs)(void);
+	void (*suspend_enable_irqs)(void);
+#endif
 };
 
 extern void power4_idle(void);
@@ -326,5 +336,8 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
 		ppc_md.log_error(buf, err_type, fatal);
 }
 
+void generic_suspend_disable_irqs(void);
+void generic_suspend_enable_irqs(void);
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_MACHDEP_H */
-- 
1.5.3

Re: [PATCH 1/3] Implement arch disable/enable irq hooks.

From: Paul Mackerras <hidden>
Date: 2007-09-11 21:16:28

Scott Wood writes:
These hooks ensure that a decrementer interrupt is not pending when
suspending; otherwise, problems may occur.  For example, with deep sleep
on the 831x, a pending decrementer will cause a system freeze because the
SoC thinks the decrementer interrupt would have woken the system, but the
core must have interrupts disabled due to the setup required for deep
sleep.
+	set_dec(0x7fffffff);
+	local_irq_disable();
+	set_dec(0x7fffffff);
It might be better to use hard_irq_disable rather than
local_irq_disable here, since I think we will need that on 64-bit (and
on 32-bit if we ever do lazy irq disabling there).
+/* Overrides the weak version in kernel/power/main.c */
+void arch_suspend_disable_irqs(void)
+{
+	if (ppc_md.suspend_disable_irqs)
+		ppc_md.suspend_disable_irqs();
+	else
+		generic_suspend_disable_irqs();
Any particular reason why we need a ppc_md hook here?  Do we expect
some platform to need to do something different?

Paul.

Re: [PATCH 1/3] Implement arch disable/enable irq hooks.

From: Scott Wood <hidden>
Date: 2007-09-11 21:33:54

Paul Mackerras wrote:
It might be better to use hard_irq_disable rather than
local_irq_disable here, since I think we will need that on 64-bit (and
on 32-bit if we ever do lazy irq disabling there).
OK.
quoted
+/* Overrides the weak version in kernel/power/main.c */
+void arch_suspend_disable_irqs(void)
+{
+	if (ppc_md.suspend_disable_irqs)
+		ppc_md.suspend_disable_irqs();
+	else
+		generic_suspend_disable_irqs();
Any particular reason why we need a ppc_md hook here?  Do we expect
some platform to need to do something different?
Not that I know the details of, but others requested it.

-Scott

Re: [PATCH 1/3] Implement arch disable/enable irq hooks.

From: Johannes Berg <johannes@sipsolutions.net>
Date: 2007-09-12 08:22:00

On Wed, 2007-09-12 at 07:16 +1000, Paul Mackerras wrote:
quoted
+/* Overrides the weak version in kernel/power/main.c */
+void arch_suspend_disable_irqs(void)
+{
+	if (ppc_md.suspend_disable_irqs)
+		ppc_md.suspend_disable_irqs();
+	else
+		generic_suspend_disable_irqs();
Any particular reason why we need a ppc_md hook here?  Do we expect
some platform to need to do something different?
Yes, we need to hook into these for the PMU and platform functions on
powermac. Once I get to convert that to the generic infrastructure...

johannes
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help