0001
0002 #include <linux/module.h>
0003 #include <linux/interrupt.h>
0004 #include <linux/device.h>
0005 #include <linux/gfp.h>
0006 #include <linux/irq.h>
0007
0008 #include "internals.h"
0009
0010
0011
0012
0013 struct irq_devres {
0014 unsigned int irq;
0015 void *dev_id;
0016 };
0017
0018 static void devm_irq_release(struct device *dev, void *res)
0019 {
0020 struct irq_devres *this = res;
0021
0022 free_irq(this->irq, this->dev_id);
0023 }
0024
0025 static int devm_irq_match(struct device *dev, void *res, void *data)
0026 {
0027 struct irq_devres *this = res, *match = data;
0028
0029 return this->irq == match->irq && this->dev_id == match->dev_id;
0030 }
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 int devm_request_threaded_irq(struct device *dev, unsigned int irq,
0052 irq_handler_t handler, irq_handler_t thread_fn,
0053 unsigned long irqflags, const char *devname,
0054 void *dev_id)
0055 {
0056 struct irq_devres *dr;
0057 int rc;
0058
0059 dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
0060 GFP_KERNEL);
0061 if (!dr)
0062 return -ENOMEM;
0063
0064 if (!devname)
0065 devname = dev_name(dev);
0066
0067 rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
0068 dev_id);
0069 if (rc) {
0070 devres_free(dr);
0071 return rc;
0072 }
0073
0074 dr->irq = irq;
0075 dr->dev_id = dev_id;
0076 devres_add(dev, dr);
0077
0078 return 0;
0079 }
0080 EXPORT_SYMBOL(devm_request_threaded_irq);
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 int devm_request_any_context_irq(struct device *dev, unsigned int irq,
0100 irq_handler_t handler, unsigned long irqflags,
0101 const char *devname, void *dev_id)
0102 {
0103 struct irq_devres *dr;
0104 int rc;
0105
0106 dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
0107 GFP_KERNEL);
0108 if (!dr)
0109 return -ENOMEM;
0110
0111 if (!devname)
0112 devname = dev_name(dev);
0113
0114 rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
0115 if (rc < 0) {
0116 devres_free(dr);
0117 return rc;
0118 }
0119
0120 dr->irq = irq;
0121 dr->dev_id = dev_id;
0122 devres_add(dev, dr);
0123
0124 return rc;
0125 }
0126 EXPORT_SYMBOL(devm_request_any_context_irq);
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
0140 {
0141 struct irq_devres match_data = { irq, dev_id };
0142
0143 WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match,
0144 &match_data));
0145 free_irq(irq, dev_id);
0146 }
0147 EXPORT_SYMBOL(devm_free_irq);
0148
0149 struct irq_desc_devres {
0150 unsigned int from;
0151 unsigned int cnt;
0152 };
0153
0154 static void devm_irq_desc_release(struct device *dev, void *res)
0155 {
0156 struct irq_desc_devres *this = res;
0157
0158 irq_free_descs(this->from, this->cnt);
0159 }
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
0179 unsigned int cnt, int node, struct module *owner,
0180 const struct irq_affinity_desc *affinity)
0181 {
0182 struct irq_desc_devres *dr;
0183 int base;
0184
0185 dr = devres_alloc(devm_irq_desc_release, sizeof(*dr), GFP_KERNEL);
0186 if (!dr)
0187 return -ENOMEM;
0188
0189 base = __irq_alloc_descs(irq, from, cnt, node, owner, affinity);
0190 if (base < 0) {
0191 devres_free(dr);
0192 return base;
0193 }
0194
0195 dr->from = base;
0196 dr->cnt = cnt;
0197 devres_add(dev, dr);
0198
0199 return base;
0200 }
0201 EXPORT_SYMBOL_GPL(__devm_irq_alloc_descs);
0202
0203 #ifdef CONFIG_GENERIC_IRQ_CHIP
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 struct irq_chip_generic *
0218 devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct,
0219 unsigned int irq_base, void __iomem *reg_base,
0220 irq_flow_handler_t handler)
0221 {
0222 struct irq_chip_generic *gc;
0223
0224 gc = devm_kzalloc(dev, struct_size(gc, chip_types, num_ct), GFP_KERNEL);
0225 if (gc)
0226 irq_init_generic_chip(gc, name, num_ct,
0227 irq_base, reg_base, handler);
0228
0229 return gc;
0230 }
0231 EXPORT_SYMBOL_GPL(devm_irq_alloc_generic_chip);
0232
0233 struct irq_generic_chip_devres {
0234 struct irq_chip_generic *gc;
0235 u32 msk;
0236 unsigned int clr;
0237 unsigned int set;
0238 };
0239
0240 static void devm_irq_remove_generic_chip(struct device *dev, void *res)
0241 {
0242 struct irq_generic_chip_devres *this = res;
0243
0244 irq_remove_generic_chip(this->gc, this->msk, this->clr, this->set);
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
0263 u32 msk, enum irq_gc_flags flags,
0264 unsigned int clr, unsigned int set)
0265 {
0266 struct irq_generic_chip_devres *dr;
0267
0268 dr = devres_alloc(devm_irq_remove_generic_chip,
0269 sizeof(*dr), GFP_KERNEL);
0270 if (!dr)
0271 return -ENOMEM;
0272
0273 irq_setup_generic_chip(gc, msk, flags, clr, set);
0274
0275 dr->gc = gc;
0276 dr->msk = msk;
0277 dr->clr = clr;
0278 dr->set = set;
0279 devres_add(dev, dr);
0280
0281 return 0;
0282 }
0283 EXPORT_SYMBOL_GPL(devm_irq_setup_generic_chip);
0284 #endif