diff options
author | Barry Song <baohua.song@csr.com> | 2011-09-21 09:40:33 -0400 |
---|---|---|
committer | Barry Song <21cnbao@gmail.com> | 2011-09-21 10:52:58 -0400 |
commit | 9c2a51faab6de454407964987ad0cdb84edf2723 (patch) | |
tree | 482fc8ddd5191057d968a0c8164c589e8d67a99c /arch/arm/mach-prima2/irq.c | |
parent | e5598a855b0e63b77b67c4ab708e09a23228d14f (diff) |
ARM: CSR: PM: save/restore irq status in suspend cycle
SiRFprimaII will lose power in deepsleep mode except rtc, pmu and sdram
self-refresh. So IRQ controller will lose status in suspend cyle.
This patch saves irq mask/level registers while suspending and restore
them while resuming.
Signed-off-by: Barry Song <baohua.song@csr.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-prima2/irq.c')
-rw-r--r-- | arch/arm/mach-prima2/irq.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c index cf80a72c0a09..d93ceef4a50a 100644 --- a/arch/arm/mach-prima2/irq.c +++ b/arch/arm/mach-prima2/irq.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/irqdomain.h> | 16 | #include <linux/irqdomain.h> |
17 | #include <linux/syscore_ops.h> | ||
17 | 18 | ||
18 | #define SIRFSOC_INT_RISC_MASK0 0x0018 | 19 | #define SIRFSOC_INT_RISC_MASK0 0x0018 |
19 | #define SIRFSOC_INT_RISC_MASK1 0x001C | 20 | #define SIRFSOC_INT_RISC_MASK1 0x001C |
@@ -73,3 +74,42 @@ void __init sirfsoc_of_irq_init(void) | |||
73 | 74 | ||
74 | sirfsoc_irq_init(); | 75 | sirfsoc_irq_init(); |
75 | } | 76 | } |
77 | |||
78 | struct sirfsoc_irq_status { | ||
79 | u32 mask0; | ||
80 | u32 mask1; | ||
81 | u32 level0; | ||
82 | u32 level1; | ||
83 | }; | ||
84 | |||
85 | static struct sirfsoc_irq_status sirfsoc_irq_st; | ||
86 | |||
87 | static int sirfsoc_irq_suspend(void) | ||
88 | { | ||
89 | sirfsoc_irq_st.mask0 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0); | ||
90 | sirfsoc_irq_st.mask1 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); | ||
91 | sirfsoc_irq_st.level0 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0); | ||
92 | sirfsoc_irq_st.level1 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static void sirfsoc_irq_resume(void) | ||
98 | { | ||
99 | writel_relaxed(sirfsoc_irq_st.mask0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0); | ||
100 | writel_relaxed(sirfsoc_irq_st.mask1, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); | ||
101 | writel_relaxed(sirfsoc_irq_st.level0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0); | ||
102 | writel_relaxed(sirfsoc_irq_st.level1, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1); | ||
103 | } | ||
104 | |||
105 | static struct syscore_ops sirfsoc_irq_syscore_ops = { | ||
106 | .suspend = sirfsoc_irq_suspend, | ||
107 | .resume = sirfsoc_irq_resume, | ||
108 | }; | ||
109 | |||
110 | static int __init sirfsoc_irq_pm_init(void) | ||
111 | { | ||
112 | register_syscore_ops(&sirfsoc_irq_syscore_ops); | ||
113 | return 0; | ||
114 | } | ||
115 | device_initcall(sirfsoc_irq_pm_init); | ||