xref: /openbmc/linux/kernel/irq/devres.c (revision 30fd8fc5)
15ea81769SAl Viro #include <linux/module.h>
25ea81769SAl Viro #include <linux/interrupt.h>
30af3678fSAl Viro #include <linux/device.h>
41aeb272cSRobert P. J. Day #include <linux/gfp.h>
52b5e7730SBartosz Golaszewski #include <linux/irq.h>
65ea81769SAl Viro 
71c3e3630SBartosz Golaszewski #include "internals.h"
81c3e3630SBartosz Golaszewski 
95ea81769SAl Viro /*
105ea81769SAl Viro  * Device resource management aware IRQ request/free implementation.
115ea81769SAl Viro  */
125ea81769SAl Viro struct irq_devres {
135ea81769SAl Viro 	unsigned int irq;
145ea81769SAl Viro 	void *dev_id;
155ea81769SAl Viro };
165ea81769SAl Viro 
175ea81769SAl Viro static void devm_irq_release(struct device *dev, void *res)
185ea81769SAl Viro {
195ea81769SAl Viro 	struct irq_devres *this = res;
205ea81769SAl Viro 
215ea81769SAl Viro 	free_irq(this->irq, this->dev_id);
225ea81769SAl Viro }
235ea81769SAl Viro 
245ea81769SAl Viro static int devm_irq_match(struct device *dev, void *res, void *data)
255ea81769SAl Viro {
265ea81769SAl Viro 	struct irq_devres *this = res, *match = data;
275ea81769SAl Viro 
285ea81769SAl Viro 	return this->irq == match->irq && this->dev_id == match->dev_id;
295ea81769SAl Viro }
305ea81769SAl Viro 
315ea81769SAl Viro /**
32935bd5b9SArjan van de Ven  *	devm_request_threaded_irq - allocate an interrupt line for a managed device
335ea81769SAl Viro  *	@dev: device to request interrupt for
345ea81769SAl Viro  *	@irq: Interrupt line to allocate
355ea81769SAl Viro  *	@handler: Function to be called when the IRQ occurs
36935bd5b9SArjan van de Ven  *	@thread_fn: function to be called in a threaded interrupt context. NULL
37935bd5b9SArjan van de Ven  *		    for devices which handle everything in @handler
385ea81769SAl Viro  *	@irqflags: Interrupt type flags
39899b5fbfSHeiner Kallweit  *	@devname: An ascii name for the claiming device, dev_name(dev) if NULL
405ea81769SAl Viro  *	@dev_id: A cookie passed back to the handler function
415ea81769SAl Viro  *
425ea81769SAl Viro  *	Except for the extra @dev argument, this function takes the
435ea81769SAl Viro  *	same arguments and performs the same function as
44307b28b9SEmilio López  *	request_threaded_irq().  IRQs requested with this function will be
455ea81769SAl Viro  *	automatically freed on driver detach.
465ea81769SAl Viro  *
475ea81769SAl Viro  *	If an IRQ allocated with this function needs to be freed
485c42dc70SJean Delvare  *	separately, devm_free_irq() must be used.
495ea81769SAl Viro  */
50935bd5b9SArjan van de Ven int devm_request_threaded_irq(struct device *dev, unsigned int irq,
51935bd5b9SArjan van de Ven 			      irq_handler_t handler, irq_handler_t thread_fn,
52935bd5b9SArjan van de Ven 			      unsigned long irqflags, const char *devname,
53935bd5b9SArjan van de Ven 			      void *dev_id)
545ea81769SAl Viro {
555ea81769SAl Viro 	struct irq_devres *dr;
565ea81769SAl Viro 	int rc;
575ea81769SAl Viro 
585ea81769SAl Viro 	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
595ea81769SAl Viro 			  GFP_KERNEL);
605ea81769SAl Viro 	if (!dr)
615ea81769SAl Viro 		return -ENOMEM;
625ea81769SAl Viro 
63899b5fbfSHeiner Kallweit 	if (!devname)
64899b5fbfSHeiner Kallweit 		devname = dev_name(dev);
65899b5fbfSHeiner Kallweit 
66935bd5b9SArjan van de Ven 	rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
67935bd5b9SArjan van de Ven 				  dev_id);
685ea81769SAl Viro 	if (rc) {
697f30e49eSTejun Heo 		devres_free(dr);
705ea81769SAl Viro 		return rc;
715ea81769SAl Viro 	}
725ea81769SAl Viro 
735ea81769SAl Viro 	dr->irq = irq;
745ea81769SAl Viro 	dr->dev_id = dev_id;
755ea81769SAl Viro 	devres_add(dev, dr);
765ea81769SAl Viro 
775ea81769SAl Viro 	return 0;
785ea81769SAl Viro }
79935bd5b9SArjan van de Ven EXPORT_SYMBOL(devm_request_threaded_irq);
805ea81769SAl Viro 
815ea81769SAl Viro /**
820668d306SStephen Boyd  *	devm_request_any_context_irq - allocate an interrupt line for a managed device
830668d306SStephen Boyd  *	@dev: device to request interrupt for
840668d306SStephen Boyd  *	@irq: Interrupt line to allocate
850668d306SStephen Boyd  *	@handler: Function to be called when the IRQ occurs
860668d306SStephen Boyd  *	@thread_fn: function to be called in a threaded interrupt context. NULL
870668d306SStephen Boyd  *		    for devices which handle everything in @handler
880668d306SStephen Boyd  *	@irqflags: Interrupt type flags
89899b5fbfSHeiner Kallweit  *	@devname: An ascii name for the claiming device, dev_name(dev) if NULL
900668d306SStephen Boyd  *	@dev_id: A cookie passed back to the handler function
910668d306SStephen Boyd  *
920668d306SStephen Boyd  *	Except for the extra @dev argument, this function takes the
930668d306SStephen Boyd  *	same arguments and performs the same function as
940668d306SStephen Boyd  *	request_any_context_irq().  IRQs requested with this function will be
950668d306SStephen Boyd  *	automatically freed on driver detach.
960668d306SStephen Boyd  *
970668d306SStephen Boyd  *	If an IRQ allocated with this function needs to be freed
980668d306SStephen Boyd  *	separately, devm_free_irq() must be used.
990668d306SStephen Boyd  */
1000668d306SStephen Boyd int devm_request_any_context_irq(struct device *dev, unsigned int irq,
1010668d306SStephen Boyd 			      irq_handler_t handler, unsigned long irqflags,
1020668d306SStephen Boyd 			      const char *devname, void *dev_id)
1030668d306SStephen Boyd {
1040668d306SStephen Boyd 	struct irq_devres *dr;
1050668d306SStephen Boyd 	int rc;
1060668d306SStephen Boyd 
1070668d306SStephen Boyd 	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
1080668d306SStephen Boyd 			  GFP_KERNEL);
1090668d306SStephen Boyd 	if (!dr)
1100668d306SStephen Boyd 		return -ENOMEM;
1110668d306SStephen Boyd 
112899b5fbfSHeiner Kallweit 	if (!devname)
113899b5fbfSHeiner Kallweit 		devname = dev_name(dev);
114899b5fbfSHeiner Kallweit 
1150668d306SStephen Boyd 	rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
11663781394SAxel Lin 	if (rc < 0) {
1170668d306SStephen Boyd 		devres_free(dr);
1180668d306SStephen Boyd 		return rc;
1190668d306SStephen Boyd 	}
1200668d306SStephen Boyd 
1210668d306SStephen Boyd 	dr->irq = irq;
1220668d306SStephen Boyd 	dr->dev_id = dev_id;
1230668d306SStephen Boyd 	devres_add(dev, dr);
1240668d306SStephen Boyd 
12563781394SAxel Lin 	return rc;
1260668d306SStephen Boyd }
1270668d306SStephen Boyd EXPORT_SYMBOL(devm_request_any_context_irq);
1280668d306SStephen Boyd 
1290668d306SStephen Boyd /**
1305ea81769SAl Viro  *	devm_free_irq - free an interrupt
1315ea81769SAl Viro  *	@dev: device to free interrupt for
1325ea81769SAl Viro  *	@irq: Interrupt line to free
1335ea81769SAl Viro  *	@dev_id: Device identity to free
1345ea81769SAl Viro  *
1355ea81769SAl Viro  *	Except for the extra @dev argument, this function takes the
1365ea81769SAl Viro  *	same arguments and performs the same function as free_irq().
1375ea81769SAl Viro  *	This function instead of free_irq() should be used to manually
1389ce8e498SBaruch Siach  *	free IRQs allocated with devm_request_irq().
1395ea81769SAl Viro  */
1405ea81769SAl Viro void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
1415ea81769SAl Viro {
1425ea81769SAl Viro 	struct irq_devres match_data = { irq, dev_id };
1435ea81769SAl Viro 
1445ea81769SAl Viro 	WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match,
1455ea81769SAl Viro 			       &match_data));
146ae891a1bSMaxin B John 	free_irq(irq, dev_id);
1475ea81769SAl Viro }
1485ea81769SAl Viro EXPORT_SYMBOL(devm_free_irq);
1492b5e7730SBartosz Golaszewski 
1502b5e7730SBartosz Golaszewski struct irq_desc_devres {
1512b5e7730SBartosz Golaszewski 	unsigned int from;
1522b5e7730SBartosz Golaszewski 	unsigned int cnt;
1532b5e7730SBartosz Golaszewski };
1542b5e7730SBartosz Golaszewski 
1552b5e7730SBartosz Golaszewski static void devm_irq_desc_release(struct device *dev, void *res)
1562b5e7730SBartosz Golaszewski {
1572b5e7730SBartosz Golaszewski 	struct irq_desc_devres *this = res;
1582b5e7730SBartosz Golaszewski 
1592b5e7730SBartosz Golaszewski 	irq_free_descs(this->from, this->cnt);
1602b5e7730SBartosz Golaszewski }
1612b5e7730SBartosz Golaszewski 
1622b5e7730SBartosz Golaszewski /**
1632b5e7730SBartosz Golaszewski  * __devm_irq_alloc_descs - Allocate and initialize a range of irq descriptors
1642b5e7730SBartosz Golaszewski  *			    for a managed device
1652b5e7730SBartosz Golaszewski  * @dev:	Device to allocate the descriptors for
1662b5e7730SBartosz Golaszewski  * @irq:	Allocate for specific irq number if irq >= 0
1672b5e7730SBartosz Golaszewski  * @from:	Start the search from this irq number
1682b5e7730SBartosz Golaszewski  * @cnt:	Number of consecutive irqs to allocate
1692b5e7730SBartosz Golaszewski  * @node:	Preferred node on which the irq descriptor should be allocated
1702b5e7730SBartosz Golaszewski  * @owner:	Owning module (can be NULL)
1712b5e7730SBartosz Golaszewski  * @affinity:	Optional pointer to an affinity mask array of size @cnt
1722b5e7730SBartosz Golaszewski  *		which hints where the irq descriptors should be allocated
1732b5e7730SBartosz Golaszewski  *		and which default affinities to use
1742b5e7730SBartosz Golaszewski  *
1752b5e7730SBartosz Golaszewski  * Returns the first irq number or error code.
1762b5e7730SBartosz Golaszewski  *
1772b5e7730SBartosz Golaszewski  * Note: Use the provided wrappers (devm_irq_alloc_desc*) for simplicity.
1782b5e7730SBartosz Golaszewski  */
1792b5e7730SBartosz Golaszewski int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
1802b5e7730SBartosz Golaszewski 			   unsigned int cnt, int node, struct module *owner,
1812b5e7730SBartosz Golaszewski 			   const struct cpumask *affinity)
1822b5e7730SBartosz Golaszewski {
1832b5e7730SBartosz Golaszewski 	struct irq_desc_devres *dr;
1842b5e7730SBartosz Golaszewski 	int base;
1852b5e7730SBartosz Golaszewski 
1862b5e7730SBartosz Golaszewski 	dr = devres_alloc(devm_irq_desc_release, sizeof(*dr), GFP_KERNEL);
1872b5e7730SBartosz Golaszewski 	if (!dr)
1882b5e7730SBartosz Golaszewski 		return -ENOMEM;
1892b5e7730SBartosz Golaszewski 
1902b5e7730SBartosz Golaszewski 	base = __irq_alloc_descs(irq, from, cnt, node, owner, affinity);
1912b5e7730SBartosz Golaszewski 	if (base < 0) {
1922b5e7730SBartosz Golaszewski 		devres_free(dr);
1932b5e7730SBartosz Golaszewski 		return base;
1942b5e7730SBartosz Golaszewski 	}
1952b5e7730SBartosz Golaszewski 
1962b5e7730SBartosz Golaszewski 	dr->from = base;
1972b5e7730SBartosz Golaszewski 	dr->cnt = cnt;
1982b5e7730SBartosz Golaszewski 	devres_add(dev, dr);
1992b5e7730SBartosz Golaszewski 
2002b5e7730SBartosz Golaszewski 	return base;
2012b5e7730SBartosz Golaszewski }
2022b5e7730SBartosz Golaszewski EXPORT_SYMBOL_GPL(__devm_irq_alloc_descs);
2031c3e3630SBartosz Golaszewski 
2041c3e3630SBartosz Golaszewski #ifdef CONFIG_GENERIC_IRQ_CHIP
2051c3e3630SBartosz Golaszewski /**
2061c3e3630SBartosz Golaszewski  * devm_irq_alloc_generic_chip - Allocate and initialize a generic chip
2071c3e3630SBartosz Golaszewski  *                               for a managed device
2081c3e3630SBartosz Golaszewski  * @dev:	Device to allocate the generic chip for
2091c3e3630SBartosz Golaszewski  * @name:	Name of the irq chip
2101c3e3630SBartosz Golaszewski  * @num_ct:	Number of irq_chip_type instances associated with this
2111c3e3630SBartosz Golaszewski  * @irq_base:	Interrupt base nr for this chip
2121c3e3630SBartosz Golaszewski  * @reg_base:	Register base address (virtual)
2131c3e3630SBartosz Golaszewski  * @handler:	Default flow handler associated with this chip
2141c3e3630SBartosz Golaszewski  *
2151c3e3630SBartosz Golaszewski  * Returns an initialized irq_chip_generic structure. The chip defaults
2161c3e3630SBartosz Golaszewski  * to the primary (index 0) irq_chip_type and @handler
2171c3e3630SBartosz Golaszewski  */
2181c3e3630SBartosz Golaszewski struct irq_chip_generic *
2191c3e3630SBartosz Golaszewski devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct,
2201c3e3630SBartosz Golaszewski 			    unsigned int irq_base, void __iomem *reg_base,
2211c3e3630SBartosz Golaszewski 			    irq_flow_handler_t handler)
2221c3e3630SBartosz Golaszewski {
2231c3e3630SBartosz Golaszewski 	struct irq_chip_generic *gc;
2241c3e3630SBartosz Golaszewski 	unsigned long sz = sizeof(*gc) + num_ct * sizeof(struct irq_chip_type);
2251c3e3630SBartosz Golaszewski 
2261c3e3630SBartosz Golaszewski 	gc = devm_kzalloc(dev, sz, GFP_KERNEL);
2271c3e3630SBartosz Golaszewski 	if (gc)
2281c3e3630SBartosz Golaszewski 		irq_init_generic_chip(gc, name, num_ct,
2291c3e3630SBartosz Golaszewski 				      irq_base, reg_base, handler);
2301c3e3630SBartosz Golaszewski 
2311c3e3630SBartosz Golaszewski 	return gc;
2321c3e3630SBartosz Golaszewski }
2331c3e3630SBartosz Golaszewski EXPORT_SYMBOL_GPL(devm_irq_alloc_generic_chip);
23430fd8fc5SBartosz Golaszewski 
23530fd8fc5SBartosz Golaszewski struct irq_generic_chip_devres {
23630fd8fc5SBartosz Golaszewski 	struct irq_chip_generic *gc;
23730fd8fc5SBartosz Golaszewski 	u32 msk;
23830fd8fc5SBartosz Golaszewski 	unsigned int clr;
23930fd8fc5SBartosz Golaszewski 	unsigned int set;
24030fd8fc5SBartosz Golaszewski };
24130fd8fc5SBartosz Golaszewski 
24230fd8fc5SBartosz Golaszewski static void devm_irq_remove_generic_chip(struct device *dev, void *res)
24330fd8fc5SBartosz Golaszewski {
24430fd8fc5SBartosz Golaszewski 	struct irq_generic_chip_devres *this = res;
24530fd8fc5SBartosz Golaszewski 
24630fd8fc5SBartosz Golaszewski 	irq_remove_generic_chip(this->gc, this->msk, this->clr, this->set);
24730fd8fc5SBartosz Golaszewski }
24830fd8fc5SBartosz Golaszewski 
24930fd8fc5SBartosz Golaszewski /**
25030fd8fc5SBartosz Golaszewski  * devm_irq_setup_generic_chip - Setup a range of interrupts with a generic
25130fd8fc5SBartosz Golaszewski  *                               chip for a managed device
25230fd8fc5SBartosz Golaszewski  *
25330fd8fc5SBartosz Golaszewski  * @dev:	Device to setup the generic chip for
25430fd8fc5SBartosz Golaszewski  * @gc:		Generic irq chip holding all data
25530fd8fc5SBartosz Golaszewski  * @msk:	Bitmask holding the irqs to initialize relative to gc->irq_base
25630fd8fc5SBartosz Golaszewski  * @flags:	Flags for initialization
25730fd8fc5SBartosz Golaszewski  * @clr:	IRQ_* bits to clear
25830fd8fc5SBartosz Golaszewski  * @set:	IRQ_* bits to set
25930fd8fc5SBartosz Golaszewski  *
26030fd8fc5SBartosz Golaszewski  * Set up max. 32 interrupts starting from gc->irq_base. Note, this
26130fd8fc5SBartosz Golaszewski  * initializes all interrupts to the primary irq_chip_type and its
26230fd8fc5SBartosz Golaszewski  * associated handler.
26330fd8fc5SBartosz Golaszewski  */
26430fd8fc5SBartosz Golaszewski int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
26530fd8fc5SBartosz Golaszewski 				u32 msk, enum irq_gc_flags flags,
26630fd8fc5SBartosz Golaszewski 				unsigned int clr, unsigned int set)
26730fd8fc5SBartosz Golaszewski {
26830fd8fc5SBartosz Golaszewski 	struct irq_generic_chip_devres *dr;
26930fd8fc5SBartosz Golaszewski 
27030fd8fc5SBartosz Golaszewski 	dr = devres_alloc(devm_irq_remove_generic_chip,
27130fd8fc5SBartosz Golaszewski 			  sizeof(*dr), GFP_KERNEL);
27230fd8fc5SBartosz Golaszewski 	if (!dr)
27330fd8fc5SBartosz Golaszewski 		return -ENOMEM;
27430fd8fc5SBartosz Golaszewski 
27530fd8fc5SBartosz Golaszewski 	irq_setup_generic_chip(gc, msk, flags, clr, set);
27630fd8fc5SBartosz Golaszewski 
27730fd8fc5SBartosz Golaszewski 	dr->gc = gc;
27830fd8fc5SBartosz Golaszewski 	dr->msk = msk;
27930fd8fc5SBartosz Golaszewski 	dr->clr = clr;
28030fd8fc5SBartosz Golaszewski 	dr->set = set;
28130fd8fc5SBartosz Golaszewski 	devres_add(dev, dr);
28230fd8fc5SBartosz Golaszewski 
28330fd8fc5SBartosz Golaszewski 	return 0;
28430fd8fc5SBartosz Golaszewski }
28530fd8fc5SBartosz Golaszewski EXPORT_SYMBOL_GPL(devm_irq_setup_generic_chip);
2861c3e3630SBartosz Golaszewski #endif /* CONFIG_GENERIC_IRQ_CHIP */
287