diff options
Diffstat (limited to 'arch/arm/plat-mxc/tzic.c')
-rw-r--r-- | arch/arm/plat-mxc/tzic.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index 98308ec1f321..c60a7e416385 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/irqdomain.h> | ||
19 | #include <linux/of.h> | ||
18 | 20 | ||
19 | #include <asm/mach/irq.h> | 21 | #include <asm/mach/irq.h> |
20 | #include <asm/exception.h> | 22 | #include <asm/exception.h> |
@@ -49,6 +51,7 @@ | |||
49 | #define TZIC_ID0 0x0FD0 /* Indentification Register 0 */ | 51 | #define TZIC_ID0 0x0FD0 /* Indentification Register 0 */ |
50 | 52 | ||
51 | void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */ | 53 | void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */ |
54 | static struct irq_domain *domain; | ||
52 | 55 | ||
53 | #define TZIC_NUM_IRQS 128 | 56 | #define TZIC_NUM_IRQS 128 |
54 | 57 | ||
@@ -77,15 +80,14 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) | |||
77 | static void tzic_irq_suspend(struct irq_data *d) | 80 | static void tzic_irq_suspend(struct irq_data *d) |
78 | { | 81 | { |
79 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 82 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
80 | int idx = gc->irq_base >> 5; | 83 | int idx = d->hwirq >> 5; |
81 | 84 | ||
82 | __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); | 85 | __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); |
83 | } | 86 | } |
84 | 87 | ||
85 | static void tzic_irq_resume(struct irq_data *d) | 88 | static void tzic_irq_resume(struct irq_data *d) |
86 | { | 89 | { |
87 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 90 | int idx = d->hwirq >> 5; |
88 | int idx = gc->irq_base >> 5; | ||
89 | 91 | ||
90 | __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), | 92 | __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), |
91 | tzic_base + TZIC_WAKEUP0(idx)); | 93 | tzic_base + TZIC_WAKEUP0(idx)); |
@@ -102,11 +104,10 @@ static struct mxc_extra_irq tzic_extra_irq = { | |||
102 | #endif | 104 | #endif |
103 | }; | 105 | }; |
104 | 106 | ||
105 | static __init void tzic_init_gc(unsigned int irq_start) | 107 | static __init void tzic_init_gc(int idx, unsigned int irq_start) |
106 | { | 108 | { |
107 | struct irq_chip_generic *gc; | 109 | struct irq_chip_generic *gc; |
108 | struct irq_chip_type *ct; | 110 | struct irq_chip_type *ct; |
109 | int idx = irq_start >> 5; | ||
110 | 111 | ||
111 | gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base, | 112 | gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base, |
112 | handle_level_irq); | 113 | handle_level_irq); |
@@ -140,7 +141,8 @@ asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) | |||
140 | while (stat) { | 141 | while (stat) { |
141 | handled = 1; | 142 | handled = 1; |
142 | irqofs = fls(stat) - 1; | 143 | irqofs = fls(stat) - 1; |
143 | handle_IRQ(irqofs + i * 32, regs); | 144 | handle_IRQ(irq_find_mapping(domain, |
145 | irqofs + i * 32), regs); | ||
144 | stat &= ~(1 << irqofs); | 146 | stat &= ~(1 << irqofs); |
145 | } | 147 | } |
146 | } | 148 | } |
@@ -154,6 +156,8 @@ asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) | |||
154 | */ | 156 | */ |
155 | void __init tzic_init_irq(void __iomem *irqbase) | 157 | void __init tzic_init_irq(void __iomem *irqbase) |
156 | { | 158 | { |
159 | struct device_node *np; | ||
160 | int irq_base; | ||
157 | int i; | 161 | int i; |
158 | 162 | ||
159 | tzic_base = irqbase; | 163 | tzic_base = irqbase; |
@@ -175,12 +179,20 @@ void __init tzic_init_irq(void __iomem *irqbase) | |||
175 | 179 | ||
176 | /* all IRQ no FIQ Warning :: No selection */ | 180 | /* all IRQ no FIQ Warning :: No selection */ |
177 | 181 | ||
178 | for (i = 0; i < TZIC_NUM_IRQS; i += 32) | 182 | irq_base = irq_alloc_descs(-1, 0, TZIC_NUM_IRQS, numa_node_id()); |
179 | tzic_init_gc(i); | 183 | WARN_ON(irq_base < 0); |
184 | |||
185 | np = of_find_compatible_node(NULL, NULL, "fsl,tzic"); | ||
186 | domain = irq_domain_add_legacy(np, TZIC_NUM_IRQS, irq_base, 0, | ||
187 | &irq_domain_simple_ops, NULL); | ||
188 | WARN_ON(!domain); | ||
189 | |||
190 | for (i = 0; i < 4; i++, irq_base += 32) | ||
191 | tzic_init_gc(i, irq_base); | ||
180 | 192 | ||
181 | #ifdef CONFIG_FIQ | 193 | #ifdef CONFIG_FIQ |
182 | /* Initialize FIQ */ | 194 | /* Initialize FIQ */ |
183 | init_FIQ(); | 195 | init_FIQ(FIQ_START); |
184 | #endif | 196 | #endif |
185 | 197 | ||
186 | pr_info("TrustZone Interrupt Controller (TZIC) initialized\n"); | 198 | pr_info("TrustZone Interrupt Controller (TZIC) initialized\n"); |