aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/avic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/avic.c')
-rw-r--r--arch/arm/mach-imx/avic.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
index 1afccae0420c..c0434a36687a 100644
--- a/arch/arm/mach-imx/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -22,6 +22,7 @@
22#include <linux/irqdomain.h> 22#include <linux/irqdomain.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_address.h>
25#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
26#include <asm/exception.h> 27#include <asm/exception.h>
27 28
@@ -51,7 +52,12 @@
51 52
52#define AVIC_NUM_IRQS 64 53#define AVIC_NUM_IRQS 64
53 54
55/* low power interrupt mask registers */
56#define MX25_CCM_LPIMR0 0x68
57#define MX25_CCM_LPIMR1 0x6C
58
54static void __iomem *avic_base; 59static void __iomem *avic_base;
60static void __iomem *mx25_ccm_base;
55static struct irq_domain *domain; 61static struct irq_domain *domain;
56 62
57#ifdef CONFIG_FIQ 63#ifdef CONFIG_FIQ
@@ -93,6 +99,18 @@ static void avic_irq_suspend(struct irq_data *d)
93 99
94 avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); 100 avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask);
95 imx_writel(gc->wake_active, avic_base + ct->regs.mask); 101 imx_writel(gc->wake_active, avic_base + ct->regs.mask);
102
103 if (mx25_ccm_base) {
104 u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ?
105 MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1;
106 /*
107 * The interrupts which are still enabled will be used as wakeup
108 * sources. Allow those interrupts in low-power mode.
109 * The LPIMR registers use 0 to allow an interrupt, the AVIC
110 * registers use 1.
111 */
112 imx_writel(~gc->wake_active, mx25_ccm_base + offs);
113 }
96} 114}
97 115
98static void avic_irq_resume(struct irq_data *d) 116static void avic_irq_resume(struct irq_data *d)
@@ -102,6 +120,13 @@ static void avic_irq_resume(struct irq_data *d)
102 int idx = d->hwirq >> 5; 120 int idx = d->hwirq >> 5;
103 121
104 imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); 122 imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
123
124 if (mx25_ccm_base) {
125 u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ?
126 MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1;
127
128 imx_writel(0xffffffff, mx25_ccm_base + offs);
129 }
105} 130}
106 131
107#else 132#else
@@ -158,6 +183,18 @@ void __init mxc_init_irq(void __iomem *irqbase)
158 183
159 avic_base = irqbase; 184 avic_base = irqbase;
160 185
186 np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm");
187 mx25_ccm_base = of_iomap(np, 0);
188
189 if (mx25_ccm_base) {
190 /*
191 * By default, we mask all interrupts. We set the actual mask
192 * before we go into low-power mode.
193 */
194 imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR0);
195 imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR1);
196 }
197
161 /* put the AVIC into the reset value with 198 /* put the AVIC into the reset value with
162 * all interrupts disabled 199 * all interrupts disabled
163 */ 200 */