Commit 21f7541d8861fdcdff663c68903e961ca1b06dc6
Committed by
Samuel Ortiz
1 parent
b09530ef84
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
mfd: Add tps65910-irq devicetree init and irqdomain support
This change changes the tps65910-irq code to use irqdomain, and support initialization from devicetree. This assumes that the irq_base in the platform data is -1 if devicetree is used. Signed-off-by: Rhyland Klein <rklein@nvidia.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Showing 3 changed files with 64 additions and 34 deletions Side-by-side Diff
drivers/mfd/Kconfig
drivers/mfd/tps65910-irq.c
... | ... | @@ -20,15 +20,10 @@ |
20 | 20 | #include <linux/device.h> |
21 | 21 | #include <linux/interrupt.h> |
22 | 22 | #include <linux/irq.h> |
23 | +#include <linux/irqdomain.h> | |
23 | 24 | #include <linux/gpio.h> |
24 | 25 | #include <linux/mfd/tps65910.h> |
25 | 26 | |
26 | -static inline int irq_to_tps65910_irq(struct tps65910 *tps65910, | |
27 | - int irq) | |
28 | -{ | |
29 | - return (irq - tps65910->irq_base); | |
30 | -} | |
31 | - | |
32 | 27 | /* |
33 | 28 | * This is a threaded IRQ handler so can access I2C/SPI. Since all |
34 | 29 | * interrupts are clear on read the IRQ line will be reasserted and |
... | ... | @@ -76,7 +71,7 @@ |
76 | 71 | if (!(irq_sts & (1 << i))) |
77 | 72 | continue; |
78 | 73 | |
79 | - handle_nested_irq(tps65910->irq_base + i); | |
74 | + handle_nested_irq(irq_find_mapping(tps65910->domain, i)); | |
80 | 75 | } |
81 | 76 | |
82 | 77 | /* Write the STS register back to clear IRQs we handled */ |
83 | 78 | |
... | ... | @@ -135,14 +130,14 @@ |
135 | 130 | { |
136 | 131 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); |
137 | 132 | |
138 | - tps65910->irq_mask &= ~( 1 << irq_to_tps65910_irq(tps65910, data->irq)); | |
133 | + tps65910->irq_mask &= ~(1 << data->hwirq); | |
139 | 134 | } |
140 | 135 | |
141 | 136 | static void tps65910_irq_disable(struct irq_data *data) |
142 | 137 | { |
143 | 138 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); |
144 | 139 | |
145 | - tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq)); | |
140 | + tps65910->irq_mask |= (1 << data->hwirq); | |
146 | 141 | } |
147 | 142 | |
148 | 143 | #ifdef CONFIG_PM_SLEEP |
149 | 144 | |
... | ... | @@ -164,10 +159,35 @@ |
164 | 159 | .irq_set_wake = tps65910_irq_set_wake, |
165 | 160 | }; |
166 | 161 | |
162 | +static int tps65910_irq_map(struct irq_domain *h, unsigned int virq, | |
163 | + irq_hw_number_t hw) | |
164 | +{ | |
165 | + struct tps65910 *tps65910 = h->host_data; | |
166 | + | |
167 | + irq_set_chip_data(virq, tps65910); | |
168 | + irq_set_chip_and_handler(virq, &tps65910_irq_chip, handle_edge_irq); | |
169 | + irq_set_nested_thread(virq, 1); | |
170 | + | |
171 | + /* ARM needs us to explicitly flag the IRQ as valid | |
172 | + * and will set them noprobe when we do so. */ | |
173 | +#ifdef CONFIG_ARM | |
174 | + set_irq_flags(virq, IRQF_VALID); | |
175 | +#else | |
176 | + irq_set_noprobe(virq); | |
177 | +#endif | |
178 | + | |
179 | + return 0; | |
180 | +} | |
181 | + | |
182 | +static struct irq_domain_ops tps65910_domain_ops = { | |
183 | + .map = tps65910_irq_map, | |
184 | + .xlate = irq_domain_xlate_twocell, | |
185 | +}; | |
186 | + | |
167 | 187 | int tps65910_irq_init(struct tps65910 *tps65910, int irq, |
168 | 188 | struct tps65910_platform_data *pdata) |
169 | 189 | { |
170 | - int ret, cur_irq; | |
190 | + int ret; | |
171 | 191 | int flags = IRQF_ONESHOT; |
172 | 192 | |
173 | 193 | if (!irq) { |
174 | 194 | |
... | ... | @@ -175,17 +195,11 @@ |
175 | 195 | return -EINVAL; |
176 | 196 | } |
177 | 197 | |
178 | - if (!pdata || !pdata->irq_base) { | |
179 | - dev_warn(tps65910->dev, "No interrupt support, no IRQ base\n"); | |
198 | + if (!pdata) { | |
199 | + dev_warn(tps65910->dev, "No interrupt support, no pdata\n"); | |
180 | 200 | return -EINVAL; |
181 | 201 | } |
182 | 202 | |
183 | - tps65910->irq_mask = 0xFFFFFF; | |
184 | - | |
185 | - mutex_init(&tps65910->irq_lock); | |
186 | - tps65910->chip_irq = irq; | |
187 | - tps65910->irq_base = pdata->irq_base; | |
188 | - | |
189 | 203 | switch (tps65910_chip_id(tps65910)) { |
190 | 204 | case TPS65910: |
191 | 205 | tps65910->irq_num = TPS65910_NUM_IRQ; |
192 | 206 | |
... | ... | @@ -195,22 +209,36 @@ |
195 | 209 | break; |
196 | 210 | } |
197 | 211 | |
198 | - /* Register with genirq */ | |
199 | - for (cur_irq = tps65910->irq_base; | |
200 | - cur_irq < tps65910->irq_num + tps65910->irq_base; | |
201 | - cur_irq++) { | |
202 | - irq_set_chip_data(cur_irq, tps65910); | |
203 | - irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip, | |
204 | - handle_edge_irq); | |
205 | - irq_set_nested_thread(cur_irq, 1); | |
212 | + if (pdata->irq_base > 0) { | |
213 | + pdata->irq_base = irq_alloc_descs(pdata->irq_base, 0, | |
214 | + tps65910->irq_num, -1); | |
215 | + if (pdata->irq_base < 0) { | |
216 | + dev_warn(tps65910->dev, "Failed to alloc IRQs: %d\n", | |
217 | + pdata->irq_base); | |
218 | + return pdata->irq_base; | |
219 | + } | |
220 | + } | |
206 | 221 | |
207 | - /* ARM needs us to explicitly flag the IRQ as valid | |
208 | - * and will set them noprobe when we do so. */ | |
209 | -#ifdef CONFIG_ARM | |
210 | - set_irq_flags(cur_irq, IRQF_VALID); | |
211 | -#else | |
212 | - irq_set_noprobe(cur_irq); | |
213 | -#endif | |
222 | + tps65910->irq_mask = 0xFFFFFF; | |
223 | + | |
224 | + mutex_init(&tps65910->irq_lock); | |
225 | + tps65910->chip_irq = irq; | |
226 | + tps65910->irq_base = pdata->irq_base; | |
227 | + | |
228 | + if (pdata->irq_base > 0) | |
229 | + tps65910->domain = irq_domain_add_legacy(tps65910->dev->of_node, | |
230 | + tps65910->irq_num, | |
231 | + pdata->irq_base, | |
232 | + 0, | |
233 | + &tps65910_domain_ops, tps65910); | |
234 | + else | |
235 | + tps65910->domain = irq_domain_add_linear(tps65910->dev->of_node, | |
236 | + tps65910->irq_num, | |
237 | + &tps65910_domain_ops, tps65910); | |
238 | + | |
239 | + if (!tps65910->domain) { | |
240 | + dev_err(tps65910->dev, "Failed to create IRQ domain\n"); | |
241 | + return -ENOMEM; | |
214 | 242 | } |
215 | 243 | |
216 | 244 | ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, |