Message ID | 1386718996-3733-6-git-send-email-sboyd@codeaurora.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Dec 10, 2013 at 03:43:14PM -0800, Stephen Boyd wrote: > Some drivers use request_any_context_irq() but there isn't a > devm_* function for it. Add one so that these drivers don't need > to explicitly free the irq on driver detach. > > Cc: Thomas Gleixner <tglx@linutronix.de> Thomas, would it be OK with me picking this patch through my tree if you do not have issues with it? Thanks. > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> > --- > include/linux/interrupt.h | 5 +++++ > kernel/irq/devres.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 50 insertions(+) > > diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h > index c9e831d..8334f9b 100644 > --- a/include/linux/interrupt.h > +++ b/include/linux/interrupt.h > @@ -160,6 +160,11 @@ devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, > devname, dev_id); > } > > +extern int __must_check > +devm_request_any_context_irq(struct device *dev, unsigned int irq, > + irq_handler_t handler, unsigned long irqflags, > + const char *devname, void *dev_id); > + > extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); > > /* > diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c > index bd8e788..f71e9ff 100644 > --- a/kernel/irq/devres.c > +++ b/kernel/irq/devres.c > @@ -73,6 +73,51 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq, > EXPORT_SYMBOL(devm_request_threaded_irq); > > /** > + * devm_request_any_context_irq - allocate an interrupt line for a managed device > + * @dev: device to request interrupt for > + * @irq: Interrupt line to allocate > + * @handler: Function to be called when the IRQ occurs > + * @thread_fn: function to be called in a threaded interrupt context. NULL > + * for devices which handle everything in @handler > + * @irqflags: Interrupt type flags > + * @devname: An ascii name for the claiming device > + * @dev_id: A cookie passed back to the handler function > + * > + * Except for the extra @dev argument, this function takes the > + * same arguments and performs the same function as > + * request_any_context_irq(). IRQs requested with this function will be > + * automatically freed on driver detach. > + * > + * If an IRQ allocated with this function needs to be freed > + * separately, devm_free_irq() must be used. > + */ > +int devm_request_any_context_irq(struct device *dev, unsigned int irq, > + irq_handler_t handler, unsigned long irqflags, > + const char *devname, void *dev_id) > +{ > + struct irq_devres *dr; > + int rc; > + > + dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres), > + GFP_KERNEL); > + if (!dr) > + return -ENOMEM; > + > + rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id); > + if (rc) { > + devres_free(dr); > + return rc; > + } > + > + dr->irq = irq; > + dr->dev_id = dev_id; > + devres_add(dev, dr); > + > + return 0; > +} > +EXPORT_SYMBOL(devm_request_any_context_irq); > + > +/** > * devm_free_irq - free an interrupt > * @dev: device to free interrupt for > * @irq: Interrupt line to free > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > hosted by The Linux Foundation >
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c9e831d..8334f9b 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -160,6 +160,11 @@ devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, devname, dev_id); } +extern int __must_check +devm_request_any_context_irq(struct device *dev, unsigned int irq, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id); + extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); /* diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c index bd8e788..f71e9ff 100644 --- a/kernel/irq/devres.c +++ b/kernel/irq/devres.c @@ -73,6 +73,51 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq, EXPORT_SYMBOL(devm_request_threaded_irq); /** + * devm_request_any_context_irq - allocate an interrupt line for a managed device + * @dev: device to request interrupt for + * @irq: Interrupt line to allocate + * @handler: Function to be called when the IRQ occurs + * @thread_fn: function to be called in a threaded interrupt context. NULL + * for devices which handle everything in @handler + * @irqflags: Interrupt type flags + * @devname: An ascii name for the claiming device + * @dev_id: A cookie passed back to the handler function + * + * Except for the extra @dev argument, this function takes the + * same arguments and performs the same function as + * request_any_context_irq(). IRQs requested with this function will be + * automatically freed on driver detach. + * + * If an IRQ allocated with this function needs to be freed + * separately, devm_free_irq() must be used. + */ +int devm_request_any_context_irq(struct device *dev, unsigned int irq, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id) +{ + struct irq_devres *dr; + int rc; + + dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres), + GFP_KERNEL); + if (!dr) + return -ENOMEM; + + rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id); + if (rc) { + devres_free(dr); + return rc; + } + + dr->irq = irq; + dr->dev_id = dev_id; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL(devm_request_any_context_irq); + +/** * devm_free_irq - free an interrupt * @dev: device to free interrupt for * @irq: Interrupt line to free
Some drivers use request_any_context_irq() but there isn't a devm_* function for it. Add one so that these drivers don't need to explicitly free the irq on driver detach. Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> --- include/linux/interrupt.h | 5 +++++ kernel/irq/devres.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+)