genirq: Add devm_request_any_context_irq()
authorStephen Boyd <sboyd@codeaurora.org>
Fri, 3 Jan 2014 00:37:32 +0000 (16:37 -0800)
committerThomas Gleixner <tglx@linutronix.de>
Sun, 9 Feb 2014 14:27:21 +0000 (15:27 +0100)
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.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Link: http://lkml.kernel.org/r/1388709460-19222-3-git-send-email-sboyd@codeaurora.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/interrupt.h
kernel/irq/devres.c

index 0053adde0ed9a37111ffd273c17f6d19956a6a77..a2678d35b5a2e8fc8f840d91f1ac5c7ec0c97bec 100644 (file)
@@ -158,6 +158,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);
 
 /*
index bd8e788d71e0dd582caa3f97602fd3b86acc21fb..1ef0606797c9c211b5b328aef7696a23b1eab652 100644 (file)
@@ -72,6 +72,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