aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2012-12-12 00:02:49 -0500
committerKukjin Kim <kgene.kim@samsung.com>2013-04-08 12:47:44 -0400
commit4e164dc5fa512ad66355b583f1f70c602e4717d6 (patch)
treefd4a0e0b3ef506bcd830e8cb3f77763e0ffc48f9
parentdf7ef462a2f8036430940b69871c762a92efead2 (diff)
irqchip: exynos-combiner: Correct combined IRQs for exynos4
This patch corrects combined IRQs for exynos4 series platform. The exynos4412 has four extra combined irq group and the exynos4212 has two more combined irqs than exynos4210. Each irq is mapped to IRQ_SPI(xx). Unfortunately, extra 4 combined IRQs isn't sequential. So, we need to map the irqs manually. Signed-off-by: Chanho Park <chanho61.park@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> [kgene.kim@samsung.com: changes moved into drivers/irqchip/] Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h5
-rw-r--r--drivers/irqchip/exynos-combiner.c50
2 files changed, 41 insertions, 14 deletions
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index c0e75d8dd737..387490661403 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -166,7 +166,10 @@
166#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) 166#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
167#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) 167#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
168 168
169#define EXYNOS4_MAX_COMBINER_NR 16 169#define EXYNOS4210_MAX_COMBINER_NR 16
170#define EXYNOS4212_MAX_COMBINER_NR 18
171#define EXYNOS4412_MAX_COMBINER_NR 20
172#define EXYNOS4_MAX_COMBINER_NR EXYNOS4412_MAX_COMBINER_NR
170 173
171#define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16 174#define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16
172#define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9 175#define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index b5ff271bfd64..e8501dbaa0b7 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -112,16 +112,22 @@ static struct irq_chip combiner_chip = {
112#endif 112#endif
113}; 113};
114 114
115static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) 115static unsigned int max_combiner_nr(void)
116{ 116{
117 unsigned int max_nr;
118
119 if (soc_is_exynos5250()) 117 if (soc_is_exynos5250())
120 max_nr = EXYNOS5_MAX_COMBINER_NR; 118 return EXYNOS5_MAX_COMBINER_NR;
119 else if (soc_is_exynos4412())
120 return EXYNOS4412_MAX_COMBINER_NR;
121 else if (soc_is_exynos4212())
122 return EXYNOS4212_MAX_COMBINER_NR;
121 else 123 else
122 max_nr = EXYNOS4_MAX_COMBINER_NR; 124 return EXYNOS4210_MAX_COMBINER_NR;
125}
123 126
124 if (combiner_nr >= max_nr) 127static void __init combiner_cascade_irq(unsigned int combiner_nr,
128 unsigned int irq)
129{
130 if (combiner_nr >= max_combiner_nr())
125 BUG(); 131 BUG();
126 if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) 132 if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
127 BUG(); 133 BUG();
@@ -186,23 +192,38 @@ static struct irq_domain_ops combiner_irq_domain_ops = {
186 .map = combiner_irq_domain_map, 192 .map = combiner_irq_domain_map,
187}; 193};
188 194
195static unsigned int exynos4x12_combiner_extra_irq(int group)
196{
197 switch (group) {
198 case 16:
199 return IRQ_SPI(107);
200 case 17:
201 return IRQ_SPI(108);
202 case 18:
203 return IRQ_SPI(48);
204 case 19:
205 return IRQ_SPI(42);
206 default:
207 return 0;
208 }
209}
210
189void __init combiner_init(void __iomem *combiner_base, 211void __init combiner_init(void __iomem *combiner_base,
190 struct device_node *np) 212 struct device_node *np)
191{ 213{
192 int i, irq, irq_base; 214 int i, irq, irq_base;
193 unsigned int max_nr, nr_irq; 215 unsigned int max_nr, nr_irq;
194 216
217 max_nr = max_combiner_nr();
218
195 if (np) { 219 if (np) {
196 if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) { 220 if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
197 pr_warning("%s: number of combiners not specified, " 221 pr_info("%s: number of combiners not specified, "
198 "setting default as %d.\n", 222 "setting default as %d.\n",
199 __func__, EXYNOS4_MAX_COMBINER_NR); 223 __func__, max_nr);
200 max_nr = EXYNOS4_MAX_COMBINER_NR;
201 } 224 }
202 } else {
203 max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
204 EXYNOS4_MAX_COMBINER_NR;
205 } 225 }
226
206 nr_irq = max_nr * MAX_IRQ_IN_COMBINER; 227 nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
207 228
208 irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0); 229 irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
@@ -219,7 +240,10 @@ void __init combiner_init(void __iomem *combiner_base,
219 } 240 }
220 241
221 for (i = 0; i < max_nr; i++) { 242 for (i = 0; i < max_nr; i++) {
222 irq = IRQ_SPI(i); 243 if (i < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
244 irq = IRQ_SPI(i);
245 else
246 irq = exynos4x12_combiner_extra_irq(i);
223#ifdef CONFIG_OF 247#ifdef CONFIG_OF
224 if (np) 248 if (np)
225 irq = irq_of_parse_and_map(np, i); 249 irq = irq_of_parse_and_map(np, i);