diff options
| author | Shawn Guo <shawn.guo@linaro.org> | 2012-06-13 04:37:04 -0400 |
|---|---|---|
| committer | Shawn Guo <shawn.guo@linaro.org> | 2012-07-01 09:58:15 -0400 |
| commit | ec7828807b14aab647a43c5b4ee2084de273c172 (patch) | |
| tree | 9c8152469958e2d5dce30b126517dc6eb0f2cad9 | |
| parent | ed4a7fb01a467f5d264fe12f17eb981f21c7bbcd (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.c | 42 |
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 | ||
| 63 | static void __iomem *brd_io; | 62 | static void __iomem *brd_io; |
| 63 | static struct irq_domain *domain; | ||
| 64 | 64 | ||
| 65 | static struct resource smsc911x_resources[] = { | 65 | static 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) | |||
| 117 | static void expio_mask_irq(struct irq_data *d) | 115 | static 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 | ||
| 127 | static void expio_ack_irq(struct irq_data *d) | 125 | static 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) | |||
| 136 | static void expio_unmask_irq(struct irq_data *d) | 134 | static 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[] = { | |||
| 157 | int __init mxc_expio_init(u32 base, u32 intr_gpio) | 155 | int __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; |
