irq-devres: add devm_request_any_context_irq
Shardar Shariff Md [Tue, 7 Oct 2014 14:35:35 +0000 (19:35 +0530)]
Add device managed version of request_any_context_irq

Bug 1557030

Signed-off-by: Shardar Shariff Md <smohammed@nvidia.com>
Change-Id: Idec07432dd4912e204d51cf7212c0e0f245dd242
Reviewed-on: http://git-master/r/554228
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

include/linux/interrupt.h
kernel/irq/devres.c

index e8401d0..35ac99e 100644 (file)
@@ -196,6 +196,9 @@ devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
 
 extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
 
+extern int devm_request_any_context_irq(struct device *dev, unsigned int irq,
+               irq_handler_t handler, unsigned long flags, const char *name,
+               void *dev_id);
 /*
  * On lockdep we dont want to enable hardirqs in hardirq
  * context. Use local_irq_enable_in_hardirq() to annotate
index bd8e788..adc8974 100644 (file)
@@ -92,3 +92,47 @@ void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
        free_irq(irq, dev_id);
 }
 EXPORT_SYMBOL(devm_free_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.
+ *                     Threaded handler for threaded interrupts.
+ *     @flags: Interrupt type flags
+ *     @name: 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_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 flags, const char *name,
+               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, flags, name, 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);