diff options
Diffstat (limited to 'drivers/mfd/twl6040-irq.c')
-rw-r--r-- | drivers/mfd/twl6040-irq.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/mfd/twl6040-irq.c b/drivers/mfd/twl6040-irq.c index b3f8ddaa28a8..4b42543da228 100644 --- a/drivers/mfd/twl6040-irq.c +++ b/drivers/mfd/twl6040-irq.c | |||
@@ -23,7 +23,10 @@ | |||
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/err.h> | ||
26 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/irqdomain.h> | ||
27 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
28 | #include <linux/mfd/core.h> | 31 | #include <linux/mfd/core.h> |
29 | #include <linux/mfd/twl6040.h> | 32 | #include <linux/mfd/twl6040.h> |
@@ -138,7 +141,8 @@ static irqreturn_t twl6040_irq_thread(int irq, void *data) | |||
138 | 141 | ||
139 | int twl6040_irq_init(struct twl6040 *twl6040) | 142 | int twl6040_irq_init(struct twl6040 *twl6040) |
140 | { | 143 | { |
141 | int cur_irq, ret; | 144 | struct device_node *node = twl6040->dev->of_node; |
145 | int i, nr_irqs, irq_base, ret; | ||
142 | u8 val; | 146 | u8 val; |
143 | 147 | ||
144 | mutex_init(&twl6040->irq_mutex); | 148 | mutex_init(&twl6040->irq_mutex); |
@@ -148,21 +152,31 @@ int twl6040_irq_init(struct twl6040 *twl6040) | |||
148 | twl6040->irq_masks_cache = TWL6040_ALLINT_MSK; | 152 | twl6040->irq_masks_cache = TWL6040_ALLINT_MSK; |
149 | twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK); | 153 | twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK); |
150 | 154 | ||
155 | nr_irqs = ARRAY_SIZE(twl6040_irqs); | ||
156 | |||
157 | irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); | ||
158 | if (IS_ERR_VALUE(irq_base)) { | ||
159 | dev_err(twl6040->dev, "Fail to allocate IRQ descs\n"); | ||
160 | return irq_base; | ||
161 | } | ||
162 | twl6040->irq_base = irq_base; | ||
163 | |||
164 | irq_domain_add_legacy(node, ARRAY_SIZE(twl6040_irqs), irq_base, 0, | ||
165 | &irq_domain_simple_ops, NULL); | ||
166 | |||
151 | /* Register them with genirq */ | 167 | /* Register them with genirq */ |
152 | for (cur_irq = twl6040->irq_base; | 168 | for (i = irq_base; i < irq_base + nr_irqs; i++) { |
153 | cur_irq < twl6040->irq_base + ARRAY_SIZE(twl6040_irqs); | 169 | irq_set_chip_data(i, twl6040); |
154 | cur_irq++) { | 170 | irq_set_chip_and_handler(i, &twl6040_irq_chip, |
155 | irq_set_chip_data(cur_irq, twl6040); | ||
156 | irq_set_chip_and_handler(cur_irq, &twl6040_irq_chip, | ||
157 | handle_level_irq); | 171 | handle_level_irq); |
158 | irq_set_nested_thread(cur_irq, 1); | 172 | irq_set_nested_thread(i, 1); |
159 | 173 | ||
160 | /* ARM needs us to explicitly flag the IRQ as valid | 174 | /* ARM needs us to explicitly flag the IRQ as valid |
161 | * and will set them noprobe when we do so. */ | 175 | * and will set them noprobe when we do so. */ |
162 | #ifdef CONFIG_ARM | 176 | #ifdef CONFIG_ARM |
163 | set_irq_flags(cur_irq, IRQF_VALID); | 177 | set_irq_flags(i, IRQF_VALID); |
164 | #else | 178 | #else |
165 | irq_set_noprobe(cur_irq); | 179 | irq_set_noprobe(i); |
166 | #endif | 180 | #endif |
167 | } | 181 | } |
168 | 182 | ||