diff options
author | Rajendra Nayak <rnayak@ti.com> | 2008-09-26 08:18:20 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-11 17:40:12 -0500 |
commit | 0addd61bc2028842bdcbd92c622d1110fc29c5a3 (patch) | |
tree | 635cb985ccb9190666feb822b362d3e0281af2ca /arch/arm | |
parent | 40c670f0314c3c9463ce9c2f2b9b1085884837f6 (diff) |
OMAP3: PM: INTC context save/restore
Add context save and restore for the INTC module to support off-mode.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/irq.c | 66 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/irqs.h | 5 |
2 files changed, 71 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 1db121f437d2..ebd3538bd1d4 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c | |||
@@ -25,6 +25,10 @@ | |||
25 | #define INTC_SYSSTATUS 0x0014 | 25 | #define INTC_SYSSTATUS 0x0014 |
26 | #define INTC_SIR 0x0040 | 26 | #define INTC_SIR 0x0040 |
27 | #define INTC_CONTROL 0x0048 | 27 | #define INTC_CONTROL 0x0048 |
28 | #define INTC_PROTECTION 0x004C | ||
29 | #define INTC_IDLE 0x0050 | ||
30 | #define INTC_THRESHOLD 0x0068 | ||
31 | #define INTC_MIR0 0x0084 | ||
28 | #define INTC_MIR_CLEAR0 0x0088 | 32 | #define INTC_MIR_CLEAR0 0x0088 |
29 | #define INTC_MIR_SET0 0x008c | 33 | #define INTC_MIR_SET0 0x008c |
30 | #define INTC_PENDING_IRQ0 0x0098 | 34 | #define INTC_PENDING_IRQ0 0x0098 |
@@ -48,6 +52,18 @@ static struct omap_irq_bank { | |||
48 | }, | 52 | }, |
49 | }; | 53 | }; |
50 | 54 | ||
55 | /* Structure to save interrupt controller context */ | ||
56 | struct omap3_intc_regs { | ||
57 | u32 sysconfig; | ||
58 | u32 protection; | ||
59 | u32 idle; | ||
60 | u32 threshold; | ||
61 | u32 ilr[INTCPS_NR_IRQS]; | ||
62 | u32 mir[INTCPS_NR_MIR_REGS]; | ||
63 | }; | ||
64 | |||
65 | static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; | ||
66 | |||
51 | /* INTC bank register get/set */ | 67 | /* INTC bank register get/set */ |
52 | 68 | ||
53 | static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) | 69 | static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) |
@@ -209,3 +225,53 @@ void __init omap_init_irq(void) | |||
209 | } | 225 | } |
210 | } | 226 | } |
211 | 227 | ||
228 | #ifdef CONFIG_ARCH_OMAP3 | ||
229 | void omap_intc_save_context(void) | ||
230 | { | ||
231 | int ind = 0, i = 0; | ||
232 | for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) { | ||
233 | struct omap_irq_bank *bank = irq_banks + ind; | ||
234 | intc_context[ind].sysconfig = | ||
235 | intc_bank_read_reg(bank, INTC_SYSCONFIG); | ||
236 | intc_context[ind].protection = | ||
237 | intc_bank_read_reg(bank, INTC_PROTECTION); | ||
238 | intc_context[ind].idle = | ||
239 | intc_bank_read_reg(bank, INTC_IDLE); | ||
240 | intc_context[ind].threshold = | ||
241 | intc_bank_read_reg(bank, INTC_THRESHOLD); | ||
242 | for (i = 0; i < INTCPS_NR_IRQS; i++) | ||
243 | intc_context[ind].ilr[i] = | ||
244 | intc_bank_read_reg(bank, (0x100 + 0x4*ind)); | ||
245 | for (i = 0; i < INTCPS_NR_MIR_REGS; i++) | ||
246 | intc_context[ind].mir[i] = | ||
247 | intc_bank_read_reg(&irq_banks[0], INTC_MIR0 + | ||
248 | (0x20 * i)); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | void omap_intc_restore_context(void) | ||
253 | { | ||
254 | int ind = 0, i = 0; | ||
255 | |||
256 | for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) { | ||
257 | struct omap_irq_bank *bank = irq_banks + ind; | ||
258 | intc_bank_write_reg(intc_context[ind].sysconfig, | ||
259 | bank, INTC_SYSCONFIG); | ||
260 | intc_bank_write_reg(intc_context[ind].sysconfig, | ||
261 | bank, INTC_SYSCONFIG); | ||
262 | intc_bank_write_reg(intc_context[ind].protection, | ||
263 | bank, INTC_PROTECTION); | ||
264 | intc_bank_write_reg(intc_context[ind].idle, | ||
265 | bank, INTC_IDLE); | ||
266 | intc_bank_write_reg(intc_context[ind].threshold, | ||
267 | bank, INTC_THRESHOLD); | ||
268 | for (i = 0; i < INTCPS_NR_IRQS; i++) | ||
269 | intc_bank_write_reg(intc_context[ind].ilr[i], | ||
270 | bank, (0x100 + 0x4*ind)); | ||
271 | for (i = 0; i < INTCPS_NR_MIR_REGS; i++) | ||
272 | intc_bank_write_reg(intc_context[ind].mir[i], | ||
273 | &irq_banks[0], INTC_MIR0 + (0x20 * i)); | ||
274 | } | ||
275 | /* MIRs are saved and restore with other PRCM registers */ | ||
276 | } | ||
277 | #endif /* CONFIG_ARCH_OMAP3 */ | ||
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index 6a6d0281e1d5..ce5dd2d1dc21 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h | |||
@@ -477,9 +477,14 @@ | |||
477 | 477 | ||
478 | #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) | 478 | #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) |
479 | 479 | ||
480 | #define INTCPS_NR_MIR_REGS 3 | ||
481 | #define INTCPS_NR_IRQS 96 | ||
482 | |||
480 | #ifndef __ASSEMBLY__ | 483 | #ifndef __ASSEMBLY__ |
481 | extern void omap_init_irq(void); | 484 | extern void omap_init_irq(void); |
482 | extern int omap_irq_pending(void); | 485 | extern int omap_irq_pending(void); |
486 | void omap_intc_save_context(void); | ||
487 | void omap_intc_restore_context(void); | ||
483 | #endif | 488 | #endif |
484 | 489 | ||
485 | #include <mach/hardware.h> | 490 | #include <mach/hardware.h> |