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