[ARM] pxa: fix resume failure by saving/restoring IPRx registers
authorHaojian Zhuang <haojian.zhuang@marvell.com>
Mon, 2 Nov 2009 19:02:21 +0000 (14:02 -0500)
committerEric Miao <eric.y.miao@gmail.com>
Tue, 3 Nov 2009 04:00:56 +0000 (12:00 +0800)
Since interrupt handler is changed to use interrupt priority, we also need
to save and restore these interrupt controller registers in suspend/resume
routine.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Tested-by: Daniel Mack <daniel@caiaq.de>
Tested-by: Pavel Machek <pavel@ucw.cz>
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
arch/arm/mach-pxa/irq.c

index d694ce289668ecf4a3e1bdb71712b9b9ad6b30bd..6112af431fa4f933b14869fc5cf4a1904f56ce06 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "generic.h"
 
+#define MAX_INTERNAL_IRQS      128
+
 #define IRQ_BIT(n)     (((n) - PXA_IRQ(0)) & 0x1f)
 #define _ICMR(n)       (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
 #define _ICLR(n)       (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
@@ -122,6 +124,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
 {
        int irq, i;
 
+       BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
+
        pxa_internal_irq_nr = irq_nr;
 
        for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
@@ -149,7 +153,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
 }
 
 #ifdef CONFIG_PM
-static unsigned long saved_icmr[2];
+static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
+static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
 
 static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
 {
@@ -159,6 +164,8 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
                saved_icmr[i] = _ICMR(irq);
                _ICMR(irq) = 0;
        }
+       for (i = 0; i < pxa_internal_irq_nr; i++)
+               saved_ipr[i] = IPR(i);
 
        return 0;
 }
@@ -171,6 +178,8 @@ static int pxa_irq_resume(struct sys_device *dev)
                _ICMR(irq) = saved_icmr[i];
                _ICLR(irq) = 0;
        }
+       for (i = 0; i < pxa_internal_irq_nr; i++)
+               IPR(i) = saved_ipr[i];
 
        ICCR = 1;
        return 0;