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  
irq_domain_get_of_node(struct irq_domain * d)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  
irq_domain_set_pm_device(struct irq_domain * d,struct device * dev)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
irq_domain_alloc_named_fwnode(const char * name)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
irq_domain_alloc_named_id_fwnode(const char * name,int id)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  
irq_domain_alloc_fwnode(phys_addr_t * pa)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  struct irq_domain_chip_generic_info;
285  
286  /**
287   * struct irq_domain_info - Domain information structure
288   * @fwnode:		firmware node for the interrupt controller
289   * @domain_flags:	Additional flags to add to the domain flags
290   * @size:		Size of linear map; 0 for radix mapping only
291   * @hwirq_max:		Maximum number of interrupts supported by controller
292   * @direct_max:		Maximum value of direct maps;
293   *			Use ~0 for no limit; 0 for no direct mapping
294   * @hwirq_base:		The first hardware interrupt number (legacy domains only)
295   * @virq_base:		The first Linux interrupt number for legacy domains to
296   *			immediately associate the interrupts after domain creation
297   * @bus_token:		Domain bus token
298   * @name_suffix:	Optional name suffix to avoid collisions when multiple
299   *			domains are added using same fwnode
300   * @ops:		Domain operation callbacks
301   * @host_data:		Controller private data pointer
302   * @dgc_info:		Geneneric chip information structure pointer used to
303   *			create generic chips for the domain if not NULL.
304   * @init:		Function called when the domain is created.
305   *			Allow to do some additional domain initialisation.
306   * @exit:		Function called when the domain is destroyed.
307   *			Allow to do some additional cleanup operation.
308   */
309  struct irq_domain_info {
310  	struct fwnode_handle			*fwnode;
311  	unsigned int				domain_flags;
312  	unsigned int				size;
313  	irq_hw_number_t				hwirq_max;
314  	int					direct_max;
315  	unsigned int				hwirq_base;
316  	unsigned int				virq_base;
317  	enum irq_domain_bus_token		bus_token;
318  	const char				*name_suffix;
319  	const struct irq_domain_ops		*ops;
320  	void					*host_data;
321  #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
322  	/**
323  	 * @parent: Pointer to the parent irq domain used in a hierarchy domain
324  	 */
325  	struct irq_domain			*parent;
326  #endif
327  	struct irq_domain_chip_generic_info	*dgc_info;
328  	int					(*init)(struct irq_domain *d);
329  	void					(*exit)(struct irq_domain *d);
330  };
331  
332  struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
333  struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
334  					       const struct irq_domain_info *info);
335  
336  struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
337  					    unsigned int size,
338  					    unsigned int first_irq,
339  					    const struct irq_domain_ops *ops,
340  					    void *host_data);
341  struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
342  					 unsigned int size,
343  					 unsigned int first_irq,
344  					 irq_hw_number_t first_hwirq,
345  					 const struct irq_domain_ops *ops,
346  					 void *host_data);
347  struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
348  					    unsigned int size,
349  					    unsigned int first_irq,
350  					    irq_hw_number_t first_hwirq,
351  					    const struct irq_domain_ops *ops,
352  					    void *host_data);
353  extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
354  						   enum irq_domain_bus_token bus_token);
355  extern void irq_set_default_host(struct irq_domain *host);
356  extern struct irq_domain *irq_get_default_host(void);
357  extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
358  				  irq_hw_number_t hwirq, int node,
359  				  const struct irq_affinity_desc *affinity);
360  
of_node_to_fwnode(struct device_node * node)361  static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
362  {
363  	return node ? &node->fwnode : NULL;
364  }
365  
366  extern const struct fwnode_operations irqchip_fwnode_ops;
367  
is_fwnode_irqchip(const struct fwnode_handle * fwnode)368  static inline bool is_fwnode_irqchip(const struct fwnode_handle *fwnode)
369  {
370  	return fwnode && fwnode->ops == &irqchip_fwnode_ops;
371  }
372  
373  extern void irq_domain_update_bus_token(struct irq_domain *domain,
374  					enum irq_domain_bus_token bus_token);
375  
376  static inline
irq_find_matching_fwnode(struct fwnode_handle * fwnode,enum irq_domain_bus_token bus_token)377  struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
378  					    enum irq_domain_bus_token bus_token)
379  {
380  	struct irq_fwspec fwspec = {
381  		.fwnode = fwnode,
382  	};
383  
384  	return irq_find_matching_fwspec(&fwspec, bus_token);
385  }
386  
irq_find_matching_host(struct device_node * node,enum irq_domain_bus_token bus_token)387  static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
388  							enum irq_domain_bus_token bus_token)
389  {
390  	return irq_find_matching_fwnode(of_node_to_fwnode(node), bus_token);
391  }
392  
irq_find_host(struct device_node * node)393  static inline struct irq_domain *irq_find_host(struct device_node *node)
394  {
395  	struct irq_domain *d;
396  
397  	d = irq_find_matching_host(node, DOMAIN_BUS_WIRED);
398  	if (!d)
399  		d = irq_find_matching_host(node, DOMAIN_BUS_ANY);
400  
401  	return d;
402  }
403  
irq_domain_add_simple(struct device_node * of_node,unsigned int size,unsigned int first_irq,const struct irq_domain_ops * ops,void * host_data)404  static inline struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
405  						       unsigned int size,
406  						       unsigned int first_irq,
407  						       const struct irq_domain_ops *ops,
408  						       void *host_data)
409  {
410  	return irq_domain_create_simple(of_node_to_fwnode(of_node), size, first_irq, ops, host_data);
411  }
412  
413  /**
414   * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
415   * @of_node: pointer to interrupt controller's device tree node.
416   * @size: Number of interrupts in the domain.
417   * @ops: map/unmap domain callbacks
418   * @host_data: Controller private data pointer
419   */
irq_domain_add_linear(struct device_node * of_node,unsigned int size,const struct irq_domain_ops * ops,void * host_data)420  static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
421  					 unsigned int size,
422  					 const struct irq_domain_ops *ops,
423  					 void *host_data)
424  {
425  	struct irq_domain_info info = {
426  		.fwnode		= of_node_to_fwnode(of_node),
427  		.size		= size,
428  		.hwirq_max	= size,
429  		.ops		= ops,
430  		.host_data	= host_data,
431  	};
432  	struct irq_domain *d;
433  
434  	d = irq_domain_instantiate(&info);
435  	return IS_ERR(d) ? NULL : d;
436  }
437  
438  #ifdef CONFIG_IRQ_DOMAIN_NOMAP
irq_domain_add_nomap(struct device_node * of_node,unsigned int max_irq,const struct irq_domain_ops * ops,void * host_data)439  static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
440  					 unsigned int max_irq,
441  					 const struct irq_domain_ops *ops,
442  					 void *host_data)
443  {
444  	struct irq_domain_info info = {
445  		.fwnode		= of_node_to_fwnode(of_node),
446  		.hwirq_max	= max_irq,
447  		.direct_max	= max_irq,
448  		.ops		= ops,
449  		.host_data	= host_data,
450  	};
451  	struct irq_domain *d;
452  
453  	d = irq_domain_instantiate(&info);
454  	return IS_ERR(d) ? NULL : d;
455  }
456  
457  extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
458  #endif
459  
irq_domain_add_tree(struct device_node * of_node,const struct irq_domain_ops * ops,void * host_data)460  static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
461  					 const struct irq_domain_ops *ops,
462  					 void *host_data)
463  {
464  	struct irq_domain_info info = {
465  		.fwnode		= of_node_to_fwnode(of_node),
466  		.hwirq_max	= ~0U,
467  		.ops		= ops,
468  		.host_data	= host_data,
469  	};
470  	struct irq_domain *d;
471  
472  	d = irq_domain_instantiate(&info);
473  	return IS_ERR(d) ? NULL : d;
474  }
475  
irq_domain_create_linear(struct fwnode_handle * fwnode,unsigned int size,const struct irq_domain_ops * ops,void * host_data)476  static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
477  					 unsigned int size,
478  					 const struct irq_domain_ops *ops,
479  					 void *host_data)
480  {
481  	struct irq_domain_info info = {
482  		.fwnode		= fwnode,
483  		.size		= size,
484  		.hwirq_max	= size,
485  		.ops		= ops,
486  		.host_data	= host_data,
487  	};
488  	struct irq_domain *d;
489  
490  	d = irq_domain_instantiate(&info);
491  	return IS_ERR(d) ? NULL : d;
492  }
493  
irq_domain_create_tree(struct fwnode_handle * fwnode,const struct irq_domain_ops * ops,void * host_data)494  static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
495  					 const struct irq_domain_ops *ops,
496  					 void *host_data)
497  {
498  	struct irq_domain_info info = {
499  		.fwnode		= fwnode,
500  		.hwirq_max	= ~0,
501  		.ops		= ops,
502  		.host_data	= host_data,
503  	};
504  	struct irq_domain *d;
505  
506  	d = irq_domain_instantiate(&info);
507  	return IS_ERR(d) ? NULL : d;
508  }
509  
510  extern void irq_domain_remove(struct irq_domain *host);
511  
512  extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
513  					irq_hw_number_t hwirq);
514  extern void irq_domain_associate_many(struct irq_domain *domain,
515  				      unsigned int irq_base,
516  				      irq_hw_number_t hwirq_base, int count);
517  
518  extern unsigned int irq_create_mapping_affinity(struct irq_domain *host,
519  				      irq_hw_number_t hwirq,
520  				      const struct irq_affinity_desc *affinity);
521  extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
522  extern void irq_dispose_mapping(unsigned int virq);
523  
irq_create_mapping(struct irq_domain * host,irq_hw_number_t hwirq)524  static inline unsigned int irq_create_mapping(struct irq_domain *host,
525  					      irq_hw_number_t hwirq)
526  {
527  	return irq_create_mapping_affinity(host, hwirq, NULL);
528  }
529  
530  extern struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
531  					      irq_hw_number_t hwirq,
532  					      unsigned int *irq);
533  
irq_resolve_mapping(struct irq_domain * domain,irq_hw_number_t hwirq)534  static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
535  						   irq_hw_number_t hwirq)
536  {
537  	return __irq_resolve_mapping(domain, hwirq, NULL);
538  }
539  
540  /**
541   * irq_find_mapping() - Find a linux irq from a hw irq number.
542   * @domain: domain owning this hardware interrupt
543   * @hwirq: hardware irq number in that domain space
544   */
irq_find_mapping(struct irq_domain * domain,irq_hw_number_t hwirq)545  static inline unsigned int irq_find_mapping(struct irq_domain *domain,
546  					    irq_hw_number_t hwirq)
547  {
548  	unsigned int irq;
549  
550  	if (__irq_resolve_mapping(domain, hwirq, &irq))
551  		return irq;
552  
553  	return 0;
554  }
555  
irq_linear_revmap(struct irq_domain * domain,irq_hw_number_t hwirq)556  static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
557  					     irq_hw_number_t hwirq)
558  {
559  	return irq_find_mapping(domain, hwirq);
560  }
561  
562  extern const struct irq_domain_ops irq_domain_simple_ops;
563  
564  /* stock xlate functions */
565  int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
566  			const u32 *intspec, unsigned int intsize,
567  			irq_hw_number_t *out_hwirq, unsigned int *out_type);
568  int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
569  			const u32 *intspec, unsigned int intsize,
570  			irq_hw_number_t *out_hwirq, unsigned int *out_type);
571  int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
572  			const u32 *intspec, unsigned int intsize,
573  			irq_hw_number_t *out_hwirq, unsigned int *out_type);
574  
575  int irq_domain_translate_twocell(struct irq_domain *d,
576  				 struct irq_fwspec *fwspec,
577  				 unsigned long *out_hwirq,
578  				 unsigned int *out_type);
579  
580  int irq_domain_translate_onecell(struct irq_domain *d,
581  				 struct irq_fwspec *fwspec,
582  				 unsigned long *out_hwirq,
583  				 unsigned int *out_type);
584  
585  /* IPI functions */
586  int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
587  int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
588  
589  /* V2 interfaces to support hierarchy IRQ domains. */
590  extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
591  						unsigned int virq);
592  extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
593  				irq_hw_number_t hwirq,
594  				const struct irq_chip *chip,
595  				void *chip_data, irq_flow_handler_t handler,
596  				void *handler_data, const char *handler_name);
597  extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
598  #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
599  extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
600  			unsigned int flags, unsigned int size,
601  			struct fwnode_handle *fwnode,
602  			const struct irq_domain_ops *ops, void *host_data);
603  
irq_domain_add_hierarchy(struct irq_domain * parent,unsigned int flags,unsigned int size,struct device_node * node,const struct irq_domain_ops * ops,void * host_data)604  static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
605  					    unsigned int flags,
606  					    unsigned int size,
607  					    struct device_node *node,
608  					    const struct irq_domain_ops *ops,
609  					    void *host_data)
610  {
611  	return irq_domain_create_hierarchy(parent, flags, size,
612  					   of_node_to_fwnode(node),
613  					   ops, host_data);
614  }
615  
616  extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
617  				   unsigned int nr_irqs, int node, void *arg,
618  				   bool realloc,
619  				   const struct irq_affinity_desc *affinity);
620  extern void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
621  extern int irq_domain_activate_irq(struct irq_data *irq_data, bool early);
622  extern void irq_domain_deactivate_irq(struct irq_data *irq_data);
623  
irq_domain_alloc_irqs(struct irq_domain * domain,unsigned int nr_irqs,int node,void * arg)624  static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
625  			unsigned int nr_irqs, int node, void *arg)
626  {
627  	return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false,
628  				       NULL);
629  }
630  
631  extern int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
632  					   unsigned int irq_base,
633  					   unsigned int nr_irqs, void *arg);
634  extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
635  					 unsigned int virq,
636  					 irq_hw_number_t hwirq,
637  					 const struct irq_chip *chip,
638  					 void *chip_data);
639  extern void irq_domain_free_irqs_common(struct irq_domain *domain,
640  					unsigned int virq,
641  					unsigned int nr_irqs);
642  extern void irq_domain_free_irqs_top(struct irq_domain *domain,
643  				     unsigned int virq, unsigned int nr_irqs);
644  
645  extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
646  extern int irq_domain_pop_irq(struct irq_domain *domain, int virq);
647  
648  extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
649  					unsigned int irq_base,
650  					unsigned int nr_irqs, void *arg);
651  
652  extern void irq_domain_free_irqs_parent(struct irq_domain *domain,
653  					unsigned int irq_base,
654  					unsigned int nr_irqs);
655  
656  extern int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
657  					   unsigned int virq);
658  
irq_domain_is_hierarchy(struct irq_domain * domain)659  static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
660  {
661  	return domain->flags & IRQ_DOMAIN_FLAG_HIERARCHY;
662  }
663  
irq_domain_is_ipi(struct irq_domain * domain)664  static inline bool irq_domain_is_ipi(struct irq_domain *domain)
665  {
666  	return domain->flags &
667  		(IRQ_DOMAIN_FLAG_IPI_PER_CPU | IRQ_DOMAIN_FLAG_IPI_SINGLE);
668  }
669  
irq_domain_is_ipi_per_cpu(struct irq_domain * domain)670  static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
671  {
672  	return domain->flags & IRQ_DOMAIN_FLAG_IPI_PER_CPU;
673  }
674  
irq_domain_is_ipi_single(struct irq_domain * domain)675  static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
676  {
677  	return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
678  }
679  
irq_domain_is_msi(struct irq_domain * domain)680  static inline bool irq_domain_is_msi(struct irq_domain *domain)
681  {
682  	return domain->flags & IRQ_DOMAIN_FLAG_MSI;
683  }
684  
irq_domain_is_msi_parent(struct irq_domain * domain)685  static inline bool irq_domain_is_msi_parent(struct irq_domain *domain)
686  {
687  	return domain->flags & IRQ_DOMAIN_FLAG_MSI_PARENT;
688  }
689  
irq_domain_is_msi_device(struct irq_domain * domain)690  static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
691  {
692  	return domain->flags & IRQ_DOMAIN_FLAG_MSI_DEVICE;
693  }
694  
695  #else	/* CONFIG_IRQ_DOMAIN_HIERARCHY */
irq_domain_alloc_irqs(struct irq_domain * domain,unsigned int nr_irqs,int node,void * arg)696  static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
697  			unsigned int nr_irqs, int node, void *arg)
698  {
699  	return -1;
700  }
701  
irq_domain_free_irqs(unsigned int virq,unsigned int nr_irqs)702  static inline void irq_domain_free_irqs(unsigned int virq,
703  					unsigned int nr_irqs) { }
704  
irq_domain_is_hierarchy(struct irq_domain * domain)705  static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
706  {
707  	return false;
708  }
709  
irq_domain_is_ipi(struct irq_domain * domain)710  static inline bool irq_domain_is_ipi(struct irq_domain *domain)
711  {
712  	return false;
713  }
714  
irq_domain_is_ipi_per_cpu(struct irq_domain * domain)715  static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
716  {
717  	return false;
718  }
719  
irq_domain_is_ipi_single(struct irq_domain * domain)720  static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
721  {
722  	return false;
723  }
724  
irq_domain_is_msi(struct irq_domain * domain)725  static inline bool irq_domain_is_msi(struct irq_domain *domain)
726  {
727  	return false;
728  }
729  
irq_domain_is_msi_parent(struct irq_domain * domain)730  static inline bool irq_domain_is_msi_parent(struct irq_domain *domain)
731  {
732  	return false;
733  }
734  
irq_domain_is_msi_device(struct irq_domain * domain)735  static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
736  {
737  	return false;
738  }
739  
740  #endif	/* CONFIG_IRQ_DOMAIN_HIERARCHY */
741  
742  #ifdef CONFIG_GENERIC_MSI_IRQ
743  int msi_device_domain_alloc_wired(struct irq_domain *domain, unsigned int hwirq,
744  				  unsigned int type);
745  void msi_device_domain_free_wired(struct irq_domain *domain, unsigned int virq);
746  #else
msi_device_domain_alloc_wired(struct irq_domain * domain,unsigned int hwirq,unsigned int type)747  static inline int msi_device_domain_alloc_wired(struct irq_domain *domain, unsigned int hwirq,
748  						unsigned int type)
749  {
750  	WARN_ON_ONCE(1);
751  	return -EINVAL;
752  }
msi_device_domain_free_wired(struct irq_domain * domain,unsigned int virq)753  static inline void msi_device_domain_free_wired(struct irq_domain *domain, unsigned int virq)
754  {
755  	WARN_ON_ONCE(1);
756  }
757  #endif
758  
759  #else /* CONFIG_IRQ_DOMAIN */
irq_dispose_mapping(unsigned int virq)760  static inline void irq_dispose_mapping(unsigned int virq) { }
irq_find_matching_fwnode(struct fwnode_handle * fwnode,enum irq_domain_bus_token bus_token)761  static inline struct irq_domain *irq_find_matching_fwnode(
762  	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
763  {
764  	return NULL;
765  }
766  #endif /* !CONFIG_IRQ_DOMAIN */
767  
768  #endif /* _LINUX_IRQDOMAIN_H */
769