Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "internals.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Device resource management aware IRQ request/free implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) struct irq_devres {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	void *dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static void devm_irq_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	struct irq_devres *this = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	free_irq(this->irq, this->dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static int devm_irq_match(struct device *dev, void *res, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct irq_devres *this = res, *match = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	return this->irq == match->irq && this->dev_id == match->dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *	devm_request_threaded_irq - allocate an interrupt line for a managed device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *	@dev: device to request interrupt for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *	@irq: Interrupt line to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *	@handler: Function to be called when the IRQ occurs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *	@thread_fn: function to be called in a threaded interrupt context. NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *		    for devices which handle everything in @handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *	@irqflags: Interrupt type flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *	@devname: An ascii name for the claiming device, dev_name(dev) if NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *	@dev_id: A cookie passed back to the handler function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *	Except for the extra @dev argument, this function takes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *	same arguments and performs the same function as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *	request_threaded_irq().  IRQs requested with this function will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  *	automatically freed on driver detach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *	If an IRQ allocated with this function needs to be freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *	separately, devm_free_irq() must be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) int devm_request_threaded_irq(struct device *dev, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			      irq_handler_t handler, irq_handler_t thread_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			      unsigned long irqflags, const char *devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			      void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	struct irq_devres *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (!dr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (!devname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		devname = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 				  dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		devres_free(dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	dr->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	dr->dev_id = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	devres_add(dev, dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) EXPORT_SYMBOL(devm_request_threaded_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *	devm_request_any_context_irq - allocate an interrupt line for a managed device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *	@dev: device to request interrupt for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *	@irq: Interrupt line to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *	@handler: Function to be called when the IRQ occurs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *	@irqflags: Interrupt type flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *	@devname: An ascii name for the claiming device, dev_name(dev) if NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *	@dev_id: A cookie passed back to the handler function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *	Except for the extra @dev argument, this function takes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *	same arguments and performs the same function as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *	request_any_context_irq().  IRQs requested with this function will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *	automatically freed on driver detach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *	If an IRQ allocated with this function needs to be freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *	separately, devm_free_irq() must be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) int devm_request_any_context_irq(struct device *dev, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			      irq_handler_t handler, unsigned long irqflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			      const char *devname, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct irq_devres *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (!dr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (!devname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		devname = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		devres_free(dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	dr->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	dr->dev_id = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	devres_add(dev, dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) EXPORT_SYMBOL(devm_request_any_context_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *	devm_free_irq - free an interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  *	@dev: device to free interrupt for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *	@irq: Interrupt line to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  *	@dev_id: Device identity to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *	Except for the extra @dev argument, this function takes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *	same arguments and performs the same function as free_irq().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  *	This function instead of free_irq() should be used to manually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  *	free IRQs allocated with devm_request_irq().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct irq_devres match_data = { irq, dev_id };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			       &match_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	free_irq(irq, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) EXPORT_SYMBOL(devm_free_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct irq_desc_devres {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	unsigned int from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	unsigned int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void devm_irq_desc_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct irq_desc_devres *this = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	irq_free_descs(this->from, this->cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * __devm_irq_alloc_descs - Allocate and initialize a range of irq descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  *			    for a managed device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  * @dev:	Device to allocate the descriptors for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * @irq:	Allocate for specific irq number if irq >= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * @from:	Start the search from this irq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * @cnt:	Number of consecutive irqs to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * @node:	Preferred node on which the irq descriptor should be allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * @owner:	Owning module (can be NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * @affinity:	Optional pointer to an irq_affinity_desc array of size @cnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  *		which hints where the irq descriptors should be allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  *		and which default affinities to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * Returns the first irq number or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * Note: Use the provided wrappers (devm_irq_alloc_desc*) for simplicity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			   unsigned int cnt, int node, struct module *owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			   const struct irq_affinity_desc *affinity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct irq_desc_devres *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	dr = devres_alloc(devm_irq_desc_release, sizeof(*dr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (!dr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	base = __irq_alloc_descs(irq, from, cnt, node, owner, affinity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (base < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		devres_free(dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	dr->from = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	dr->cnt = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	devres_add(dev, dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) EXPORT_SYMBOL_GPL(__devm_irq_alloc_descs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #ifdef CONFIG_GENERIC_IRQ_CHIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * devm_irq_alloc_generic_chip - Allocate and initialize a generic chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  *                               for a managed device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * @dev:	Device to allocate the generic chip for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * @name:	Name of the irq chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * @num_ct:	Number of irq_chip_type instances associated with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * @irq_base:	Interrupt base nr for this chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * @reg_base:	Register base address (virtual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * @handler:	Default flow handler associated with this chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Returns an initialized irq_chip_generic structure. The chip defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * to the primary (index 0) irq_chip_type and @handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct irq_chip_generic *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			    unsigned int irq_base, void __iomem *reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			    irq_flow_handler_t handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct irq_chip_generic *gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	gc = devm_kzalloc(dev, struct_size(gc, chip_types, num_ct), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		irq_init_generic_chip(gc, name, num_ct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				      irq_base, reg_base, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	return gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) EXPORT_SYMBOL_GPL(devm_irq_alloc_generic_chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct irq_generic_chip_devres {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct irq_chip_generic *gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	u32 msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	unsigned int clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	unsigned int set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void devm_irq_remove_generic_chip(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	struct irq_generic_chip_devres *this = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	irq_remove_generic_chip(this->gc, this->msk, this->clr, this->set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * devm_irq_setup_generic_chip - Setup a range of interrupts with a generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *                               chip for a managed device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * @dev:	Device to setup the generic chip for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * @gc:		Generic irq chip holding all data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * @msk:	Bitmask holding the irqs to initialize relative to gc->irq_base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * @flags:	Flags for initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * @clr:	IRQ_* bits to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * @set:	IRQ_* bits to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  * Set up max. 32 interrupts starting from gc->irq_base. Note, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  * initializes all interrupts to the primary irq_chip_type and its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  * associated handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				u32 msk, enum irq_gc_flags flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				unsigned int clr, unsigned int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	struct irq_generic_chip_devres *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	dr = devres_alloc(devm_irq_remove_generic_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			  sizeof(*dr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (!dr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	irq_setup_generic_chip(gc, msk, flags, clr, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	dr->gc = gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	dr->msk = msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	dr->clr = clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	dr->set = set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	devres_add(dev, dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) EXPORT_SYMBOL_GPL(devm_irq_setup_generic_chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #endif /* CONFIG_GENERIC_IRQ_CHIP */