diff options
Diffstat (limited to 'arch/arm/plat-mxc/3ds_debugboard.c')
-rw-r--r-- | arch/arm/plat-mxc/3ds_debugboard.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c index 5cac2c540f4f..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,27 +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 | #define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_INTERNAL_IRQS) | ||
53 | |||
54 | #define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) | ||
55 | #define MXC_MAX_EXP_IO_LINES 16 | 53 | #define MXC_MAX_EXP_IO_LINES 16 |
56 | 54 | ||
57 | /* interrupts like external uart , external ethernet etc*/ | 55 | /* interrupts like external uart , external ethernet etc*/ |
58 | #define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0) | 56 | #define EXPIO_INT_ENET 0 |
59 | #define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1) | 57 | #define EXPIO_INT_XUART_A 1 |
60 | #define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2) | 58 | #define EXPIO_INT_XUART_B 2 |
61 | #define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3) | 59 | #define EXPIO_INT_BUTTON_A 3 |
62 | #define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4) | 60 | #define EXPIO_INT_BUTTON_B 4 |
63 | 61 | ||
64 | static void __iomem *brd_io; | 62 | static void __iomem *brd_io; |
63 | static struct irq_domain *domain; | ||
65 | 64 | ||
66 | static struct resource smsc911x_resources[] = { | 65 | static struct resource smsc911x_resources[] = { |
67 | { | 66 | { |
68 | .flags = IORESOURCE_MEM, | 67 | .flags = IORESOURCE_MEM, |
69 | } , { | 68 | } , { |
70 | .start = EXPIO_INT_ENET, | ||
71 | .end = EXPIO_INT_ENET, | ||
72 | .flags = IORESOURCE_IRQ, | 69 | .flags = IORESOURCE_IRQ, |
73 | }, | 70 | }, |
74 | }; | 71 | }; |
@@ -100,11 +97,11 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) | |||
100 | imr_val = __raw_readw(brd_io + INTR_MASK_REG); | 97 | imr_val = __raw_readw(brd_io + INTR_MASK_REG); |
101 | int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; | 98 | int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; |
102 | 99 | ||
103 | expio_irq = MXC_BOARD_IRQ_START; | 100 | expio_irq = 0; |
104 | for (; int_valid != 0; int_valid >>= 1, expio_irq++) { | 101 | for (; int_valid != 0; int_valid >>= 1, expio_irq++) { |
105 | if ((int_valid & 1) == 0) | 102 | if ((int_valid & 1) == 0) |
106 | continue; | 103 | continue; |
107 | generic_handle_irq(expio_irq); | 104 | generic_handle_irq(irq_find_mapping(domain, expio_irq)); |
108 | } | 105 | } |
109 | 106 | ||
110 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 107 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
@@ -118,7 +115,7 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) | |||
118 | static void expio_mask_irq(struct irq_data *d) | 115 | static void expio_mask_irq(struct irq_data *d) |
119 | { | 116 | { |
120 | u16 reg; | 117 | u16 reg; |
121 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | 118 | u32 expio = d->hwirq; |
122 | 119 | ||
123 | reg = __raw_readw(brd_io + INTR_MASK_REG); | 120 | reg = __raw_readw(brd_io + INTR_MASK_REG); |
124 | reg |= (1 << expio); | 121 | reg |= (1 << expio); |
@@ -127,7 +124,7 @@ static void expio_mask_irq(struct irq_data *d) | |||
127 | 124 | ||
128 | static void expio_ack_irq(struct irq_data *d) | 125 | static void expio_ack_irq(struct irq_data *d) |
129 | { | 126 | { |
130 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | 127 | u32 expio = d->hwirq; |
131 | 128 | ||
132 | __raw_writew(1 << expio, brd_io + INTR_RESET_REG); | 129 | __raw_writew(1 << expio, brd_io + INTR_RESET_REG); |
133 | __raw_writew(0, brd_io + INTR_RESET_REG); | 130 | __raw_writew(0, brd_io + INTR_RESET_REG); |
@@ -137,7 +134,7 @@ static void expio_ack_irq(struct irq_data *d) | |||
137 | static void expio_unmask_irq(struct irq_data *d) | 134 | static void expio_unmask_irq(struct irq_data *d) |
138 | { | 135 | { |
139 | u16 reg; | 136 | u16 reg; |
140 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | 137 | u32 expio = d->hwirq; |
141 | 138 | ||
142 | reg = __raw_readw(brd_io + INTR_MASK_REG); | 139 | reg = __raw_readw(brd_io + INTR_MASK_REG); |
143 | reg &= ~(1 << expio); | 140 | reg &= ~(1 << expio); |
@@ -155,8 +152,10 @@ static struct regulator_consumer_supply dummy_supplies[] = { | |||
155 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | 152 | REGULATOR_SUPPLY("vddvario", "smsc911x"), |
156 | }; | 153 | }; |
157 | 154 | ||
158 | int __init mxc_expio_init(u32 base, u32 p_irq) | 155 | int __init mxc_expio_init(u32 base, u32 intr_gpio) |
159 | { | 156 | { |
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); |
@@ -178,16 +177,23 @@ int __init mxc_expio_init(u32 base, u32 p_irq) | |||
178 | /* | 177 | /* |
179 | * Configure INT line as GPIO input | 178 | * Configure INT line as GPIO input |
180 | */ | 179 | */ |
181 | gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq"); | 180 | gpio_request(intr_gpio, "expio_pirq"); |
182 | gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq)); | 181 | gpio_direction_input(intr_gpio); |
183 | 182 | ||
184 | /* disable the interrupt and clear the status */ | 183 | /* disable the interrupt and clear the status */ |
185 | __raw_writew(0, brd_io + INTR_MASK_REG); | 184 | __raw_writew(0, brd_io + INTR_MASK_REG); |
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 p_irq) | |||
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; |