diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-06-13 05:07:25 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2012-07-01 09:58:21 -0400 |
commit | 130d8bd7b67ddfcac52437821cf84a1087b19d4e (patch) | |
tree | 6d0d35123201691617599dbb4acbbe56045f7af9 /arch/arm/mach-imx/mach-mx31ads.c | |
parent | ec7828807b14aab647a43c5b4ee2084de273c172 (diff) |
ARM: imx: add a legacy irqdomain for mx31ads
Call irq_alloc_descs to get the irq_base for mx31ads, and add a legacy
irqdomain using the irq_base, so that the mapping between mx31ads
hardware irq and Linux irq number can be dynamically handled by
irqdomain. As the result, the use of MXC_BOARD_IRQ_START can be
completely removed from mach-mx31ads.c.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Dong Aisheng <dong.aisheng@linaro.org>
Diffstat (limited to 'arch/arm/mach-imx/mach-mx31ads.c')
-rw-r--r-- | arch/arm/mach-imx/mach-mx31ads.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index a27a8543b9b5..d37f4809c556 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/irqdomain.h> | ||
24 | 25 | ||
25 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
26 | #include <asm/mach/arch.h> | 27 | #include <asm/mach/arch.h> |
@@ -63,18 +64,17 @@ | |||
63 | #define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) | 64 | #define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) |
64 | #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) | 65 | #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) |
65 | 66 | ||
66 | #define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START | 67 | #define EXPIO_INT_XUART_INTA 10 |
67 | #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) | 68 | #define EXPIO_INT_XUART_INTB 11 |
68 | |||
69 | #define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) | ||
70 | #define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11) | ||
71 | 69 | ||
72 | #define MXC_MAX_EXP_IO_LINES 16 | 70 | #define MXC_MAX_EXP_IO_LINES 16 |
73 | 71 | ||
74 | /* CS8900 */ | 72 | /* CS8900 */ |
75 | #define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) | 73 | #define EXPIO_INT_ENET_INT 8 |
76 | #define CS4_CS8900_MMIO_START 0x20000 | 74 | #define CS4_CS8900_MMIO_START 0x20000 |
77 | 75 | ||
76 | static struct irq_domain *domain; | ||
77 | |||
78 | /* | 78 | /* |
79 | * The serial port definition structure. | 79 | * The serial port definition structure. |
80 | */ | 80 | */ |
@@ -82,7 +82,6 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
82 | { | 82 | { |
83 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA), | 83 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA), |
84 | .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA), | 84 | .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA), |
85 | .irq = EXPIO_INT_XUART_INTA, | ||
86 | .uartclk = 14745600, | 85 | .uartclk = 14745600, |
87 | .regshift = 0, | 86 | .regshift = 0, |
88 | .iotype = UPIO_MEM, | 87 | .iotype = UPIO_MEM, |
@@ -90,7 +89,6 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
90 | }, { | 89 | }, { |
91 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB), | 90 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB), |
92 | .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB), | 91 | .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB), |
93 | .irq = EXPIO_INT_XUART_INTB, | ||
94 | .uartclk = 14745600, | 92 | .uartclk = 14745600, |
95 | .regshift = 0, | 93 | .regshift = 0, |
96 | .iotype = UPIO_MEM, | 94 | .iotype = UPIO_MEM, |
@@ -107,9 +105,9 @@ static struct platform_device serial_device = { | |||
107 | }, | 105 | }, |
108 | }; | 106 | }; |
109 | 107 | ||
110 | static const struct resource mx31ads_cs8900_resources[] __initconst = { | 108 | static struct resource mx31ads_cs8900_resources[] __initdata = { |
111 | DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K), | 109 | DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K), |
112 | DEFINE_RES_IRQ(EXPIO_INT_ENET_INT), | 110 | DEFINE_RES_IRQ(-1), |
113 | }; | 111 | }; |
114 | 112 | ||
115 | static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { | 113 | static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { |
@@ -121,11 +119,19 @@ static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { | |||
121 | 119 | ||
122 | static int __init mxc_init_extuart(void) | 120 | static int __init mxc_init_extuart(void) |
123 | { | 121 | { |
122 | serial_platform_data[0].irq = irq_find_mapping(domain, | ||
123 | EXPIO_INT_XUART_INTA); | ||
124 | serial_platform_data[1].irq = irq_find_mapping(domain, | ||
125 | EXPIO_INT_XUART_INTB); | ||
124 | return platform_device_register(&serial_device); | 126 | return platform_device_register(&serial_device); |
125 | } | 127 | } |
126 | 128 | ||
127 | static void __init mxc_init_ext_ethernet(void) | 129 | static void __init mxc_init_ext_ethernet(void) |
128 | { | 130 | { |
131 | mx31ads_cs8900_resources[1].start = | ||
132 | irq_find_mapping(domain, EXPIO_INT_ENET_INT); | ||
133 | mx31ads_cs8900_resources[1].end = | ||
134 | irq_find_mapping(domain, EXPIO_INT_ENET_INT); | ||
129 | platform_device_register_full( | 135 | platform_device_register_full( |
130 | (struct platform_device_info *)&mx31ads_cs8900_devinfo); | 136 | (struct platform_device_info *)&mx31ads_cs8900_devinfo); |
131 | } | 137 | } |
@@ -156,12 +162,12 @@ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) | |||
156 | imr_val = __raw_readw(PBC_INTMASK_SET_REG); | 162 | imr_val = __raw_readw(PBC_INTMASK_SET_REG); |
157 | int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; | 163 | int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; |
158 | 164 | ||
159 | expio_irq = MXC_EXP_IO_BASE; | 165 | expio_irq = 0; |
160 | for (; int_valid != 0; int_valid >>= 1, expio_irq++) { | 166 | for (; int_valid != 0; int_valid >>= 1, expio_irq++) { |
161 | if ((int_valid & 1) == 0) | 167 | if ((int_valid & 1) == 0) |
162 | continue; | 168 | continue; |
163 | 169 | ||
164 | generic_handle_irq(expio_irq); | 170 | generic_handle_irq(irq_find_mapping(domain, expio_irq)); |
165 | } | 171 | } |
166 | } | 172 | } |
167 | 173 | ||
@@ -171,7 +177,7 @@ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) | |||
171 | */ | 177 | */ |
172 | static void expio_mask_irq(struct irq_data *d) | 178 | static void expio_mask_irq(struct irq_data *d) |
173 | { | 179 | { |
174 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | 180 | u32 expio = d->hwirq; |
175 | /* mask the interrupt */ | 181 | /* mask the interrupt */ |
176 | __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); | 182 | __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); |
177 | __raw_readw(PBC_INTMASK_CLEAR_REG); | 183 | __raw_readw(PBC_INTMASK_CLEAR_REG); |
@@ -183,7 +189,7 @@ static void expio_mask_irq(struct irq_data *d) | |||
183 | */ | 189 | */ |
184 | static void expio_ack_irq(struct irq_data *d) | 190 | static void expio_ack_irq(struct irq_data *d) |
185 | { | 191 | { |
186 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | 192 | u32 expio = d->hwirq; |
187 | /* clear the interrupt status */ | 193 | /* clear the interrupt status */ |
188 | __raw_writew(1 << expio, PBC_INTSTATUS_REG); | 194 | __raw_writew(1 << expio, PBC_INTSTATUS_REG); |
189 | } | 195 | } |
@@ -194,7 +200,7 @@ static void expio_ack_irq(struct irq_data *d) | |||
194 | */ | 200 | */ |
195 | static void expio_unmask_irq(struct irq_data *d) | 201 | static void expio_unmask_irq(struct irq_data *d) |
196 | { | 202 | { |
197 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | 203 | u32 expio = d->hwirq; |
198 | /* unmask the interrupt */ | 204 | /* unmask the interrupt */ |
199 | __raw_writew(1 << expio, PBC_INTMASK_SET_REG); | 205 | __raw_writew(1 << expio, PBC_INTMASK_SET_REG); |
200 | } | 206 | } |
@@ -208,6 +214,7 @@ static struct irq_chip expio_irq_chip = { | |||
208 | 214 | ||
209 | static void __init mx31ads_init_expio(void) | 215 | static void __init mx31ads_init_expio(void) |
210 | { | 216 | { |
217 | int irq_base; | ||
211 | int i, irq; | 218 | int i, irq; |
212 | 219 | ||
213 | printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); | 220 | printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); |
@@ -220,8 +227,15 @@ static void __init mx31ads_init_expio(void) | |||
220 | /* disable the interrupt and clear the status */ | 227 | /* disable the interrupt and clear the status */ |
221 | __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); | 228 | __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); |
222 | __raw_writew(0xFFFF, PBC_INTSTATUS_REG); | 229 | __raw_writew(0xFFFF, PBC_INTSTATUS_REG); |
223 | for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); | 230 | |
224 | i++) { | 231 | irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); |
232 | WARN_ON(irq_base < 0); | ||
233 | |||
234 | domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0, | ||
235 | &irq_domain_simple_ops, NULL); | ||
236 | WARN_ON(!domain); | ||
237 | |||
238 | for (i = irq_base; i < irq_base + MXC_MAX_EXP_IO_LINES; i++) { | ||
225 | irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); | 239 | irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); |
226 | set_irq_flags(i, IRQF_VALID); | 240 | set_irq_flags(i, IRQF_VALID); |
227 | } | 241 | } |