summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2012-12-12 14:02:49 +0900
committerKukjin Kim <kgene.kim@samsung.com>2013-04-09 01:47:44 +0900
commit4e164dc5fa512ad66355b583f1f70c602e4717d6 (patch)
treefd4a0e0b3ef506bcd830e8cb3f77763e0ffc48f9 /drivers/irqchip
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>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/exynos-combiner.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index b5ff271bfd6..e8501dbaa0b 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -112,16 +112,22 @@ static struct irq_chip combiner_chip = {
#endif
};
-static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
+static unsigned int max_combiner_nr(void)
{
- unsigned int max_nr;
-
if (soc_is_exynos5250())
- max_nr = EXYNOS5_MAX_COMBINER_NR;
+ return EXYNOS5_MAX_COMBINER_NR;
+ else if (soc_is_exynos4412())
+ return EXYNOS4412_MAX_COMBINER_NR;
+ else if (soc_is_exynos4212())
+ return EXYNOS4212_MAX_COMBINER_NR;
else
- max_nr = EXYNOS4_MAX_COMBINER_NR;
+ return EXYNOS4210_MAX_COMBINER_NR;
+}
- if (combiner_nr >= max_nr)
+static void __init combiner_cascade_irq(unsigned int combiner_nr,
+ unsigned int irq)
+{
+ if (combiner_nr >= max_combiner_nr())
BUG();
if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
BUG();
@@ -186,23 +192,38 @@ static struct irq_domain_ops combiner_irq_domain_ops = {
.map = combiner_irq_domain_map,
};
+static unsigned int exynos4x12_combiner_extra_irq(int group)
+{
+ switch (group) {
+ case 16:
+ return IRQ_SPI(107);
+ case 17:
+ return IRQ_SPI(108);
+ case 18:
+ return IRQ_SPI(48);
+ case 19:
+ return IRQ_SPI(42);
+ default:
+ return 0;
+ }
+}
+
void __init combiner_init(void __iomem *combiner_base,
struct device_node *np)
{
int i, irq, irq_base;
unsigned int max_nr, nr_irq;
+ max_nr = max_combiner_nr();
+
if (np) {
if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
- pr_warning("%s: number of combiners not specified, "
+ pr_info("%s: number of combiners not specified, "
"setting default as %d.\n",
- __func__, EXYNOS4_MAX_COMBINER_NR);
- max_nr = EXYNOS4_MAX_COMBINER_NR;
+ __func__, max_nr);
}
- } else {
- max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
- EXYNOS4_MAX_COMBINER_NR;
}
+
nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
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,
}
for (i = 0; i < max_nr; i++) {
- irq = IRQ_SPI(i);
+ if (i < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
+ irq = IRQ_SPI(i);
+ else
+ irq = exynos4x12_combiner_extra_irq(i);
#ifdef CONFIG_OF
if (np)
irq = irq_of_parse_and_map(np, i);