1 #include <linux/module.h> 2 #include <linux/interrupt.h> 3 #include <linux/device.h> 4 #include <linux/gfp.h> 5 #include <linux/irq.h> 6 7 /* 8 * Device resource management aware IRQ request/free implementation. 9 */ 10 struct irq_devres { 11 unsigned int irq; 12 void *dev_id; 13 }; 14 15 static void devm_irq_release(struct device *dev, void *res) 16 { 17 struct irq_devres *this = res; 18 19 free_irq(this->irq, this->dev_id); 20 } 21 22 static int devm_irq_match(struct device *dev, void *res, void *data) 23 { 24 struct irq_devres *this = res, *match = data; 25 26 return this->irq == match->irq && this->dev_id == match->dev_id; 27 } 28 29 /** 30 * devm_request_threaded_irq - allocate an interrupt line for a managed device 31 * @dev: device to request interrupt for 32 * @irq: Interrupt line to allocate 33 * @handler: Function to be called when the IRQ occurs 34 * @thread_fn: function to be called in a threaded interrupt context. NULL 35 * for devices which handle everything in @handler 36 * @irqflags: Interrupt type flags 37 * @devname: An ascii name for the claiming device, dev_name(dev) if NULL 38 * @dev_id: A cookie passed back to the handler function 39 * 40 * Except for the extra @dev argument, this function takes the 41 * same arguments and performs the same function as 42 * request_threaded_irq(). IRQs requested with this function will be 43 * automatically freed on driver detach. 44 * 45 * If an IRQ allocated with this function needs to be freed 46 * separately, devm_free_irq() must be used. 47 */ 48 int devm_request_threaded_irq(struct device *dev, unsigned int irq, 49 irq_handler_t handler, irq_handler_t thread_fn, 50 unsigned long irqflags, const char *devname, 51 void *dev_id) 52 { 53 struct irq_devres *dr; 54 int rc; 55 56 dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres), 57 GFP_KERNEL); 58 if (!dr) 59 return -ENOMEM; 60 61 if (!devname) 62 devname = dev_name(dev); 63 64 rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname, 65 dev_id); 66 if (rc) { 67 devres_free(dr); 68 return rc; 69 } 70 71 dr->irq = irq; 72 dr->dev_id = dev_id; 73 devres_add(dev, dr); 74 75 return 0; 76 } 77 EXPORT_SYMBOL(devm_request_threaded_irq); 78 79 /** 80 * devm_request_any_context_irq - allocate an interrupt line for a managed device 81 * @dev: device to request interrupt for 82 * @irq: Interrupt line to allocate 83 * @handler: Function to be called when the IRQ occurs 84 * @thread_fn: function to be called in a threaded interrupt context. NULL 85 * for devices which handle everything in @handler 86 * @irqflags: Interrupt type flags 87 * @devname: An ascii name for the claiming device, dev_name(dev) if NULL 88 * @dev_id: A cookie passed back to the handler function 89 * 90 * Except for the extra @dev argument, this function takes the 91 * same arguments and performs the same function as 92 * request_any_context_irq(). IRQs requested with this function will be 93 * automatically freed on driver detach. 94 * 95 * If an IRQ allocated with this function needs to be freed 96 * separately, devm_free_irq() must be used. 97 */ 98 int devm_request_any_context_irq(struct device *dev, unsigned int irq, 99 irq_handler_t handler, unsigned long irqflags, 100 const char *devname, void *dev_id) 101 { 102 struct irq_devres *dr; 103 int rc; 104 105 dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres), 106 GFP_KERNEL); 107 if (!dr) 108 return -ENOMEM; 109 110 if (!devname) 111 devname = dev_name(dev); 112 113 rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id); 114 if (rc < 0) { 115 devres_free(dr); 116 return rc; 117 } 118 119 dr->irq = irq; 120 dr->dev_id = dev_id; 121 devres_add(dev, dr); 122 123 return rc; 124 } 125 EXPORT_SYMBOL(devm_request_any_context_irq); 126 127 /** 128 * devm_free_irq - free an interrupt 129 * @dev: device to free interrupt for 130 * @irq: Interrupt line to free 131 * @dev_id: Device identity to free 132 * 133 * Except for the extra @dev argument, this function takes the 134 * same arguments and performs the same function as free_irq(). 135 * This function instead of free_irq() should be used to manually 136 * free IRQs allocated with devm_request_irq(). 137 */ 138 void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id) 139 { 140 struct irq_devres match_data = { irq, dev_id }; 141 142 WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match, 143 &match_data)); 144 free_irq(irq, dev_id); 145 } 146 EXPORT_SYMBOL(devm_free_irq); 147 148 struct irq_desc_devres { 149 unsigned int from; 150 unsigned int cnt; 151 }; 152 153 static void devm_irq_desc_release(struct device *dev, void *res) 154 { 155 struct irq_desc_devres *this = res; 156 157 irq_free_descs(this->from, this->cnt); 158 } 159 160 /** 161 * __devm_irq_alloc_descs - Allocate and initialize a range of irq descriptors 162 * for a managed device 163 * @dev: Device to allocate the descriptors for 164 * @irq: Allocate for specific irq number if irq >= 0 165 * @from: Start the search from this irq number 166 * @cnt: Number of consecutive irqs to allocate 167 * @node: Preferred node on which the irq descriptor should be allocated 168 * @owner: Owning module (can be NULL) 169 * @affinity: Optional pointer to an affinity mask array of size @cnt 170 * which hints where the irq descriptors should be allocated 171 * and which default affinities to use 172 * 173 * Returns the first irq number or error code. 174 * 175 * Note: Use the provided wrappers (devm_irq_alloc_desc*) for simplicity. 176 */ 177 int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, 178 unsigned int cnt, int node, struct module *owner, 179 const struct cpumask *affinity) 180 { 181 struct irq_desc_devres *dr; 182 int base; 183 184 dr = devres_alloc(devm_irq_desc_release, sizeof(*dr), GFP_KERNEL); 185 if (!dr) 186 return -ENOMEM; 187 188 base = __irq_alloc_descs(irq, from, cnt, node, owner, affinity); 189 if (base < 0) { 190 devres_free(dr); 191 return base; 192 } 193 194 dr->from = base; 195 dr->cnt = cnt; 196 devres_add(dev, dr); 197 198 return base; 199 } 200 EXPORT_SYMBOL_GPL(__devm_irq_alloc_descs); 201