1 #include <linux/module.h> 2 #include <linux/interrupt.h> 3 #include <linux/device.h> 4 #include <linux/gfp.h> 5 6 /* 7 * Device resource management aware IRQ request/free implementation. 8 */ 9 struct irq_devres { 10 unsigned int irq; 11 void *dev_id; 12 }; 13 14 static void devm_irq_release(struct device *dev, void *res) 15 { 16 struct irq_devres *this = res; 17 18 free_irq(this->irq, this->dev_id); 19 } 20 21 static int devm_irq_match(struct device *dev, void *res, void *data) 22 { 23 struct irq_devres *this = res, *match = data; 24 25 return this->irq == match->irq && this->dev_id == match->dev_id; 26 } 27 28 /** 29 * devm_request_irq - allocate an interrupt line for a managed device 30 * @dev: device to request interrupt for 31 * @irq: Interrupt line to allocate 32 * @handler: Function to be called when the IRQ occurs 33 * @irqflags: Interrupt type flags 34 * @devname: An ascii name for the claiming device 35 * @dev_id: A cookie passed back to the handler function 36 * 37 * Except for the extra @dev argument, this function takes the 38 * same arguments and performs the same function as 39 * request_irq(). IRQs requested with this function will be 40 * automatically freed on driver detach. 41 * 42 * If an IRQ allocated with this function needs to be freed 43 * separately, dev_free_irq() must be used. 44 */ 45 int devm_request_irq(struct device *dev, unsigned int irq, 46 irq_handler_t handler, unsigned long irqflags, 47 const char *devname, void *dev_id) 48 { 49 struct irq_devres *dr; 50 int rc; 51 52 dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres), 53 GFP_KERNEL); 54 if (!dr) 55 return -ENOMEM; 56 57 rc = request_irq(irq, handler, irqflags, devname, dev_id); 58 if (rc) { 59 devres_free(dr); 60 return rc; 61 } 62 63 dr->irq = irq; 64 dr->dev_id = dev_id; 65 devres_add(dev, dr); 66 67 return 0; 68 } 69 EXPORT_SYMBOL(devm_request_irq); 70 71 /** 72 * devm_free_irq - free an interrupt 73 * @dev: device to free interrupt for 74 * @irq: Interrupt line to free 75 * @dev_id: Device identity to free 76 * 77 * Except for the extra @dev argument, this function takes the 78 * same arguments and performs the same function as free_irq(). 79 * This function instead of free_irq() should be used to manually 80 * free IRQs allocated with dev_request_irq(). 81 */ 82 void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id) 83 { 84 struct irq_devres match_data = { irq, dev_id }; 85 86 free_irq(irq, dev_id); 87 WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match, 88 &match_data)); 89 } 90 EXPORT_SYMBOL(devm_free_irq); 91