Lines Matching +full:interrupt +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0+
6 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8 * Copyright (C) 1996-2001 Cort Dougan
13 * device tree to actual irq numbers on an interrupt controller
30 * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
31 * @dev: Device node of the device whose interrupt is to be mapped
32 * @index: Index of the interrupt to map
49 * of_irq_find_parent - Given a device node, find its interrupt parent node
52 * Returns a pointer to the interrupt parent node, or NULL if the interrupt
64 if (of_property_read_u32(child, "interrupt-parent", &parent)) { in of_irq_find_parent()
74 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); in of_irq_find_parent()
81 * of_irq_parse_raw - Low level interrupt tree parsing
87 * This function is a low-level interrupt tree walking function. It
90 * node exist for the parent. It takes an interrupt specifier structure as
91 * input, walks the tree looking for any interrupt-map properties, translates
92 * the specifier for each map, and then returns the translated map.
101 int imaplen, match, i, rc = -EINVAL; in of_irq_parse_raw()
107 ipar = of_node_get(out_irq->np); in of_irq_parse_raw()
109 /* First get the #interrupt-cells property of the current cursor in of_irq_parse_raw()
110 * that tells us how to interpret the passed-in intspec. If there in of_irq_parse_raw()
114 if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize)) in of_irq_parse_raw()
121 pr_debug(" -> no parent found !\n"); in of_irq_parse_raw()
127 if (out_irq->args_count != intsize) in of_irq_parse_raw()
130 /* Look for this #address-cells. We have to implement the old linux in of_irq_parse_raw()
131 * trick of looking for the parent here as some device-trees rely on it in of_irq_parse_raw()
135 tmp = of_get_property(old, "#address-cells", NULL); in of_irq_parse_raw()
144 pr_debug(" -> addrsize=%d\n", addrsize); in of_irq_parse_raw()
148 rc = -EFAULT; in of_irq_parse_raw()
152 /* Precalculate the match array - this simplifies match loop */ in of_irq_parse_raw()
156 initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]); in of_irq_parse_raw()
158 /* Now start the actual "proper" walk of the interrupt tree */ in of_irq_parse_raw()
160 /* Now check if cursor is an interrupt-controller and if it is in of_irq_parse_raw()
163 if (of_property_read_bool(ipar, "interrupt-controller")) { in of_irq_parse_raw()
164 pr_debug(" -> got it !\n"); in of_irq_parse_raw()
169 * interrupt-map parsing does not work without a reg in of_irq_parse_raw()
170 * property when #address-cells != 0 in of_irq_parse_raw()
173 pr_debug(" -> no reg passed in when needed !\n"); in of_irq_parse_raw()
177 /* Now look for an interrupt-map */ in of_irq_parse_raw()
178 imap = of_get_property(ipar, "interrupt-map", &imaplen); in of_irq_parse_raw()
179 /* No interrupt map, check for an interrupt parent */ in of_irq_parse_raw()
181 pr_debug(" -> no map, getting parent\n"); in of_irq_parse_raw()
188 imask = of_get_property(ipar, "interrupt-map-mask", NULL); in of_irq_parse_raw()
192 /* Parse interrupt-map */ in of_irq_parse_raw()
197 for (i = 0; i < (addrsize + intsize); i++, imaplen--) in of_irq_parse_raw()
200 pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); in of_irq_parse_raw()
202 /* Get the interrupt parent */ in of_irq_parse_raw()
208 --imaplen; in of_irq_parse_raw()
212 pr_debug(" -> imap parent not found !\n"); in of_irq_parse_raw()
219 /* Get #interrupt-cells and #address-cells of new in of_irq_parse_raw()
222 if (of_property_read_u32(newpar, "#interrupt-cells", in of_irq_parse_raw()
224 pr_debug(" -> parent lacks #interrupt-cells!\n"); in of_irq_parse_raw()
227 if (of_property_read_u32(newpar, "#address-cells", in of_irq_parse_raw()
231 pr_debug(" -> newintsize=%d, newaddrsize=%d\n", in of_irq_parse_raw()
237 rc = -EFAULT; in of_irq_parse_raw()
242 imaplen -= newaddrsize + newintsize; in of_irq_parse_raw()
244 pr_debug(" -> imaplen=%d\n", imaplen); in of_irq_parse_raw()
250 * Successfully parsed an interrrupt-map translation; copy new in of_irq_parse_raw()
251 * interrupt specifier into the out_irq structure in of_irq_parse_raw()
253 match_array = imap - newaddrsize - newintsize; in of_irq_parse_raw()
255 out_irq->args[i] = be32_to_cpup(imap - newintsize + i); in of_irq_parse_raw()
256 out_irq->args_count = intsize = newintsize; in of_irq_parse_raw()
261 out_irq->np = newpar; in of_irq_parse_raw()
262 pr_debug(" -> new parent: %pOF\n", newpar); in of_irq_parse_raw()
267 rc = -ENOENT; /* No interrupt-map found */ in of_irq_parse_raw()
278 * of_irq_parse_one - Resolve an interrupt for a device
279 * @device: the device whose interrupt is to be resolved
280 * @index: index of the interrupt to resolve
283 * This function resolves an interrupt for a node by walking the interrupt tree,
284 * finding which interrupt controller node it is attached to, and returning the
285 * interrupt specifier that can be used to retrieve a Linux IRQ number.
303 /* Try the new-style interrupts-extended first */ in of_irq_parse_one()
304 res = of_parse_phandle_with_args(device, "interrupts-extended", in of_irq_parse_one()
305 "#interrupt-cells", index, out_irq); in of_irq_parse_one()
309 /* Look for the interrupt parent. */ in of_irq_parse_one()
312 return -EINVAL; in of_irq_parse_one()
314 /* Get size of interrupt specifier */ in of_irq_parse_one()
315 if (of_property_read_u32(p, "#interrupt-cells", &intsize)) { in of_irq_parse_one()
316 res = -EINVAL; in of_irq_parse_one()
323 out_irq->np = p; in of_irq_parse_one()
324 out_irq->args_count = intsize; in of_irq_parse_one()
328 out_irq->args + i); in of_irq_parse_one()
333 pr_debug(" intspec=%d\n", *out_irq->args); in of_irq_parse_one()
336 /* Check if there are any interrupt-map translations to process */ in of_irq_parse_one()
345 * of_irq_to_resource - Decode a node's IRQ and return it as a resource
347 * @index: zero-based index of the irq
364 * Get optional "interrupt-names" property to add a name in of_irq_to_resource()
367 of_property_read_string_index(dev, "interrupt-names", index, in of_irq_to_resource()
370 r->start = r->end = irq; in of_irq_to_resource()
371 r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); in of_irq_to_resource()
372 r->name = name ? name : of_node_full_name(dev); in of_irq_to_resource()
380 * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
382 * @index: zero-based index of the IRQ
385 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
400 return -EPROBE_DEFER; in of_irq_get()
407 * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
412 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
420 return -EINVAL; in of_irq_get_byname()
422 index = of_property_match_string(dev, "interrupt-names", name); in of_irq_get_byname()
431 * of_irq_count - Count the number of IRQs a node uses
446 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
474 * of_irq_init - Scan and init matching interrupt controllers in DT
477 * This function scans the device tree for matching interrupt controller nodes,
491 if (!of_property_read_bool(np, "interrupt-controller") || in of_irq_init()
495 if (WARN(!match->data, "of_irq_init: no init function for %s\n", in of_irq_init()
496 match->compatible)) in of_irq_init()
501 * pointer, interrupt-parent device_node etc. in of_irq_init()
509 desc->irq_init_cb = match->data; in of_irq_init()
510 desc->dev = of_node_get(np); in of_irq_init()
511 desc->interrupt_parent = of_irq_find_parent(np); in of_irq_init()
512 if (desc->interrupt_parent == np) in of_irq_init()
513 desc->interrupt_parent = NULL; in of_irq_init()
514 list_add_tail(&desc->list, &intc_desc_list); in of_irq_init()
518 * The root irq controller is the one without an interrupt-parent. in of_irq_init()
531 if (desc->interrupt_parent != parent) in of_irq_init()
534 list_del(&desc->list); in of_irq_init()
536 of_node_set_flag(desc->dev, OF_POPULATED); in of_irq_init()
539 desc->dev, in of_irq_init()
540 desc->dev, desc->interrupt_parent); in of_irq_init()
541 ret = desc->irq_init_cb(desc->dev, in of_irq_init()
542 desc->interrupt_parent); in of_irq_init()
544 of_node_clear_flag(desc->dev, OF_POPULATED); in of_irq_init()
553 list_add_tail(&desc->list, &intc_parent_list); in of_irq_init()
563 list_del(&desc->list); in of_irq_init()
564 parent = desc->dev; in of_irq_init()
569 list_del(&desc->list); in of_irq_init()
574 list_del(&desc->list); in of_irq_init()
575 of_node_put(desc->dev); in of_irq_init()
588 * "msi-map" property. in __of_msi_map_rid()
590 for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) in __of_msi_map_rid()
591 if (!of_pci_map_rid(parent_dev->of_node, rid_in, "msi-map", in __of_msi_map_rid()
592 "msi-map-mask", np, &rid_out)) in __of_msi_map_rid()
598 * of_msi_map_rid - Map a MSI requester ID for a device.
603 * Walk up the device hierarchy looking for devices with a "msi-map"
614 * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
618 * Walk up the device hierarchy looking for devices with a "msi-map"
632 * of_msi_get_domain - Use msi-parent to find the relevant MSI domain
637 * Parse the msi-parent property (both the simple and the complex
649 /* Check for a single msi-parent property */ in of_msi_get_domain()
650 msi_np = of_parse_phandle(np, "msi-parent", 0); in of_msi_get_domain()
651 if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) { in of_msi_get_domain()
659 /* Check for the complex msi-parent version */ in of_msi_get_domain()
663 while (!of_parse_phandle_with_args(np, "msi-parent", in of_msi_get_domain()
664 "#msi-cells", in of_msi_get_domain()
679 * of_msi_configure - Set the msi_domain field of a device