diff options
Diffstat (limited to 'kernel/irq/devres.c')
-rw-r--r-- | kernel/irq/devres.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c index 1613bfd48365..194c506d9d20 100644 --- a/kernel/irq/devres.c +++ b/kernel/irq/devres.c | |||
@@ -4,6 +4,8 @@ | |||
4 | #include <linux/gfp.h> | 4 | #include <linux/gfp.h> |
5 | #include <linux/irq.h> | 5 | #include <linux/irq.h> |
6 | 6 | ||
7 | #include "internals.h" | ||
8 | |||
7 | /* | 9 | /* |
8 | * Device resource management aware IRQ request/free implementation. | 10 | * Device resource management aware IRQ request/free implementation. |
9 | */ | 11 | */ |
@@ -198,3 +200,87 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, | |||
198 | return base; | 200 | return base; |
199 | } | 201 | } |
200 | EXPORT_SYMBOL_GPL(__devm_irq_alloc_descs); | 202 | EXPORT_SYMBOL_GPL(__devm_irq_alloc_descs); |
203 | |||
204 | #ifdef CONFIG_GENERIC_IRQ_CHIP | ||
205 | /** | ||
206 | * devm_irq_alloc_generic_chip - Allocate and initialize a generic chip | ||
207 | * for a managed device | ||
208 | * @dev: Device to allocate the generic chip for | ||
209 | * @name: Name of the irq chip | ||
210 | * @num_ct: Number of irq_chip_type instances associated with this | ||
211 | * @irq_base: Interrupt base nr for this chip | ||
212 | * @reg_base: Register base address (virtual) | ||
213 | * @handler: Default flow handler associated with this chip | ||
214 | * | ||
215 | * Returns an initialized irq_chip_generic structure. The chip defaults | ||
216 | * to the primary (index 0) irq_chip_type and @handler | ||
217 | */ | ||
218 | struct irq_chip_generic * | ||
219 | devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct, | ||
220 | unsigned int irq_base, void __iomem *reg_base, | ||
221 | irq_flow_handler_t handler) | ||
222 | { | ||
223 | struct irq_chip_generic *gc; | ||
224 | unsigned long sz = sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); | ||
225 | |||
226 | gc = devm_kzalloc(dev, sz, GFP_KERNEL); | ||
227 | if (gc) | ||
228 | irq_init_generic_chip(gc, name, num_ct, | ||
229 | irq_base, reg_base, handler); | ||
230 | |||
231 | return gc; | ||
232 | } | ||
233 | EXPORT_SYMBOL_GPL(devm_irq_alloc_generic_chip); | ||
234 | |||
235 | struct irq_generic_chip_devres { | ||
236 | struct irq_chip_generic *gc; | ||
237 | u32 msk; | ||
238 | unsigned int clr; | ||
239 | unsigned int set; | ||
240 | }; | ||
241 | |||
242 | static void devm_irq_remove_generic_chip(struct device *dev, void *res) | ||
243 | { | ||
244 | struct irq_generic_chip_devres *this = res; | ||
245 | |||
246 | irq_remove_generic_chip(this->gc, this->msk, this->clr, this->set); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * devm_irq_setup_generic_chip - Setup a range of interrupts with a generic | ||
251 | * chip for a managed device | ||
252 | * | ||
253 | * @dev: Device to setup the generic chip for | ||
254 | * @gc: Generic irq chip holding all data | ||
255 | * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base | ||
256 | * @flags: Flags for initialization | ||
257 | * @clr: IRQ_* bits to clear | ||
258 | * @set: IRQ_* bits to set | ||
259 | * | ||
260 | * Set up max. 32 interrupts starting from gc->irq_base. Note, this | ||
261 | * initializes all interrupts to the primary irq_chip_type and its | ||
262 | * associated handler. | ||
263 | */ | ||
264 | int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc, | ||
265 | u32 msk, enum irq_gc_flags flags, | ||
266 | unsigned int clr, unsigned int set) | ||
267 | { | ||
268 | struct irq_generic_chip_devres *dr; | ||
269 | |||
270 | dr = devres_alloc(devm_irq_remove_generic_chip, | ||
271 | sizeof(*dr), GFP_KERNEL); | ||
272 | if (!dr) | ||
273 | return -ENOMEM; | ||
274 | |||
275 | irq_setup_generic_chip(gc, msk, flags, clr, set); | ||
276 | |||
277 | dr->gc = gc; | ||
278 | dr->msk = msk; | ||
279 | dr->clr = clr; | ||
280 | dr->set = set; | ||
281 | devres_add(dev, dr); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | EXPORT_SYMBOL_GPL(devm_irq_setup_generic_chip); | ||
286 | #endif /* CONFIG_GENERIC_IRQ_CHIP */ | ||