Lines Matching +full:interrupt +full:- +full:parent
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
7 * Copyright (C) 1996-2001 Cort Dougan
17 * 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 * @device: Device node of the device whose interrupt is to be mapped
32 * @index: Index of the interrupt to map
50 * of_irq_find_parent - Given a device node, find its interrupt parent node
53 * Returns a pointer to the interrupt parent node, or NULL if the interrupt
54 * parent could not be determined.
65 parp = of_get_property(child, "interrupt-parent", NULL); in of_irq_find_parent()
76 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); in of_irq_find_parent()
82 * of_irq_map_raw - Low level interrupt tree parsing
83 * @parent: the device interrupt parent
84 * @intspec: interrupt specifier ("interrupts" property of the device)
85 * @ointsize: size of the passed in interrupt specifier
91 * This function is a low-level interrupt tree walking function. It
94 * node exist for the parent.
96 int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, in of_irq_map_raw() argument
105 parent->full_name, be32_to_cpup(intspec), in of_irq_map_raw()
108 ipar = of_node_get(parent); in of_irq_map_raw()
110 /* First get the #interrupt-cells property of the current cursor in of_irq_map_raw()
111 * that tells us how to interpret the passed-in intspec. If there in of_irq_map_raw()
115 tmp = of_get_property(ipar, "#interrupt-cells", NULL); in of_irq_map_raw()
125 pr_debug(" -> no parent found !\n"); in of_irq_map_raw()
129 pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); in of_irq_map_raw()
132 return -EINVAL; in of_irq_map_raw()
134 /* Look for this #address-cells. We have to implement the old linux in of_irq_map_raw()
135 * trick of looking for the parent here as some device-trees rely on it in of_irq_map_raw()
139 tmp = of_get_property(old, "#address-cells", NULL); in of_irq_map_raw()
148 pr_debug(" -> addrsize=%d\n", addrsize); in of_irq_map_raw()
150 /* Now start the actual "proper" walk of the interrupt tree */ in of_irq_map_raw()
152 /* Now check if cursor is an interrupt-controller and if it is in of_irq_map_raw()
155 if (of_get_property(ipar, "interrupt-controller", NULL) != in of_irq_map_raw()
157 pr_debug(" -> got it !\n"); in of_irq_map_raw()
159 out_irq->specifier[i] = in of_irq_map_raw()
161 out_irq->size = intsize; in of_irq_map_raw()
162 out_irq->controller = ipar; in of_irq_map_raw()
167 /* Now look for an interrupt-map */ in of_irq_map_raw()
168 imap = of_get_property(ipar, "interrupt-map", &imaplen); in of_irq_map_raw()
169 /* No interrupt map, check for an interrupt parent */ in of_irq_map_raw()
171 pr_debug(" -> no map, getting parent\n"); in of_irq_map_raw()
178 imask = of_get_property(ipar, "interrupt-map-mask", NULL); in of_irq_map_raw()
181 * an interrupt-map, then #address-cells must be 0. in of_irq_map_raw()
185 pr_debug(" -> no reg passed in when needed !\n"); in of_irq_map_raw()
189 /* Parse interrupt-map */ in of_irq_map_raw()
201 ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; in of_irq_map_raw()
204 imaplen -= addrsize + intsize; in of_irq_map_raw()
206 pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); in of_irq_map_raw()
208 /* Get the interrupt parent */ in of_irq_map_raw()
214 --imaplen; in of_irq_map_raw()
218 pr_debug(" -> imap parent not found !\n"); in of_irq_map_raw()
222 /* Get #interrupt-cells and #address-cells of new in of_irq_map_raw()
223 * parent in of_irq_map_raw()
225 tmp = of_get_property(newpar, "#interrupt-cells", NULL); in of_irq_map_raw()
227 pr_debug(" -> parent lacks #interrupt-cells!\n"); in of_irq_map_raw()
231 tmp = of_get_property(newpar, "#address-cells", NULL); in of_irq_map_raw()
234 pr_debug(" -> newintsize=%d, newaddrsize=%d\n", in of_irq_map_raw()
242 imaplen -= newaddrsize + newintsize; in of_irq_map_raw()
244 pr_debug(" -> imaplen=%d\n", imaplen); in of_irq_map_raw()
253 intspec = imap - intsize; in of_irq_map_raw()
254 addr = intspec - addrsize; in of_irq_map_raw()
257 /* Iterate again with new parent */ in of_irq_map_raw()
258 pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>"); in of_irq_map_raw()
268 return -EINVAL; in of_irq_map_raw()
273 * of_irq_map_one - Resolve an interrupt for a device
274 * @device: the device whose interrupt is to be resolved
275 * @index: index of the interrupt to resolve
278 * This function resolves an interrupt, walking the tree, for a given
279 * device-tree node. It's the high level pendant to of_irq_map_raw().
286 int res = -EINVAL; in of_irq_map_one()
288 pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); in of_irq_map_one()
297 return -EINVAL; in of_irq_map_one()
305 /* Look for the interrupt parent. */ in of_irq_map_one()
308 return -EINVAL; in of_irq_map_one()
310 /* Get size of interrupt specifier */ in of_irq_map_one()
311 tmp = of_get_property(p, "#interrupt-cells", NULL); in of_irq_map_one()
332 * of_irq_to_resource - Decode a node's IRQ and return it as a resource
334 * @index: zero-based index of the irq
347 * Get optional "interrupts-names" property to add a name in of_irq_to_resource()
350 of_property_read_string_index(dev, "interrupt-names", index, in of_irq_to_resource()
353 r->start = r->end = irq; in of_irq_to_resource()
354 r->flags = IORESOURCE_IRQ; in of_irq_to_resource()
355 r->name = name ? name : dev->full_name; in of_irq_to_resource()
363 * of_irq_count - Count the number of IRQs a node uses
377 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
403 * of_irq_init - Scan and init matching interrupt controllers in DT
406 * This function scans the device tree for matching interrupt controller nodes,
411 struct device_node *np, *parent = NULL; in of_irq_init() local
419 if (!of_find_property(np, "interrupt-controller", NULL)) in of_irq_init()
423 * pointer, interrupt-parent device_node etc. in of_irq_init()
429 desc->dev = np; in of_irq_init()
430 desc->interrupt_parent = of_irq_find_parent(np); in of_irq_init()
431 if (desc->interrupt_parent == np) in of_irq_init()
432 desc->interrupt_parent = NULL; in of_irq_init()
433 list_add_tail(&desc->list, &intc_desc_list); in of_irq_init()
437 * The root irq controller is the one without an interrupt-parent. in of_irq_init()
443 * Process all controllers with the current 'parent'. in of_irq_init()
444 * First pass will be looking for NULL as the parent. in of_irq_init()
445 * The assumption is that NULL parent means a root controller. in of_irq_init()
452 if (desc->interrupt_parent != parent) in of_irq_init()
455 list_del(&desc->list); in of_irq_init()
456 match = of_match_node(matches, desc->dev); in of_irq_init()
457 if (WARN(!match->data, in of_irq_init()
459 match->compatible)) { in of_irq_init()
464 pr_debug("of_irq_init: init %s @ %p, parent %p\n", in of_irq_init()
465 match->compatible, in of_irq_init()
466 desc->dev, desc->interrupt_parent); in of_irq_init()
467 irq_init_cb = match->data; in of_irq_init()
468 ret = irq_init_cb(desc->dev, desc->interrupt_parent); in of_irq_init()
475 * This one is now set up; add it to the parent list so in of_irq_init()
478 list_add_tail(&desc->list, &intc_parent_list); in of_irq_init()
481 /* Get the next pending parent that might have children */ in of_irq_init()
487 list_del(&desc->list); in of_irq_init()
488 parent = desc->dev; in of_irq_init()
493 list_del(&desc->list); in of_irq_init()
498 list_del(&desc->list); in of_irq_init()