File Index
Files and directories
Sign in
FILE

irq.c

File preview with syntax highlighting.

linux-6.19.14/drivers/of/irq.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 *  Derived from arch/i386/kernel/irq.c
  4 *    Copyright (C) 1992 Linus Torvalds
  5 *  Adapted from arch/i386 by Gary Thomas
  6 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  7 *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
  8 *    Copyright (C) 1996-2001 Cort Dougan
  9 *  Adapted for Power Macintosh by Paul Mackerras
 10 *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
 11 *
 12 * This file contains the code used to make IRQ descriptions in the
 13 * device tree to actual irq numbers on an interrupt controller
 14 * driver.
 15 */
 16
 17#define pr_fmt(fmt)	"OF: " fmt
 18
 19#include <linux/cleanup.h>
 20#include <linux/device.h>
 21#include <linux/errno.h>
 22#include <linux/list.h>
 23#include <linux/module.h>
 24#include <linux/of.h>
 25#include <linux/of_irq.h>
 26#include <linux/string.h>
 27#include <linux/slab.h>
 28
 29#include "of_private.h"
 30
 31/**
 32 * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
 33 * @dev: Device node of the device whose interrupt is to be mapped
 34 * @index: Index of the interrupt to map
 35 *
 36 * This function is a wrapper that chains of_irq_parse_one() and
 37 * irq_create_of_mapping() to make things easier to callers
 38 */
 39unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
 40{
 41	struct of_phandle_args oirq;
 42	unsigned int ret;
 43
 44	if (of_irq_parse_one(dev, index, &oirq))
 45		return 0;
 46
 47	ret = irq_create_of_mapping(&oirq);
 48	of_node_put(oirq.np);
 49
 50	return ret;
 51}
 52EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
 53
 54/**
 55 * of_irq_find_parent - Given a device node, find its interrupt parent node
 56 * @child: pointer to device node
 57 *
 58 * Return: A pointer to the interrupt parent node with refcount increased
 59 * or NULL if the interrupt parent could not be determined.
 60 */
 61struct device_node *of_irq_find_parent(struct device_node *child)
 62{
 63	struct device_node *p;
 64	phandle parent;
 65
 66	if (!of_node_get(child))
 67		return NULL;
 68
 69	do {
 70		if (of_property_read_u32(child, "interrupt-parent", &parent)) {
 71			p = of_get_parent(child);
 72		} else	{
 73			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
 74				p = of_node_get(of_irq_dflt_pic);
 75			else
 76				p = of_find_node_by_phandle(parent);
 77		}
 78		of_node_put(child);
 79		child = p;
 80	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
 81
 82	return p;
 83}
 84EXPORT_SYMBOL_GPL(of_irq_find_parent);
 85
 86/*
 87 * These interrupt controllers abuse interrupt-map for unspeakable
 88 * reasons and rely on the core code to *ignore* it (the drivers do
 89 * their own parsing of the property). The PAsemi entry covers a
 90 * non-sensical interrupt-map that is better left ignored.
 91 *
 92 * If you think of adding to the list for something *new*, think
 93 * again. There is a high chance that you will be sent back to the
 94 * drawing board.
 95 */
 96static const char * const of_irq_imap_abusers[] = {
 97	"CBEA,platform-spider-pic",
 98	"sti,platform-spider-pic",
 99	"realtek,rtl-intc",
100	"fsl,ls1021a-extirq",
101	"fsl,ls1043a-extirq",
102	"fsl,ls1088a-extirq",
103	"renesas,rza1-irqc",
104	"pasemi,rootbus",
105	NULL,
106};
107
108const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_phandle_args *out_irq)
109{
110	u32 intsize, addrsize;
111	struct device_node *np;
112
113	/* Get the interrupt parent */
114	if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
115		np = of_node_get(of_irq_dflt_pic);
116	else
117		np = of_find_node_by_phandle(be32_to_cpup(imap));
118	imap++;
119	len--;
120
121	/* Check if not found */
122	if (!np) {
123		pr_debug(" -> imap parent not found !\n");
124		return NULL;
125	}
126
127	/* Get #interrupt-cells and #address-cells of new parent */
128	if (of_property_read_u32(np, "#interrupt-cells",
129					&intsize)) {
130		pr_debug(" -> parent lacks #interrupt-cells!\n");
131		of_node_put(np);
132		return NULL;
133	}
134	if (of_property_read_u32(np, "#address-cells",
135					&addrsize))
136		addrsize = 0;
137
138	pr_debug(" -> intsize=%d, addrsize=%d\n",
139		intsize, addrsize);
140
141	/* Check for malformed properties */
142	if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)
143		|| (len < (addrsize + intsize))) {
144		of_node_put(np);
145		return NULL;
146	}
147
148	pr_debug(" -> imaplen=%d\n", len);
149
150	imap += addrsize + intsize;
151
152	out_irq->np = np;
153	for (int i = 0; i < intsize; i++)
154		out_irq->args[i] = be32_to_cpup(imap - intsize + i);
155	out_irq->args_count = intsize;
156
157	return imap;
158}
159
160/**
161 * of_irq_parse_raw - Low level interrupt tree parsing
162 * @addr:	address specifier (start of "reg" property of the device) in be32 format
163 * @out_irq:	structure of_phandle_args updated by this function
164 *
165 * This function is a low-level interrupt tree walking function. It
166 * can be used to do a partial walk with synthesized reg and interrupts
167 * properties, for example when resolving PCI interrupts when no device
168 * node exist for the parent. It takes an interrupt specifier structure as
169 * input, walks the tree looking for any interrupt-map properties, translates
170 * the specifier for each map, and then returns the translated map.
171 *
172 * Return: 0 on success and a negative number on error
173 *
174 * Note: refcount of node @out_irq->np is increased by 1 on success.
175 */
176int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
177{
178	struct device_node *ipar, *tnode, *old = NULL;
179	__be32 initial_match_array[MAX_PHANDLE_ARGS];
180	const __be32 *match_array = initial_match_array;
181	const __be32 *tmp, dummy_imask[] = { [0 ... (MAX_PHANDLE_ARGS - 1)] = cpu_to_be32(~0) };
182	u32 intsize = 1, addrsize;
183	int i, rc = -EINVAL;
184
185#ifdef DEBUG
186	of_print_phandle_args("of_irq_parse_raw: ", out_irq);
187#endif
188
189	ipar = of_node_get(out_irq->np);
190
191	/* First get the #interrupt-cells property of the current cursor
192	 * that tells us how to interpret the passed-in intspec. If there
193	 * is none, we are nice and just walk up the tree
194	 */
195	do {
196		if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize))
197			break;
198		tnode = ipar;
199		ipar = of_irq_find_parent(ipar);
200		of_node_put(tnode);
201	} while (ipar);
202	if (ipar == NULL) {
203		pr_debug(" -> no parent found !\n");
204		goto fail;
205	}
206
207	pr_debug("of_irq_parse_raw: ipar=%pOF, size=%d\n", ipar, intsize);
208
209	if (out_irq->args_count != intsize)
210		goto fail;
211
212	/* Look for this #address-cells. We have to implement the old linux
213	 * trick of looking for the parent here as some device-trees rely on it
214	 */
215	old = of_node_get(ipar);
216	do {
217		tmp = of_get_property(old, "#address-cells", NULL);
218		tnode = of_get_parent(old);
219		of_node_put(old);
220		old = tnode;
221	} while (old && tmp == NULL);
222	of_node_put(old);
223	old = NULL;
224	addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
225
226	pr_debug(" -> addrsize=%d\n", addrsize);
227
228	/* Range check so that the temporary buffer doesn't overflow */
229	if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) {
230		rc = -EFAULT;
231		goto fail;
232	}
233
234	/* Precalculate the match array - this simplifies match loop */
235	for (i = 0; i < addrsize; i++)
236		initial_match_array[i] = addr ? addr[i] : 0;
237	for (i = 0; i < intsize; i++)
238		initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
239
240	/* Now start the actual "proper" walk of the interrupt tree */
241	while (ipar != NULL) {
242		int imaplen, match;
243		const __be32 *imap, *oldimap, *imask;
244		struct device_node *newpar;
245		/*
246		 * Now check if cursor is an interrupt-controller and
247		 * if it is then we are done, unless there is an
248		 * interrupt-map which takes precedence except on one
249		 * of these broken platforms that want to parse
250		 * interrupt-map themselves for $reason.
251		 */
252		bool intc = of_property_read_bool(ipar, "interrupt-controller");
253
254		imap = of_get_property(ipar, "interrupt-map", &imaplen);
255		if (intc &&
256		    (!imap || of_device_compatible_match(ipar, of_irq_imap_abusers))) {
257			pr_debug(" -> got it !\n");
258			return 0;
259		}
260
261		/*
262		 * interrupt-map parsing does not work without a reg
263		 * property when #address-cells != 0
264		 */
265		if (addrsize && !addr) {
266			pr_debug(" -> no reg passed in when needed !\n");
267			goto fail;
268		}
269
270		/* No interrupt map, check for an interrupt parent */
271		if (imap == NULL) {
272			pr_debug(" -> no map, getting parent\n");
273			newpar = of_irq_find_parent(ipar);
274			goto skiplevel;
275		}
276		imaplen /= sizeof(u32);
277
278		/* Look for a mask */
279		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
280		if (!imask)
281			imask = dummy_imask;
282
283		/* Parse interrupt-map */
284		match = 0;
285		while (imaplen > (addrsize + intsize + 1)) {
286			/* Compare specifiers */
287			match = 1;
288			for (i = 0; i < (addrsize + intsize); i++, imaplen--)
289				match &= !((match_array[i] ^ *imap++) & imask[i]);
290
291			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
292
293			oldimap = imap;
294			imap = of_irq_parse_imap_parent(oldimap, imaplen, out_irq);
295			if (!imap)
296				goto fail;
297
298			match &= of_device_is_available(out_irq->np);
299			if (match)
300				break;
301
302			of_node_put(out_irq->np);
303			imaplen -= imap - oldimap;
304			pr_debug(" -> imaplen=%d\n", imaplen);
305		}
306		if (!match)
307			goto fail;
308
309		/*
310		 * Successfully parsed an interrupt-map translation; copy new
311		 * interrupt specifier into the out_irq structure
312		 */
313		match_array = oldimap + 1;
314
315		newpar = out_irq->np;
316		intsize = out_irq->args_count;
317		addrsize = (imap - match_array) - intsize;
318
319		if (ipar == newpar) {
320			/*
321			 * We got @ipar's refcount, but the refcount was
322			 * gotten again by of_irq_parse_imap_parent() via its
323			 * alias @newpar.
324			 */
325			of_node_put(ipar);
326			pr_debug("%pOF interrupt-map entry to self\n", ipar);
327			return 0;
328		}
329
330	skiplevel:
331		/* Iterate again with new parent */
332		pr_debug(" -> new parent: %pOF\n", newpar);
333		of_node_put(ipar);
334		ipar = newpar;
335		newpar = NULL;
336	}
337	rc = -ENOENT; /* No interrupt-map found */
338
339 fail:
340	of_node_put(ipar);
341
342	return rc;
343}
344EXPORT_SYMBOL_GPL(of_irq_parse_raw);
345
346/**
347 * of_irq_parse_one - Resolve an interrupt for a device
348 * @device: the device whose interrupt is to be resolved
349 * @index: index of the interrupt to resolve
350 * @out_irq: structure of_phandle_args filled by this function
351 *
352 * This function resolves an interrupt for a node by walking the interrupt tree,
353 * finding which interrupt controller node it is attached to, and returning the
354 * interrupt specifier that can be used to retrieve a Linux IRQ number.
355 *
356 * Note: refcount of node @out_irq->np is increased by 1 on success.
357 */
358int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
359{
360	struct device_node __free(device_node) *p = NULL;
361	const __be32 *addr;
362	u32 intsize;
363	int i, res, addr_len;
364	__be32 addr_buf[3] = { 0 };
365
366	pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index);
367
368	/* OldWorld mac stuff is "special", handle out of line */
369	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
370		return of_irq_parse_oldworld(device, index, out_irq);
371
372	/* Get the reg property (if any) */
373	addr_len = 0;
374	addr = of_get_property(device, "reg", &addr_len);
375
376	/* Prevent out-of-bounds read in case of longer interrupt parent address size */
377	if (addr_len > sizeof(addr_buf))
378		addr_len = sizeof(addr_buf);
379	if (addr)
380		memcpy(addr_buf, addr, addr_len);
381
382	/* Try the new-style interrupts-extended first */
383	res = of_parse_phandle_with_args(device, "interrupts-extended",
384					"#interrupt-cells", index, out_irq);
385	if (!res) {
386		p = out_irq->np;
387	} else {
388		/* Look for the interrupt parent. */
389		p = of_irq_find_parent(device);
390		/* Get size of interrupt specifier */
391		if (!p || of_property_read_u32(p, "#interrupt-cells", &intsize))
392			return -EINVAL;
393
394		pr_debug(" parent=%pOF, intsize=%d\n", p, intsize);
395
396		/* Copy intspec into irq structure */
397		out_irq->np = p;
398		out_irq->args_count = intsize;
399		for (i = 0; i < intsize; i++) {
400			res = of_property_read_u32_index(device, "interrupts",
401							(index * intsize) + i,
402							out_irq->args + i);
403			if (res)
404				return res;
405		}
406
407		pr_debug(" intspec=%d\n", *out_irq->args);
408	}
409
410	/* Check if there are any interrupt-map translations to process */
411	return of_irq_parse_raw(addr_buf, out_irq);
412}
413EXPORT_SYMBOL_GPL(of_irq_parse_one);
414
415/**
416 * of_irq_to_resource - Decode a node's IRQ and return it as a resource
417 * @dev: pointer to device tree node
418 * @index: zero-based index of the irq
419 * @r: pointer to resource structure to return result into.
420 */
421int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
422{
423	int irq = of_irq_get(dev, index);
424
425	if (irq < 0)
426		return irq;
427
428	/* Only dereference the resource if both the
429	 * resource and the irq are valid. */
430	if (r && irq) {
431		const char *name = NULL;
432
433		memset(r, 0, sizeof(*r));
434		/*
435		 * Get optional "interrupt-names" property to add a name
436		 * to the resource.
437		 */
438		of_property_read_string_index(dev, "interrupt-names", index,
439					      &name);
440
441		*r = DEFINE_RES_IRQ_NAMED(irq, name ?: of_node_full_name(dev));
442		r->flags |= irq_get_trigger_type(irq);
443	}
444
445	return irq;
446}
447EXPORT_SYMBOL_GPL(of_irq_to_resource);
448
449/**
450 * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
451 * @dev: pointer to device tree node
452 * @index: zero-based index of the IRQ
453 *
454 * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
455 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
456 * of any other failure.
457 */
458int of_irq_get(struct device_node *dev, int index)
459{
460	int rc;
461	struct of_phandle_args oirq;
462	struct irq_domain *domain;
463
464	rc = of_irq_parse_one(dev, index, &oirq);
465	if (rc)
466		return rc;
467
468	domain = irq_find_host(oirq.np);
469	if (!domain) {
470		rc = -EPROBE_DEFER;
471		goto out;
472	}
473
474	rc = irq_create_of_mapping(&oirq);
475out:
476	of_node_put(oirq.np);
477
478	return rc;
479}
480EXPORT_SYMBOL_GPL(of_irq_get);
481
482const struct cpumask *of_irq_get_affinity(struct device_node *dev, int index)
483{
484	struct of_phandle_args oirq;
485	struct irq_fwspec_info info;
486	struct irq_fwspec fwspec;
487	int rc;
488
489	rc = of_irq_parse_one(dev, index, &oirq);
490	if (rc)
491		return NULL;
492
493	of_phandle_args_to_fwspec(oirq.np, oirq.args, oirq.args_count,
494				  &fwspec);
495
496	if (irq_populate_fwspec_info(&fwspec, &info))
497		return NULL;
498
499	return info.affinity;
500}
501
502/**
503 * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
504 * @dev: pointer to device tree node
505 * @name: IRQ name
506 *
507 * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
508 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
509 * of any other failure.
510 */
511int of_irq_get_byname(struct device_node *dev, const char *name)
512{
513	int index;
514
515	if (unlikely(!name))
516		return -EINVAL;
517
518	index = of_property_match_string(dev, "interrupt-names", name);
519	if (index < 0)
520		return index;
521
522	return of_irq_get(dev, index);
523}
524EXPORT_SYMBOL_GPL(of_irq_get_byname);
525
526/**
527 * of_irq_count - Count the number of IRQs a node uses
528 * @dev: pointer to device tree node
529 */
530int of_irq_count(struct device_node *dev)
531{
532	struct of_phandle_args irq;
533	int nr = 0;
534
535	while (of_irq_parse_one(dev, nr, &irq) == 0) {
536		of_node_put(irq.np);
537		nr++;
538	}
539
540	return nr;
541}
542EXPORT_SYMBOL_GPL(of_irq_count);
543
544/**
545 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
546 * @dev: pointer to device tree node
547 * @res: array of resources to fill in
548 * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
549 *
550 * Return: The size of the filled in table (up to @nr_irqs).
551 */
552int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
553		int nr_irqs)
554{
555	int i;
556
557	for (i = 0; i < nr_irqs; i++, res++)
558		if (of_irq_to_resource(dev, i, res) <= 0)
559			break;
560
561	return i;
562}
563EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
564
565struct of_intc_desc {
566	struct list_head	list;
567	of_irq_init_cb_t	irq_init_cb;
568	struct device_node	*dev;
569	struct device_node	*interrupt_parent;
570};
571
572/**
573 * of_irq_init - Scan and init matching interrupt controllers in DT
574 * @matches: 0 terminated array of nodes to match and init function to call
575 *
576 * This function scans the device tree for matching interrupt controller nodes,
577 * and calls their initialization functions in order with parents first.
578 */
579void __init of_irq_init(const struct of_device_id *matches)
580{
581	const struct of_device_id *match;
582	struct device_node *np, *parent = NULL;
583	struct of_intc_desc *desc, *temp_desc;
584	struct list_head intc_desc_list, intc_parent_list;
585
586	INIT_LIST_HEAD(&intc_desc_list);
587	INIT_LIST_HEAD(&intc_parent_list);
588
589	for_each_matching_node_and_match(np, matches, &match) {
590		if (!of_property_read_bool(np, "interrupt-controller") ||
591				!of_device_is_available(np))
592			continue;
593
594		if (WARN(!match->data, "of_irq_init: no init function for %s\n",
595			 match->compatible))
596			continue;
597
598		/*
599		 * Here, we allocate and populate an of_intc_desc with the node
600		 * pointer, interrupt-parent device_node etc.
601		 */
602		desc = kzalloc(sizeof(*desc), GFP_KERNEL);
603		if (!desc) {
604			of_node_put(np);
605			goto err;
606		}
607
608		desc->irq_init_cb = match->data;
609		desc->dev = of_node_get(np);
610		/*
611		 * interrupts-extended can reference multiple parent domains.
612		 * Arbitrarily pick the first one; assume any other parents
613		 * are the same distance away from the root irq controller.
614		 */
615		desc->interrupt_parent = of_parse_phandle(np, "interrupts-extended", 0);
616		if (!desc->interrupt_parent && of_property_present(np, "interrupts"))
617			desc->interrupt_parent = of_irq_find_parent(np);
618		else if (!desc->interrupt_parent)
619			desc->interrupt_parent = of_parse_phandle(np, "interrupt-parent", 0);
620		if (desc->interrupt_parent == np) {
621			of_node_put(desc->interrupt_parent);
622			desc->interrupt_parent = NULL;
623		}
624		list_add_tail(&desc->list, &intc_desc_list);
625	}
626
627	/*
628	 * The root irq controller is the one without an interrupt-parent.
629	 * That one goes first, followed by the controllers that reference it,
630	 * followed by the ones that reference the 2nd level controllers, etc.
631	 */
632	while (!list_empty(&intc_desc_list)) {
633		/*
634		 * Process all controllers with the current 'parent'.
635		 * First pass will be looking for NULL as the parent.
636		 * The assumption is that NULL parent means a root controller.
637		 */
638		list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
639			int ret;
640
641			if (desc->interrupt_parent != parent)
642				continue;
643
644			list_del(&desc->list);
645
646			of_node_set_flag(desc->dev, OF_POPULATED);
647
648			pr_debug("of_irq_init: init %pOF (%p), parent %p\n",
649				 desc->dev,
650				 desc->dev, desc->interrupt_parent);
651			ret = desc->irq_init_cb(desc->dev,
652						desc->interrupt_parent);
653			if (ret) {
654				pr_err("%s: Failed to init %pOF (%p), parent %p\n",
655				       __func__, desc->dev, desc->dev,
656				       desc->interrupt_parent);
657				of_node_clear_flag(desc->dev, OF_POPULATED);
658				of_node_put(desc->interrupt_parent);
659				of_node_put(desc->dev);
660				kfree(desc);
661				continue;
662			}
663
664			/*
665			 * This one is now set up; add it to the parent list so
666			 * its children can get processed in a subsequent pass.
667			 */
668			list_add_tail(&desc->list, &intc_parent_list);
669		}
670
671		/* Get the next pending parent that might have children */
672		desc = list_first_entry_or_null(&intc_parent_list,
673						typeof(*desc), list);
674		if (!desc) {
675			pr_err("of_irq_init: children remain, but no parents\n");
676			break;
677		}
678		list_del(&desc->list);
679		parent = desc->dev;
680		kfree(desc);
681	}
682
683	list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
684		list_del(&desc->list);
685		kfree(desc);
686	}
687err:
688	list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
689		list_del(&desc->list);
690		of_node_put(desc->interrupt_parent);
691		of_node_put(desc->dev);
692		kfree(desc);
693	}
694}
695
696static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node)
697{
698	struct of_phandle_args msi_spec;
699	int ret;
700
701	/*
702	 * An msi-parent phandle with a missing or == 0 #msi-cells
703	 * property identifies a 1:1 ID translation mapping.
704	 *
705	 * Set the msi controller node if the firmware matches this
706	 * condition.
707	 */
708	ret = of_parse_phandle_with_optional_args(dev_node, "msi-parent", "#msi-cells",
709						  0, &msi_spec);
710	if (ret)
711		return ret;
712
713	if ((*msi_node && *msi_node != msi_spec.np) || msi_spec.args_count != 0)
714		ret = -EINVAL;
715
716	if (!ret) {
717		/* Return with a node reference held */
718		*msi_node = msi_spec.np;
719		return 0;
720	}
721	of_node_put(msi_spec.np);
722
723	return ret;
724}
725
726/**
727 * of_msi_xlate - map a MSI ID and find relevant MSI controller node
728 * @dev: device for which the mapping is to be done.
729 * @msi_np: Pointer to target MSI controller node
730 * @id_in: Device ID.
731 *
732 * Walk up the device hierarchy looking for devices with a "msi-map"
733 * or "msi-parent" property. If found, apply the mapping to @id_in.
734 * If @msi_np points to a non-NULL device node pointer, only entries targeting
735 * that node will be matched; if it points to a NULL value, it will receive the
736 * device node of the first matching target phandle, with a reference held.
737 *
738 * Returns: The mapped MSI id.
739 */
740u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
741{
742	struct device *parent_dev;
743	u32 id_out = id_in;
744
745	/*
746	 * Walk up the device parent links looking for one with a
747	 * "msi-map" or an "msi-parent" property.
748	 */
749	for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
750		if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
751				"msi-map-mask", msi_np, &id_out))
752			break;
753		if (!of_check_msi_parent(parent_dev->of_node, msi_np))
754			break;
755	}
756	return id_out;
757}
758EXPORT_SYMBOL_GPL(of_msi_xlate);
759
760/**
761 * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
762 * @dev: device for which the mapping is to be done.
763 * @id: Device ID.
764 * @bus_token: Bus token
765 *
766 * Walk up the device hierarchy looking for devices with a "msi-map"
767 * property.
768 *
769 * Returns: the MSI domain for this device (or NULL on failure)
770 */
771struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
772						u32 bus_token)
773{
774	struct device_node *np = NULL;
775
776	of_msi_xlate(dev, &np, id);
777	return irq_find_matching_host(np, bus_token);
778}
779
780/**
781 * of_msi_get_domain - Use msi-parent to find the relevant MSI domain
782 * @dev: device for which the domain is requested
783 * @np: device node for @dev
784 * @token: bus type for this domain
785 *
786 * Parse the msi-parent property and returns the corresponding MSI domain.
787 *
788 * Returns: the MSI domain for this device (or NULL on failure).
789 */
790struct irq_domain *of_msi_get_domain(struct device *dev,
791				     const struct device_node *np,
792				     enum irq_domain_bus_token token)
793{
794	struct of_phandle_iterator it;
795	struct irq_domain *d;
796	int err;
797
798	of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) {
799		d = irq_find_matching_host(it.node, token);
800		if (d) {
801			of_node_put(it.node);
802			return d;
803		}
804	}
805
806	return NULL;
807}
808EXPORT_SYMBOL_GPL(of_msi_get_domain);
809
810/**
811 * of_msi_configure - Set the msi_domain field of a device
812 * @dev: device structure to associate with an MSI irq domain
813 * @np: device node for that device
814 */
815void of_msi_configure(struct device *dev, const struct device_node *np)
816{
817	dev_set_msi_domain(dev,
818			   of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
819}
820EXPORT_SYMBOL_GPL(of_msi_configure);
~/ Read-only file preview.