Lines Matching +full:intc +full:- +full:nr +full:- +full:irqs
1 // SPDX-License-Identifier: GPL-2.0+
6 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8 * Copyright (C) 1996-2001 Cort Dougan
32 * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
55 * of_irq_find_parent - Given a device node, find its interrupt parent node
70 if (of_property_read_u32(child, "interrupt-parent", &parent)) {
80 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
87 * These interrupt controllers abuse interrupt-map for unspeakable
90 * non-sensical interrupt-map that is better left ignored.
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",
119 len--;
123 pr_debug(" -> imap parent not found !\n");
127 /* Get #interrupt-cells and #address-cells of new parent */
128 if (of_property_read_u32(np, "#interrupt-cells",
130 pr_debug(" -> parent lacks #interrupt-cells!\n");
134 if (of_property_read_u32(np, "#address-cells",
138 pr_debug(" -> intsize=%d, addrsize=%d\n",
148 pr_debug(" -> imaplen=%d\n", len);
152 out_irq->np = np;
154 out_irq->args[i] = be32_to_cpup(imap - intsize + i);
155 out_irq->args_count = intsize;
161 * of_irq_parse_raw - Low level interrupt tree parsing
165 * This function is a low-level interrupt tree walking function. It
169 * input, walks the tree looking for any interrupt-map properties, translates
174 * Note: refcount of node @out_irq->np is increased by 1 on success.
181 const __be32 *tmp, dummy_imask[] = { [0 ... (MAX_PHANDLE_ARGS - 1)] = cpu_to_be32(~0) };
183 int i, rc = -EINVAL;
189 ipar = of_node_get(out_irq->np);
191 /* First get the #interrupt-cells property of the current cursor
192 * that tells us how to interpret the passed-in intspec. If there
196 if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize))
203 pr_debug(" -> no parent found !\n");
209 if (out_irq->args_count != intsize)
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
217 tmp = of_get_property(old, "#address-cells", NULL);
226 pr_debug(" -> addrsize=%d\n", addrsize);
230 rc = -EFAULT;
234 /* Precalculate the match array - this simplifies match loop */
238 initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
246 * Now check if cursor is an interrupt-controller and
248 * interrupt-map which takes precedence except on one
250 * interrupt-map themselves for $reason.
252 bool intc = of_property_read_bool(ipar, "interrupt-controller");
254 imap = of_get_property(ipar, "interrupt-map", &imaplen);
255 if (intc &&
257 pr_debug(" -> got it !\n");
262 * interrupt-map parsing does not work without a reg
263 * property when #address-cells != 0
266 pr_debug(" -> no reg passed in when needed !\n");
272 pr_debug(" -> no map, getting parent\n");
279 imask = of_get_property(ipar, "interrupt-map-mask", NULL);
283 /* Parse interrupt-map */
288 for (i = 0; i < (addrsize + intsize); i++, imaplen--)
291 pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
298 match &= of_device_is_available(out_irq->np);
302 of_node_put(out_irq->np);
303 imaplen -= imap - oldimap;
304 pr_debug(" -> imaplen=%d\n", imaplen);
310 * Successfully parsed an interrupt-map translation; copy new
315 newpar = out_irq->np;
316 intsize = out_irq->args_count;
317 addrsize = (imap - match_array) - intsize;
326 pr_debug("%pOF interrupt-map entry to self\n", ipar);
332 pr_debug(" -> new parent: %pOF\n", newpar);
337 rc = -ENOENT; /* No interrupt-map found */
347 * of_irq_parse_one - Resolve an interrupt for a device
356 * Note: refcount of node @out_irq->np is increased by 1 on success.
376 /* Prevent out-of-bounds read in case of longer interrupt parent address size */
382 /* Try the new-style interrupts-extended first */
383 res = of_parse_phandle_with_args(device, "interrupts-extended",
384 "#interrupt-cells", index, out_irq);
386 p = out_irq->np;
391 if (!p || of_property_read_u32(p, "#interrupt-cells", &intsize))
392 return -EINVAL;
397 out_irq->np = p;
398 out_irq->args_count = intsize;
402 out_irq->args + i);
407 pr_debug(" intspec=%d\n", *out_irq->args);
410 /* Check if there are any interrupt-map translations to process */
416 * of_irq_to_resource - Decode a node's IRQ and return it as a resource
418 * @index: zero-based index of the irq
435 * Get optional "interrupt-names" property to add a name
438 of_property_read_string_index(dev, "interrupt-names", index,
442 r->flags |= irq_get_trigger_type(irq);
450 * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
452 * @index: zero-based index of the IRQ
455 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
470 rc = -EPROBE_DEFER;
483 * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
488 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
496 return -EINVAL;
498 index = of_property_match_string(dev, "interrupt-names", name);
507 * of_irq_count - Count the number of IRQs a node uses
513 int nr = 0;
515 while (of_irq_parse_one(dev, nr, &irq) == 0) {
517 nr++;
520 return nr;
524 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
527 * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
552 * of_irq_init - Scan and init matching interrupt controllers in DT
569 if (!of_property_read_bool(np, "interrupt-controller") ||
573 if (WARN(!match->data, "of_irq_init: no init function for %s\n",
574 match->compatible))
579 * pointer, interrupt-parent device_node etc.
587 desc->irq_init_cb = match->data;
588 desc->dev = of_node_get(np);
590 * interrupts-extended can reference multiple parent domains.
594 desc->interrupt_parent = of_parse_phandle(np, "interrupts-extended", 0);
595 if (!desc->interrupt_parent)
596 desc->interrupt_parent = of_irq_find_parent(np);
597 if (desc->interrupt_parent == np) {
598 of_node_put(desc->interrupt_parent);
599 desc->interrupt_parent = NULL;
601 list_add_tail(&desc->list, &intc_desc_list);
605 * The root irq controller is the one without an interrupt-parent.
618 if (desc->interrupt_parent != parent)
621 list_del(&desc->list);
623 of_node_set_flag(desc->dev, OF_POPULATED);
626 desc->dev,
627 desc->dev, desc->interrupt_parent);
628 ret = desc->irq_init_cb(desc->dev,
629 desc->interrupt_parent);
632 __func__, desc->dev, desc->dev,
633 desc->interrupt_parent);
634 of_node_clear_flag(desc->dev, OF_POPULATED);
635 of_node_put(desc->interrupt_parent);
636 of_node_put(desc->dev);
645 list_add_tail(&desc->list, &intc_parent_list);
655 list_del(&desc->list);
656 parent = desc->dev;
661 list_del(&desc->list);
666 list_del(&desc->list);
667 of_node_put(desc->interrupt_parent);
668 of_node_put(desc->dev);
681 * "msi-map" property.
683 for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
684 if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
685 "msi-map-mask", np, &id_out))
691 * of_msi_map_id - Map a MSI ID for a device.
696 * Walk up the device hierarchy looking for devices with a "msi-map"
707 * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
712 * Walk up the device hierarchy looking for devices with a "msi-map"
727 * of_msi_get_domain - Use msi-parent to find the relevant MSI domain
732 * Parse the msi-parent property and returns the corresponding MSI domain.
744 of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) {
755 * of_msi_configure - Set the msi_domain field of a device