xref: /linux-6.15/include/linux/irqdomain.h (revision 9f98a4f4)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * irq_domain - IRQ translation domains
4  *
5  * Translation infrastructure between hw and linux irq numbers.  This is
6  * helpful for interrupt controllers to implement mapping between hardware
7  * irq numbers and the Linux irq number space.
8  *
9  * irq_domains also have hooks for translating device tree or other
10  * firmware interrupt representations into a hardware irq number that
11  * can be mapped back to a Linux irq number without any extra platform
12  * support code.
13  *
14  * Interrupt controller "domain" data structure. This could be defined as a
15  * irq domain controller. That is, it handles the mapping between hardware
16  * and virtual interrupt numbers for a given interrupt domain. The domain
17  * structure is generally created by the PIC code for a given PIC instance
18  * (though a domain can cover more than one PIC if they have a flat number
19  * model). It's the domain callbacks that are responsible for setting the
20  * irq_chip on a given irq_desc after it's been mapped.
21  *
22  * The host code and data structures use a fwnode_handle pointer to
23  * identify the domain. In some cases, and in order to preserve source
24  * code compatibility, this fwnode pointer is "upgraded" to a DT
25  * device_node. For those firmware infrastructures that do not provide
26  * a unique identifier for an interrupt controller, the irq_domain
27  * code offers a fwnode allocator.
28  */
29 
30 #ifndef _LINUX_IRQDOMAIN_H
31 #define _LINUX_IRQDOMAIN_H
32 
33 #include <linux/types.h>
34 #include <linux/irqdomain_defs.h>
35 #include <linux/irqhandler.h>
36 #include <linux/of.h>
37 #include <linux/mutex.h>
38 #include <linux/radix-tree.h>
39 
40 struct device_node;
41 struct fwnode_handle;
42 struct irq_domain;
43 struct irq_chip;
44 struct irq_data;
45 struct irq_desc;
46 struct cpumask;
47 struct seq_file;
48 struct irq_affinity_desc;
49 struct msi_parent_ops;
50 
51 #define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
52 
53 /**
54  * struct irq_fwspec - generic IRQ specifier structure
55  *
56  * @fwnode:		Pointer to a firmware-specific descriptor
57  * @param_count:	Number of device-specific parameters
58  * @param:		Device-specific parameters
59  *
60  * This structure, directly modeled after of_phandle_args, is used to
61  * pass a device-specific description of an interrupt.
62  */
63 struct irq_fwspec {
64 	struct fwnode_handle *fwnode;
65 	int param_count;
66 	u32 param[IRQ_DOMAIN_IRQ_SPEC_PARAMS];
67 };
68 
69 /* Conversion function from of_phandle_args fields to fwspec  */
70 void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args,
71 			       unsigned int count, struct irq_fwspec *fwspec);
72 
73 /**
74  * struct irq_domain_ops - Methods for irq_domain objects
75  * @match: Match an interrupt controller device node to a host, returns
76  *         1 on a match
77  * @select: Match an interrupt controller fw specification. It is more generic
78  *	    than @match as it receives a complete struct irq_fwspec. Therefore,
79  *	    @select is preferred if provided. Returns 1 on a match.
80  * @map: Create or update a mapping between a virtual irq number and a hw
81  *       irq number. This is called only once for a given mapping.
82  * @unmap: Dispose of such a mapping
83  * @xlate: Given a device tree node and interrupt specifier, decode
84  *         the hardware irq number and linux irq type value.
85  * @alloc: Allocate @nr_irqs interrupts starting from @virq.
86  * @free: Free @nr_irqs interrupts starting from @virq.
87  * @activate: Activate one interrupt in HW (@irqd). If @reserve is set, only
88  *	      reserve the vector. If unset, assign the vector (called from
89  *	      request_irq()).
90  * @deactivate: Disarm one interrupt (@irqd).
91  * @translate: Given @fwspec, decode the hardware irq number (@out_hwirq) and
92  *	       linux irq type value (@out_type). This is a generalised @xlate
93  *	       (over struct irq_fwspec) and is preferred if provided.
94  * @debug_show: For domains to show specific data for an interrupt in debugfs.
95  *
96  * Functions below are provided by the driver and called whenever a new mapping
97  * is created or an old mapping is disposed. The driver can then proceed to
98  * whatever internal data structures management is required. It also needs
99  * to setup the irq_desc when returning from map().
100  */
101 struct irq_domain_ops {
102 	int (*match)(struct irq_domain *d, struct device_node *node,
103 		     enum irq_domain_bus_token bus_token);
104 	int (*select)(struct irq_domain *d, struct irq_fwspec *fwspec,
105 		      enum irq_domain_bus_token bus_token);
106 	int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
107 	void (*unmap)(struct irq_domain *d, unsigned int virq);
108 	int (*xlate)(struct irq_domain *d, struct device_node *node,
109 		     const u32 *intspec, unsigned int intsize,
110 		     unsigned long *out_hwirq, unsigned int *out_type);
111 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
112 	/* extended V2 interfaces to support hierarchy irq_domains */
113 	int (*alloc)(struct irq_domain *d, unsigned int virq,
114 		     unsigned int nr_irqs, void *arg);
115 	void (*free)(struct irq_domain *d, unsigned int virq,
116 		     unsigned int nr_irqs);
117 	int (*activate)(struct irq_domain *d, struct irq_data *irqd, bool reserve);
118 	void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data);
119 	int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec,
120 			 unsigned long *out_hwirq, unsigned int *out_type);
121 #endif
122 #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
123 	void (*debug_show)(struct seq_file *m, struct irq_domain *d,
124 			   struct irq_data *irqd, int ind);
125 #endif
126 };
127 
128 extern const struct irq_domain_ops irq_generic_chip_ops;
129 
130 struct irq_domain_chip_generic;
131 
132 /**
133  * struct irq_domain - Hardware interrupt number translation object
134  * @link:	Element in global irq_domain list.
135  * @name:	Name of interrupt domain
136  * @ops:	Pointer to irq_domain methods
137  * @host_data:	Private data pointer for use by owner.  Not touched by irq_domain
138  *		core code.
139  * @flags:	Per irq_domain flags
140  * @mapcount:	The number of mapped interrupts
141  * @mutex:	Domain lock, hierarchical domains use root domain's lock
142  * @root:	Pointer to root domain, or containing structure if non-hierarchical
143  *
144  * Optional elements:
145  * @fwnode:	Pointer to firmware node associated with the irq_domain. Pretty easy
146  *		to swap it for the of_node via the irq_domain_get_of_node accessor
147  * @bus_token:	@fwnode's device_node might be used for several irq domains. But
148  *		in connection with @bus_token, the pair shall be unique in a
149  *		system.
150  * @gc:		Pointer to a list of generic chips. There is a helper function for
151  *		setting up one or more generic chips for interrupt controllers
152  *		drivers using the generic chip library which uses this pointer.
153  * @dev:	Pointer to the device which instantiated the irqdomain
154  *		With per device irq domains this is not necessarily the same
155  *		as @pm_dev.
156  * @pm_dev:	Pointer to a device that can be utilized for power management
157  *		purposes related to the irq domain.
158  * @parent:	Pointer to parent irq_domain to support hierarchy irq_domains
159  * @msi_parent_ops: Pointer to MSI parent domain methods for per device domain init
160  * @exit:	Function called when the domain is destroyed
161  *
162  * Revmap data, used internally by the irq domain code:
163  * @hwirq_max:		Top limit for the HW irq number. Especially to avoid
164  *			conflicts/failures with reserved HW irqs. Can be ~0.
165  * @revmap_size:	Size of the linear map table @revmap
166  * @revmap_tree:	Radix map tree for hwirqs that don't fit in the linear map
167  * @revmap:		Linear table of irq_data pointers
168  */
169 struct irq_domain {
170 	struct list_head		link;
171 	const char			*name;
172 	const struct irq_domain_ops	*ops;
173 	void				*host_data;
174 	unsigned int			flags;
175 	unsigned int			mapcount;
176 	struct mutex			mutex;
177 	struct irq_domain		*root;
178 
179 	/* Optional data */
180 	struct fwnode_handle		*fwnode;
181 	enum irq_domain_bus_token	bus_token;
182 	struct irq_domain_chip_generic	*gc;
183 	struct device			*dev;
184 	struct device			*pm_dev;
185 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
186 	struct irq_domain		*parent;
187 #endif
188 #ifdef CONFIG_GENERIC_MSI_IRQ
189 	const struct msi_parent_ops	*msi_parent_ops;
190 #endif
191 	void				(*exit)(struct irq_domain *d);
192 
193 	/* reverse map data. The linear map gets appended to the irq_domain */
194 	irq_hw_number_t			hwirq_max;
195 	unsigned int			revmap_size;
196 	struct radix_tree_root		revmap_tree;
197 	struct irq_data __rcu		*revmap[] __counted_by(revmap_size);
198 };
199 
200 /* Irq domain flags */
201 enum {
202 	/* Irq domain is hierarchical */
203 	IRQ_DOMAIN_FLAG_HIERARCHY	= (1 << 0),
204 
205 	/* Irq domain name was allocated internally */
206 	IRQ_DOMAIN_NAME_ALLOCATED	= (1 << 1),
207 
208 	/* Irq domain is an IPI domain with virq per cpu */
209 	IRQ_DOMAIN_FLAG_IPI_PER_CPU	= (1 << 2),
210 
211 	/* Irq domain is an IPI domain with single virq */
212 	IRQ_DOMAIN_FLAG_IPI_SINGLE	= (1 << 3),
213 
214 	/* Irq domain implements MSIs */
215 	IRQ_DOMAIN_FLAG_MSI		= (1 << 4),
216 
217 	/*
218 	 * Irq domain implements isolated MSI, see msi_device_has_isolated_msi()
219 	 */
220 	IRQ_DOMAIN_FLAG_ISOLATED_MSI	= (1 << 5),
221 
222 	/* Irq domain doesn't translate anything */
223 	IRQ_DOMAIN_FLAG_NO_MAP		= (1 << 6),
224 
225 	/* Irq domain is a MSI parent domain */
226 	IRQ_DOMAIN_FLAG_MSI_PARENT	= (1 << 8),
227 
228 	/* Irq domain is a MSI device domain */
229 	IRQ_DOMAIN_FLAG_MSI_DEVICE	= (1 << 9),
230 
231 	/* Irq domain must destroy generic chips when removed */
232 	IRQ_DOMAIN_FLAG_DESTROY_GC	= (1 << 10),
233 
234 	/*
235 	 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
236 	 * for implementation specific purposes and ignored by the
237 	 * core code.
238 	 */
239 	IRQ_DOMAIN_FLAG_NONCORE		= (1 << 16),
240 };
241 
242 static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
243 {
244 	return to_of_node(d->fwnode);
245 }
246 
247 static inline void irq_domain_set_pm_device(struct irq_domain *d,
248 					    struct device *dev)
249 {
250 	if (d)
251 		d->pm_dev = dev;
252 }
253 
254 #ifdef CONFIG_IRQ_DOMAIN
255 struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id,
256 						const char *name, phys_addr_t *pa);
257 
258 enum {
259 	IRQCHIP_FWNODE_REAL,
260 	IRQCHIP_FWNODE_NAMED,
261 	IRQCHIP_FWNODE_NAMED_ID,
262 };
263 
264 static inline
265 struct fwnode_handle *irq_domain_alloc_named_fwnode(const char *name)
266 {
267 	return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED, 0, name, NULL);
268 }
269 
270 static inline
271 struct fwnode_handle *irq_domain_alloc_named_id_fwnode(const char *name, int id)
272 {
273 	return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED_ID, id, name,
274 					 NULL);
275 }
276 
277 static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
278 {
279 	return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_REAL, 0, NULL, pa);
280 }
281 
282 void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
283 
284 DEFINE_FREE(irq_domain_free_fwnode, struct fwnode_handle *, if (_T) irq_domain_free_fwnode(_T))
285 
286 struct irq_domain_chip_generic_info;
287 
288 /**
289  * struct irq_domain_info - Domain information structure
290  * @fwnode:		firmware node for the interrupt controller
291  * @domain_flags:	Additional flags to add to the domain flags
292  * @size:		Size of linear map; 0 for radix mapping only
293  * @hwirq_max:		Maximum number of interrupts supported by controller
294  * @direct_max:		Maximum value of direct maps;
295  *			Use ~0 for no limit; 0 for no direct mapping
296  * @hwirq_base:		The first hardware interrupt number (legacy domains only)
297  * @virq_base:		The first Linux interrupt number for legacy domains to
298  *			immediately associate the interrupts after domain creation
299  * @bus_token:		Domain bus token
300  * @name_suffix:	Optional name suffix to avoid collisions when multiple
301  *			domains are added using same fwnode
302  * @ops:		Domain operation callbacks
303  * @host_data:		Controller private data pointer
304  * @dgc_info:		Geneneric chip information structure pointer used to
305  *			create generic chips for the domain if not NULL.
306  * @init:		Function called when the domain is created.
307  *			Allow to do some additional domain initialisation.
308  * @exit:		Function called when the domain is destroyed.
309  *			Allow to do some additional cleanup operation.
310  */
311 struct irq_domain_info {
312 	struct fwnode_handle			*fwnode;
313 	unsigned int				domain_flags;
314 	unsigned int				size;
315 	irq_hw_number_t				hwirq_max;
316 	int					direct_max;
317 	unsigned int				hwirq_base;
318 	unsigned int				virq_base;
319 	enum irq_domain_bus_token		bus_token;
320 	const char				*name_suffix;
321 	const struct irq_domain_ops		*ops;
322 	void					*host_data;
323 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
324 	/**
325 	 * @parent: Pointer to the parent irq domain used in a hierarchy domain
326 	 */
327 	struct irq_domain			*parent;
328 #endif
329 	struct irq_domain_chip_generic_info	*dgc_info;
330 	int					(*init)(struct irq_domain *d);
331 	void					(*exit)(struct irq_domain *d);
332 };
333 
334 struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
335 struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
336 					       const struct irq_domain_info *info);
337 
338 struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
339 					    unsigned int size,
340 					    unsigned int first_irq,
341 					    const struct irq_domain_ops *ops,
342 					    void *host_data);
343 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
344 					 unsigned int size,
345 					 unsigned int first_irq,
346 					 irq_hw_number_t first_hwirq,
347 					 const struct irq_domain_ops *ops,
348 					 void *host_data);
349 struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
350 					    unsigned int size,
351 					    unsigned int first_irq,
352 					    irq_hw_number_t first_hwirq,
353 					    const struct irq_domain_ops *ops,
354 					    void *host_data);
355 struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
356 					    enum irq_domain_bus_token bus_token);
357 void irq_set_default_host(struct irq_domain *host);
358 struct irq_domain *irq_get_default_host(void);
359 int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
360 			   irq_hw_number_t hwirq, int node,
361 			   const struct irq_affinity_desc *affinity);
362 
363 static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
364 {
365 	return node ? &node->fwnode : NULL;
366 }
367 
368 extern const struct fwnode_operations irqchip_fwnode_ops;
369 
370 static inline bool is_fwnode_irqchip(const struct fwnode_handle *fwnode)
371 {
372 	return fwnode && fwnode->ops == &irqchip_fwnode_ops;
373 }
374 
375 void irq_domain_update_bus_token(struct irq_domain *domain,
376 				 enum irq_domain_bus_token bus_token);
377 
378 static inline
379 struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
380 					    enum irq_domain_bus_token bus_token)
381 {
382 	struct irq_fwspec fwspec = {
383 		.fwnode = fwnode,
384 	};
385 
386 	return irq_find_matching_fwspec(&fwspec, bus_token);
387 }
388 
389 static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
390 							enum irq_domain_bus_token bus_token)
391 {
392 	return irq_find_matching_fwnode(of_node_to_fwnode(node), bus_token);
393 }
394 
395 static inline struct irq_domain *irq_find_host(struct device_node *node)
396 {
397 	struct irq_domain *d;
398 
399 	d = irq_find_matching_host(node, DOMAIN_BUS_WIRED);
400 	if (!d)
401 		d = irq_find_matching_host(node, DOMAIN_BUS_ANY);
402 
403 	return d;
404 }
405 
406 static inline struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
407 						       unsigned int size,
408 						       unsigned int first_irq,
409 						       const struct irq_domain_ops *ops,
410 						       void *host_data)
411 {
412 	return irq_domain_create_simple(of_node_to_fwnode(of_node), size, first_irq, ops, host_data);
413 }
414 
415 /**
416  * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
417  * @of_node: pointer to interrupt controller's device tree node.
418  * @size: Number of interrupts in the domain.
419  * @ops: map/unmap domain callbacks
420  * @host_data: Controller private data pointer
421  */
422 static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
423 					 unsigned int size,
424 					 const struct irq_domain_ops *ops,
425 					 void *host_data)
426 {
427 	struct irq_domain_info info = {
428 		.fwnode		= of_node_to_fwnode(of_node),
429 		.size		= size,
430 		.hwirq_max	= size,
431 		.ops		= ops,
432 		.host_data	= host_data,
433 	};
434 	struct irq_domain *d;
435 
436 	d = irq_domain_instantiate(&info);
437 	return IS_ERR(d) ? NULL : d;
438 }
439 
440 #ifdef CONFIG_IRQ_DOMAIN_NOMAP
441 static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
442 					 unsigned int max_irq,
443 					 const struct irq_domain_ops *ops,
444 					 void *host_data)
445 {
446 	struct irq_domain_info info = {
447 		.fwnode		= of_node_to_fwnode(of_node),
448 		.hwirq_max	= max_irq,
449 		.direct_max	= max_irq,
450 		.ops		= ops,
451 		.host_data	= host_data,
452 	};
453 	struct irq_domain *d;
454 
455 	d = irq_domain_instantiate(&info);
456 	return IS_ERR(d) ? NULL : d;
457 }
458 
459 unsigned int irq_create_direct_mapping(struct irq_domain *host);
460 #endif
461 
462 static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
463 					 const struct irq_domain_ops *ops,
464 					 void *host_data)
465 {
466 	struct irq_domain_info info = {
467 		.fwnode		= of_node_to_fwnode(of_node),
468 		.hwirq_max	= ~0U,
469 		.ops		= ops,
470 		.host_data	= host_data,
471 	};
472 	struct irq_domain *d;
473 
474 	d = irq_domain_instantiate(&info);
475 	return IS_ERR(d) ? NULL : d;
476 }
477 
478 static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
479 					 unsigned int size,
480 					 const struct irq_domain_ops *ops,
481 					 void *host_data)
482 {
483 	struct irq_domain_info info = {
484 		.fwnode		= fwnode,
485 		.size		= size,
486 		.hwirq_max	= size,
487 		.ops		= ops,
488 		.host_data	= host_data,
489 	};
490 	struct irq_domain *d;
491 
492 	d = irq_domain_instantiate(&info);
493 	return IS_ERR(d) ? NULL : d;
494 }
495 
496 static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
497 					 const struct irq_domain_ops *ops,
498 					 void *host_data)
499 {
500 	struct irq_domain_info info = {
501 		.fwnode		= fwnode,
502 		.hwirq_max	= ~0,
503 		.ops		= ops,
504 		.host_data	= host_data,
505 	};
506 	struct irq_domain *d;
507 
508 	d = irq_domain_instantiate(&info);
509 	return IS_ERR(d) ? NULL : d;
510 }
511 
512 void irq_domain_remove(struct irq_domain *host);
513 
514 int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
515 			 irq_hw_number_t hwirq);
516 void irq_domain_associate_many(struct irq_domain *domain,
517 			       unsigned int irq_base,
518 			       irq_hw_number_t hwirq_base, int count);
519 
520 unsigned int irq_create_mapping_affinity(struct irq_domain *host,
521 					 irq_hw_number_t hwirq,
522 					 const struct irq_affinity_desc *affinity);
523 unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
524 void irq_dispose_mapping(unsigned int virq);
525 
526 static inline unsigned int irq_create_mapping(struct irq_domain *host,
527 					      irq_hw_number_t hwirq)
528 {
529 	return irq_create_mapping_affinity(host, hwirq, NULL);
530 }
531 
532 struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
533 				       irq_hw_number_t hwirq,
534 				       unsigned int *irq);
535 
536 static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
537 						   irq_hw_number_t hwirq)
538 {
539 	return __irq_resolve_mapping(domain, hwirq, NULL);
540 }
541 
542 /**
543  * irq_find_mapping() - Find a linux irq from a hw irq number.
544  * @domain: domain owning this hardware interrupt
545  * @hwirq: hardware irq number in that domain space
546  */
547 static inline unsigned int irq_find_mapping(struct irq_domain *domain,
548 					    irq_hw_number_t hwirq)
549 {
550 	unsigned int irq;
551 
552 	if (__irq_resolve_mapping(domain, hwirq, &irq))
553 		return irq;
554 
555 	return 0;
556 }
557 
558 static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
559 					     irq_hw_number_t hwirq)
560 {
561 	return irq_find_mapping(domain, hwirq);
562 }
563 
564 extern const struct irq_domain_ops irq_domain_simple_ops;
565 
566 /* stock xlate functions */
567 int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
568 			const u32 *intspec, unsigned int intsize,
569 			irq_hw_number_t *out_hwirq, unsigned int *out_type);
570 int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
571 			const u32 *intspec, unsigned int intsize,
572 			irq_hw_number_t *out_hwirq, unsigned int *out_type);
573 int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
574 			const u32 *intspec, unsigned int intsize,
575 			irq_hw_number_t *out_hwirq, unsigned int *out_type);
576 
577 int irq_domain_translate_twocell(struct irq_domain *d,
578 				 struct irq_fwspec *fwspec,
579 				 unsigned long *out_hwirq,
580 				 unsigned int *out_type);
581 
582 int irq_domain_translate_onecell(struct irq_domain *d,
583 				 struct irq_fwspec *fwspec,
584 				 unsigned long *out_hwirq,
585 				 unsigned int *out_type);
586 
587 /* IPI functions */
588 int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
589 int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
590 
591 /* V2 interfaces to support hierarchy IRQ domains. */
592 struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
593 					 unsigned int virq);
594 void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
595 			 irq_hw_number_t hwirq,
596 			 const struct irq_chip *chip,
597 			 void *chip_data, irq_flow_handler_t handler,
598 			 void *handler_data, const char *handler_name);
599 void irq_domain_reset_irq_data(struct irq_data *irq_data);
600 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
601 struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
602 					       unsigned int flags,
603 					       unsigned int size,
604 					       struct fwnode_handle *fwnode,
605 					       const struct irq_domain_ops *ops,
606 					       void *host_data);
607 
608 static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
609 					    unsigned int flags,
610 					    unsigned int size,
611 					    struct device_node *node,
612 					    const struct irq_domain_ops *ops,
613 					    void *host_data)
614 {
615 	return irq_domain_create_hierarchy(parent, flags, size,
616 					   of_node_to_fwnode(node),
617 					   ops, host_data);
618 }
619 
620 int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
621 			    unsigned int nr_irqs, int node, void *arg,
622 			    bool realloc,
623 			    const struct irq_affinity_desc *affinity);
624 void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
625 int irq_domain_activate_irq(struct irq_data *irq_data, bool early);
626 void irq_domain_deactivate_irq(struct irq_data *irq_data);
627 
628 static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
629 			unsigned int nr_irqs, int node, void *arg)
630 {
631 	return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false,
632 				       NULL);
633 }
634 
635 int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
636 				  unsigned int virq,
637 				  irq_hw_number_t hwirq,
638 				  const struct irq_chip *chip,
639 				  void *chip_data);
640 void irq_domain_free_irqs_common(struct irq_domain *domain,
641 				 unsigned int virq,
642 				 unsigned int nr_irqs);
643 void irq_domain_free_irqs_top(struct irq_domain *domain,
644 			      unsigned int virq, unsigned int nr_irqs);
645 
646 int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
647 int irq_domain_pop_irq(struct irq_domain *domain, int virq);
648 
649 int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
650 				 unsigned int irq_base,
651 				 unsigned int nr_irqs, void *arg);
652 
653 void irq_domain_free_irqs_parent(struct irq_domain *domain,
654 				 unsigned int irq_base,
655 				 unsigned int nr_irqs);
656 
657 int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
658 					   unsigned int virq);
659 
660 static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
661 {
662 	return domain->flags & IRQ_DOMAIN_FLAG_HIERARCHY;
663 }
664 
665 static inline bool irq_domain_is_ipi(struct irq_domain *domain)
666 {
667 	return domain->flags &
668 		(IRQ_DOMAIN_FLAG_IPI_PER_CPU | IRQ_DOMAIN_FLAG_IPI_SINGLE);
669 }
670 
671 static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
672 {
673 	return domain->flags & IRQ_DOMAIN_FLAG_IPI_PER_CPU;
674 }
675 
676 static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
677 {
678 	return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
679 }
680 
681 static inline bool irq_domain_is_msi(struct irq_domain *domain)
682 {
683 	return domain->flags & IRQ_DOMAIN_FLAG_MSI;
684 }
685 
686 static inline bool irq_domain_is_msi_parent(struct irq_domain *domain)
687 {
688 	return domain->flags & IRQ_DOMAIN_FLAG_MSI_PARENT;
689 }
690 
691 static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
692 {
693 	return domain->flags & IRQ_DOMAIN_FLAG_MSI_DEVICE;
694 }
695 
696 #else	/* CONFIG_IRQ_DOMAIN_HIERARCHY */
697 static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
698 			unsigned int nr_irqs, int node, void *arg)
699 {
700 	return -1;
701 }
702 
703 static inline void irq_domain_free_irqs(unsigned int virq,
704 					unsigned int nr_irqs) { }
705 
706 static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
707 {
708 	return false;
709 }
710 
711 static inline bool irq_domain_is_ipi(struct irq_domain *domain)
712 {
713 	return false;
714 }
715 
716 static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
717 {
718 	return false;
719 }
720 
721 static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
722 {
723 	return false;
724 }
725 
726 static inline bool irq_domain_is_msi(struct irq_domain *domain)
727 {
728 	return false;
729 }
730 
731 static inline bool irq_domain_is_msi_parent(struct irq_domain *domain)
732 {
733 	return false;
734 }
735 
736 static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
737 {
738 	return false;
739 }
740 
741 #endif	/* CONFIG_IRQ_DOMAIN_HIERARCHY */
742 
743 #ifdef CONFIG_GENERIC_MSI_IRQ
744 int msi_device_domain_alloc_wired(struct irq_domain *domain, unsigned int hwirq,
745 				  unsigned int type);
746 void msi_device_domain_free_wired(struct irq_domain *domain, unsigned int virq);
747 #else
748 static inline int msi_device_domain_alloc_wired(struct irq_domain *domain, unsigned int hwirq,
749 						unsigned int type)
750 {
751 	WARN_ON_ONCE(1);
752 	return -EINVAL;
753 }
754 static inline void msi_device_domain_free_wired(struct irq_domain *domain, unsigned int virq)
755 {
756 	WARN_ON_ONCE(1);
757 }
758 #endif
759 
760 #else /* CONFIG_IRQ_DOMAIN */
761 static inline void irq_dispose_mapping(unsigned int virq) { }
762 static inline struct irq_domain *irq_find_matching_fwnode(
763 	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
764 {
765 	return NULL;
766 }
767 #endif /* !CONFIG_IRQ_DOMAIN */
768 
769 #endif /* _LINUX_IRQDOMAIN_H */
770