aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-06-13 04:37:04 -0400
committerShawn Guo <shawn.guo@linaro.org>2012-07-01 09:58:15 -0400
commitec7828807b14aab647a43c5b4ee2084de273c172 (patch)
tree9c8152469958e2d5dce30b126517dc6eb0f2cad9
parented4a7fb01a467f5d264fe12f17eb981f21c7bbcd (diff)
ARM: imx: add a legacy irqdomain for 3ds_debugboard
Call irq_alloc_descs to get the irq_base for 3ds_debugboard, and add a legacy irqdomain using the irq_base, so that the mapping between 3ds_debugboard 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 3ds_debugboard.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>
-rw-r--r--arch/arm/plat-mxc/3ds_debugboard.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c
index 3b48a08c165a..5c10ad05df74 100644
--- a/arch/arm/plat-mxc/3ds_debugboard.c
+++ b/arch/arm/plat-mxc/3ds_debugboard.c
@@ -12,9 +12,11 @@
12 12
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/irqdomain.h>
15#include <linux/io.h> 16#include <linux/io.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/module.h>
18#include <linux/smsc911x.h> 20#include <linux/smsc911x.h>
19#include <linux/regulator/machine.h> 21#include <linux/regulator/machine.h>
20#include <linux/regulator/fixed.h> 22#include <linux/regulator/fixed.h>
@@ -48,26 +50,22 @@
48/* CPU ID and Personality ID */ 50/* CPU ID and Personality ID */
49#define MCU_BOARD_ID_REG 0x68 51#define MCU_BOARD_ID_REG 0x68
50 52
51#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START)
52
53#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
54#define MXC_MAX_EXP_IO_LINES 16 53#define MXC_MAX_EXP_IO_LINES 16
55 54
56/* interrupts like external uart , external ethernet etc*/ 55/* interrupts like external uart , external ethernet etc*/
57#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0) 56#define EXPIO_INT_ENET 0
58#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1) 57#define EXPIO_INT_XUART_A 1
59#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2) 58#define EXPIO_INT_XUART_B 2
60#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3) 59#define EXPIO_INT_BUTTON_A 3
61#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4) 60#define EXPIO_INT_BUTTON_B 4
62 61
63static void __iomem *brd_io; 62static void __iomem *brd_io;
63static struct irq_domain *domain;
64 64
65static struct resource smsc911x_resources[] = { 65static struct resource smsc911x_resources[] = {
66 { 66 {
67 .flags = IORESOURCE_MEM, 67 .flags = IORESOURCE_MEM,
68 } , { 68 } , {
69 .start = EXPIO_INT_ENET,
70 .end = EXPIO_INT_ENET,
71 .flags = IORESOURCE_IRQ, 69 .flags = IORESOURCE_IRQ,
72 }, 70 },
73}; 71};
@@ -99,11 +97,11 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
99 imr_val = __raw_readw(brd_io + INTR_MASK_REG); 97 imr_val = __raw_readw(brd_io + INTR_MASK_REG);
100 int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; 98 int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
101 99
102 expio_irq = MXC_BOARD_IRQ_START; 100 expio_irq = 0;
103 for (; int_valid != 0; int_valid >>= 1, expio_irq++) { 101 for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
104 if ((int_valid & 1) == 0) 102 if ((int_valid & 1) == 0)
105 continue; 103 continue;
106 generic_handle_irq(expio_irq); 104 generic_handle_irq(irq_find_mapping(domain, expio_irq));
107 } 105 }
108 106
109 desc->irq_data.chip->irq_ack(&desc->irq_data); 107 desc->irq_data.chip->irq_ack(&desc->irq_data);
@@ -117,7 +115,7 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
117static void expio_mask_irq(struct irq_data *d) 115static void expio_mask_irq(struct irq_data *d)
118{ 116{
119 u16 reg; 117 u16 reg;
120 u32 expio = MXC_IRQ_TO_EXPIO(d->irq); 118 u32 expio = d->hwirq;
121 119
122 reg = __raw_readw(brd_io + INTR_MASK_REG); 120 reg = __raw_readw(brd_io + INTR_MASK_REG);
123 reg |= (1 << expio); 121 reg |= (1 << expio);
@@ -126,7 +124,7 @@ static void expio_mask_irq(struct irq_data *d)
126 124
127static void expio_ack_irq(struct irq_data *d) 125static void expio_ack_irq(struct irq_data *d)
128{ 126{
129 u32 expio = MXC_IRQ_TO_EXPIO(d->irq); 127 u32 expio = d->hwirq;
130 128
131 __raw_writew(1 << expio, brd_io + INTR_RESET_REG); 129 __raw_writew(1 << expio, brd_io + INTR_RESET_REG);
132 __raw_writew(0, brd_io + INTR_RESET_REG); 130 __raw_writew(0, brd_io + INTR_RESET_REG);
@@ -136,7 +134,7 @@ static void expio_ack_irq(struct irq_data *d)
136static void expio_unmask_irq(struct irq_data *d) 134static void expio_unmask_irq(struct irq_data *d)
137{ 135{
138 u16 reg; 136 u16 reg;
139 u32 expio = MXC_IRQ_TO_EXPIO(d->irq); 137 u32 expio = d->hwirq;
140 138
141 reg = __raw_readw(brd_io + INTR_MASK_REG); 139 reg = __raw_readw(brd_io + INTR_MASK_REG);
142 reg &= ~(1 << expio); 140 reg &= ~(1 << expio);
@@ -157,6 +155,7 @@ static struct regulator_consumer_supply dummy_supplies[] = {
157int __init mxc_expio_init(u32 base, u32 intr_gpio) 155int __init mxc_expio_init(u32 base, u32 intr_gpio)
158{ 156{
159 u32 p_irq = gpio_to_irq(intr_gpio); 157 u32 p_irq = gpio_to_irq(intr_gpio);
158 int irq_base;
160 int i; 159 int i;
161 160
162 brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K); 161 brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K);
@@ -186,8 +185,15 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio)
186 __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); 185 __raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
187 __raw_writew(0, brd_io + INTR_RESET_REG); 186 __raw_writew(0, brd_io + INTR_RESET_REG);
188 __raw_writew(0x1F, brd_io + INTR_MASK_REG); 187 __raw_writew(0x1F, brd_io + INTR_MASK_REG);
189 for (i = MXC_EXP_IO_BASE; 188
190 i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) { 189 irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id());
190 WARN_ON(irq_base < 0);
191
192 domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0,
193 &irq_domain_simple_ops, NULL);
194 WARN_ON(!domain);
195
196 for (i = irq_base; i < irq_base + MXC_MAX_EXP_IO_LINES; i++) {
191 irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); 197 irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
192 set_irq_flags(i, IRQF_VALID); 198 set_irq_flags(i, IRQF_VALID);
193 } 199 }
@@ -199,6 +205,8 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio)
199 205
200 smsc911x_resources[0].start = LAN9217_BASE_ADDR(base); 206 smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
201 smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1; 207 smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1;
208 smsc911x_resources[1].start = irq_find_mapping(domain, EXPIO_INT_ENET);
209 smsc911x_resources[1].end = irq_find_mapping(domain, EXPIO_INT_ENET);
202 platform_device_register(&smsc_lan9217_device); 210 platform_device_register(&smsc_lan9217_device);
203 211
204 return 0; 212 return 0;