21 #include <linux/errno.h>
22 #include <linux/list.h>
23 #include <linux/module.h>
26 #include <linux/string.h>
27 #include <linux/slab.h>
61 if (!of_node_get(child))
69 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
70 p = of_node_get(of_irq_dflt_pic);
101 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
104 pr_debug(
"of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
108 ipar = of_node_get(parent);
125 pr_debug(
" -> no parent found !\n");
131 if (ointsize != intsize)
137 old = of_node_get(ipar);
143 }
while (old && tmp ==
NULL);
148 pr_debug(
" -> addrsize=%d\n", addrsize);
151 while (ipar !=
NULL) {
158 for (i = 0; i < intsize; i++)
159 out_irq->specifier[i] =
160 of_read_number(intspec +i, 1);
161 out_irq->size = intsize;
162 out_irq->controller = ipar;
171 pr_debug(
" -> no map, getting parent\n");
175 imaplen /=
sizeof(
u32);
184 if (addr ==
NULL && addrsize != 0) {
185 pr_debug(
" -> no reg passed in when needed !\n");
191 while (imaplen > (addrsize + intsize + 1) && !match) {
194 for (i = 0; i < addrsize &&
match; ++
i) {
197 match = ((addr[
i] ^ imap[
i]) & mask) == 0;
199 for (; i < (addrsize + intsize) && match; ++
i) {
203 ((intspec[i-addrsize] ^ imap[
i]) & mask) == 0;
205 imap += addrsize + intsize;
206 imaplen -= addrsize + intsize;
208 pr_debug(
" -> match=%d (imaplen=%d)\n", match, imaplen);
211 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
212 newpar = of_node_get(of_irq_dflt_pic);
219 if (newpar ==
NULL) {
220 pr_debug(
" -> imap parent not found !\n");
229 pr_debug(
" -> parent lacks #interrupt-cells!\n");
236 pr_debug(
" -> newintsize=%d, newaddrsize=%d\n",
237 newintsize, newaddrsize);
240 if (imaplen < (newaddrsize + newintsize))
243 imap += newaddrsize + newintsize;
244 imaplen -= newaddrsize + newintsize;
246 pr_debug(
" -> imaplen=%d\n", imaplen);
252 old = of_node_get(newpar);
253 addrsize = newaddrsize;
254 intsize = newintsize;
255 intspec = imap - intsize;
256 addr = intspec - addrsize;
260 pr_debug(
" -> new parent: %s\n", of_node_full_name(newpar));
293 if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
294 return of_irq_map_oldworld(device, index, out_irq);
300 intlen /=
sizeof(*intspec);
318 pr_debug(
" intsize=%d intlen=%d\n", intsize, intlen);
321 if ((index + 1) * intsize > intlen)
391 for (i = 0; i <
nr_irqs; i++, res++)
416 struct list_head intc_desc_list, intc_parent_list;
418 INIT_LIST_HEAD(&intc_desc_list);
419 INIT_LIST_HEAD(&intc_parent_list);
421 for_each_matching_node(np, matches) {
444 while (!list_empty(&intc_desc_list)) {
453 of_irq_init_cb_t irq_init_cb;
461 "of_irq_init: no init function for %s\n",
467 pr_debug(
"of_irq_init: init %s @ %p, parent %p\n",
470 irq_init_cb = (of_irq_init_cb_t)match->
data;
486 if (list_empty(&intc_parent_list) || !desc) {
487 pr_err(
"of_irq_init: children remain, but no parents\n");