aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/imx23.dtsi2
-rw-r--r--arch/arm/boot/dts/imx28.dtsi2
-rw-r--r--arch/arm/mach-mxs/icoll.c45
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c25
4 files changed, 41 insertions, 33 deletions
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 573066bc4c51..bee37226399a 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -43,7 +43,7 @@
43 ranges; 43 ranges;
44 44
45 icoll: interrupt-controller@80000000 { 45 icoll: interrupt-controller@80000000 {
46 compatible = "fsl,imx23-icoll", "fsl,mxs-icoll"; 46 compatible = "fsl,imx23-icoll", "fsl,icoll";
47 interrupt-controller; 47 interrupt-controller;
48 #interrupt-cells = <1>; 48 #interrupt-cells = <1>;
49 reg = <0x80000000 0x2000>; 49 reg = <0x80000000 0x2000>;
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 183fc65faa56..99f7d7a8ba28 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -50,7 +50,7 @@
50 ranges; 50 ranges;
51 51
52 icoll: interrupt-controller@80000000 { 52 icoll: interrupt-controller@80000000 {
53 compatible = "fsl,imx28-icoll", "fsl,mxs-icoll"; 53 compatible = "fsl,imx28-icoll", "fsl,icoll";
54 interrupt-controller; 54 interrupt-controller;
55 #interrupt-cells = <1>; 55 #interrupt-cells = <1>;
56 reg = <0x80000000 0x2000>; 56 reg = <0x80000000 0x2000>;
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
index a11b6184026e..8fb23af154b3 100644
--- a/arch/arm/mach-mxs/icoll.c
+++ b/arch/arm/mach-mxs/icoll.c
@@ -19,7 +19,10 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/init.h> 20#include <linux/init.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>
25#include <linux/of_irq.h>
23#include <asm/exception.h> 26#include <asm/exception.h>
24#include <mach/mxs.h> 27#include <mach/mxs.h>
25#include <mach/common.h> 28#include <mach/common.h>
@@ -33,7 +36,10 @@
33#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004 36#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
34#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1 37#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
35 38
39#define ICOLL_NUM_IRQS 128
40
36static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR); 41static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
42static struct irq_domain *icoll_domain;
37 43
38static void icoll_ack_irq(struct irq_data *d) 44static void icoll_ack_irq(struct irq_data *d)
39{ 45{
@@ -49,13 +55,13 @@ static void icoll_ack_irq(struct irq_data *d)
49static void icoll_mask_irq(struct irq_data *d) 55static void icoll_mask_irq(struct irq_data *d)
50{ 56{
51 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, 57 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
52 icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->irq)); 58 icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
53} 59}
54 60
55static void icoll_unmask_irq(struct irq_data *d) 61static void icoll_unmask_irq(struct irq_data *d)
56{ 62{
57 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, 63 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
58 icoll_base + HW_ICOLL_INTERRUPTn_SET(d->irq)); 64 icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
59} 65}
60 66
61static struct irq_chip mxs_icoll_chip = { 67static struct irq_chip mxs_icoll_chip = {
@@ -72,6 +78,7 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
72 irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET); 78 irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
73 if (irqnr != 0x7f) { 79 if (irqnr != 0x7f) {
74 __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR); 80 __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
81 irqnr = irq_find_mapping(icoll_domain, irqnr);
75 handle_IRQ(irqnr, regs); 82 handle_IRQ(irqnr, regs);
76 continue; 83 continue;
77 } 84 }
@@ -79,18 +86,40 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
79 } while (1); 86 } while (1);
80} 87}
81 88
82void __init icoll_init_irq(void) 89static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
90 irq_hw_number_t hw)
83{ 91{
84 int i; 92 irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
93 set_irq_flags(virq, IRQF_VALID);
94
95 return 0;
96}
85 97
98static struct irq_domain_ops icoll_irq_domain_ops = {
99 .map = icoll_irq_domain_map,
100 .xlate = irq_domain_xlate_onecell,
101};
102
103void __init icoll_of_init(struct device_node *np,
104 struct device_node *interrupt_parent)
105{
86 /* 106 /*
87 * Interrupt Collector reset, which initializes the priority 107 * Interrupt Collector reset, which initializes the priority
88 * for each irq to level 0. 108 * for each irq to level 0.
89 */ 109 */
90 mxs_reset_block(icoll_base + HW_ICOLL_CTRL); 110 mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
91 111
92 for (i = 0; i < MXS_INTERNAL_IRQS; i++) { 112 icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
93 irq_set_chip_and_handler(i, &mxs_icoll_chip, handle_level_irq); 113 &icoll_irq_domain_ops, NULL);
94 set_irq_flags(i, IRQF_VALID); 114 WARN_ON(!icoll_domain);
95 } 115}
116
117static const struct of_device_id icoll_of_match[] __initconst = {
118 {.compatible = "fsl,icoll", .data = icoll_of_init},
119 { /* sentinel */ }
120};
121
122void __init icoll_init_irq(void)
123{
124 of_irq_init(icoll_of_match);
96} 125}
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index b07af1c12cb6..256ec656fc65 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -15,10 +15,8 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/irqdomain.h>
19#include <linux/micrel_phy.h> 18#include <linux/micrel_phy.h>
20#include <linux/mxsfb.h> 19#include <linux/mxsfb.h>
21#include <linux/of_irq.h>
22#include <linux/of_platform.h> 20#include <linux/of_platform.h>
23#include <linux/phy.h> 21#include <linux/phy.h>
24#include <asm/mach/arch.h> 22#include <asm/mach/arch.h>
@@ -105,25 +103,6 @@ static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
105 { /* sentinel */ } 103 { /* sentinel */ }
106}; 104};
107 105
108static int __init mxs_icoll_add_irq_domain(struct device_node *np,
109 struct device_node *interrupt_parent)
110{
111 irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
112
113 return 0;
114}
115
116static const struct of_device_id mxs_irq_match[] __initconst = {
117 { .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
118 { /* sentinel */ }
119};
120
121static void __init mxs_dt_init_irq(void)
122{
123 icoll_init_irq();
124 of_irq_init(mxs_irq_match);
125}
126
127static void __init imx23_timer_init(void) 106static void __init imx23_timer_init(void)
128{ 107{
129 mx23_clocks_init(); 108 mx23_clocks_init();
@@ -293,7 +272,7 @@ static const char *imx28_dt_compat[] __initdata = {
293 272
294DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)") 273DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
295 .map_io = mx23_map_io, 274 .map_io = mx23_map_io,
296 .init_irq = mxs_dt_init_irq, 275 .init_irq = icoll_init_irq,
297 .handle_irq = icoll_handle_irq, 276 .handle_irq = icoll_handle_irq,
298 .timer = &imx23_timer, 277 .timer = &imx23_timer,
299 .init_machine = mxs_machine_init, 278 .init_machine = mxs_machine_init,
@@ -303,7 +282,7 @@ MACHINE_END
303 282
304DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)") 283DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)")
305 .map_io = mx28_map_io, 284 .map_io = mx28_map_io,
306 .init_irq = mxs_dt_init_irq, 285 .init_irq = icoll_init_irq,
307 .handle_irq = icoll_handle_irq, 286 .handle_irq = icoll_handle_irq,
308 .timer = &imx28_timer, 287 .timer = &imx28_timer,
309 .init_machine = mxs_machine_init, 288 .init_machine = mxs_machine_init,