aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc/avic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-mxc/avic.c')
-rw-r--r--arch/arm/plat-mxc/avic.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index 689f81f9593b..f3d671ff7f1b 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -19,7 +19,9 @@
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/irqdomain.h>
22#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of.h>
23#include <mach/common.h> 25#include <mach/common.h>
24#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
25#include <asm/exception.h> 27#include <asm/exception.h>
@@ -50,15 +52,19 @@
50#define AVIC_NUM_IRQS 64 52#define AVIC_NUM_IRQS 64
51 53
52void __iomem *avic_base; 54void __iomem *avic_base;
55static struct irq_domain *domain;
53 56
54static u32 avic_saved_mask_reg[2]; 57static u32 avic_saved_mask_reg[2];
55 58
56#ifdef CONFIG_MXC_IRQ_PRIOR 59#ifdef CONFIG_MXC_IRQ_PRIOR
57static int avic_irq_set_priority(unsigned char irq, unsigned char prio) 60static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
58{ 61{
62 struct irq_data *d = irq_get_irq_data(irq);
59 unsigned int temp; 63 unsigned int temp;
60 unsigned int mask = 0x0F << irq % 8 * 4; 64 unsigned int mask = 0x0F << irq % 8 * 4;
61 65
66 irq = d->hwirq;
67
62 if (irq >= AVIC_NUM_IRQS) 68 if (irq >= AVIC_NUM_IRQS)
63 return -EINVAL; 69 return -EINVAL;
64 70
@@ -75,8 +81,11 @@ static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
75#ifdef CONFIG_FIQ 81#ifdef CONFIG_FIQ
76static int avic_set_irq_fiq(unsigned int irq, unsigned int type) 82static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
77{ 83{
84 struct irq_data *d = irq_get_irq_data(irq);
78 unsigned int irqt; 85 unsigned int irqt;
79 86
87 irq = d->hwirq;
88
80 if (irq >= AVIC_NUM_IRQS) 89 if (irq >= AVIC_NUM_IRQS)
81 return -EINVAL; 90 return -EINVAL;
82 91
@@ -108,7 +117,7 @@ static void avic_irq_suspend(struct irq_data *d)
108{ 117{
109 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 118 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
110 struct irq_chip_type *ct = gc->chip_types; 119 struct irq_chip_type *ct = gc->chip_types;
111 int idx = gc->irq_base >> 5; 120 int idx = d->hwirq >> 5;
112 121
113 avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); 122 avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask);
114 __raw_writel(gc->wake_active, avic_base + ct->regs.mask); 123 __raw_writel(gc->wake_active, avic_base + ct->regs.mask);
@@ -118,7 +127,7 @@ static void avic_irq_resume(struct irq_data *d)
118{ 127{
119 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 128 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
120 struct irq_chip_type *ct = gc->chip_types; 129 struct irq_chip_type *ct = gc->chip_types;
121 int idx = gc->irq_base >> 5; 130 int idx = d->hwirq >> 5;
122 131
123 __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); 132 __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
124} 133}
@@ -128,11 +137,10 @@ static void avic_irq_resume(struct irq_data *d)
128#define avic_irq_resume NULL 137#define avic_irq_resume NULL
129#endif 138#endif
130 139
131static __init void avic_init_gc(unsigned int irq_start) 140static __init void avic_init_gc(int idx, unsigned int irq_start)
132{ 141{
133 struct irq_chip_generic *gc; 142 struct irq_chip_generic *gc;
134 struct irq_chip_type *ct; 143 struct irq_chip_type *ct;
135 int idx = irq_start >> 5;
136 144
137 gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base, 145 gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base,
138 handle_level_irq); 146 handle_level_irq);
@@ -161,7 +169,7 @@ asmlinkage void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
161 if (nivector == 0xffff) 169 if (nivector == 0xffff)
162 break; 170 break;
163 171
164 handle_IRQ(nivector, regs); 172 handle_IRQ(irq_find_mapping(domain, nivector), regs);
165 } while (1); 173 } while (1);
166} 174}
167 175
@@ -172,6 +180,8 @@ asmlinkage void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
172 */ 180 */
173void __init mxc_init_irq(void __iomem *irqbase) 181void __init mxc_init_irq(void __iomem *irqbase)
174{ 182{
183 struct device_node *np;
184 int irq_base;
175 int i; 185 int i;
176 186
177 avic_base = irqbase; 187 avic_base = irqbase;
@@ -190,8 +200,16 @@ void __init mxc_init_irq(void __iomem *irqbase)
190 __raw_writel(0, avic_base + AVIC_INTTYPEH); 200 __raw_writel(0, avic_base + AVIC_INTTYPEH);
191 __raw_writel(0, avic_base + AVIC_INTTYPEL); 201 __raw_writel(0, avic_base + AVIC_INTTYPEL);
192 202
193 for (i = 0; i < AVIC_NUM_IRQS; i += 32) 203 irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id());
194 avic_init_gc(i); 204 WARN_ON(irq_base < 0);
205
206 np = of_find_compatible_node(NULL, NULL, "fsl,avic");
207 domain = irq_domain_add_legacy(np, AVIC_NUM_IRQS, irq_base, 0,
208 &irq_domain_simple_ops, NULL);
209 WARN_ON(!domain);
210
211 for (i = 0; i < AVIC_NUM_IRQS / 32; i++, irq_base += 32)
212 avic_init_gc(i, irq_base);
195 213
196 /* Set default priority value (0) for all IRQ's */ 214 /* Set default priority value (0) for all IRQ's */
197 for (i = 0; i < 8; i++) 215 for (i = 0; i < 8; i++)
@@ -199,7 +217,7 @@ void __init mxc_init_irq(void __iomem *irqbase)
199 217
200#ifdef CONFIG_FIQ 218#ifdef CONFIG_FIQ
201 /* Initialize FIQ */ 219 /* Initialize FIQ */
202 init_FIQ(); 220 init_FIQ(FIQ_START);
203#endif 221#endif
204 222
205 printk(KERN_INFO "MXC IRQ initialized\n"); 223 printk(KERN_INFO "MXC IRQ initialized\n");