linux/drivers/of/irq.c
<<
>>
Prefs
   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/device.h>
  20#include <linux/errno.h>
  21#include <linux/list.h>
  22#include <linux/module.h>
  23#include <linux/of.h>
  24#include <linux/of_irq.h>
  25#include <linux/of_pci.h>
  26#include <linux/string.h>
  27#include <linux/slab.h>
  28
  29/**
  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
  33 *
  34 * This function is a wrapper that chains of_irq_parse_one() and
  35 * irq_create_of_mapping() to make things easier to callers
  36 */
  37unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
  38{
  39        struct of_phandle_args oirq;
  40
  41        if (of_irq_parse_one(dev, index, &oirq))
  42                return 0;
  43
  44        return irq_create_of_mapping(&oirq);
  45}
  46EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
  47
  48/**
  49 * of_irq_find_parent - Given a device node, find its interrupt parent node
  50 * @child: pointer to device node
  51 *
  52 * Returns a pointer to the interrupt parent node, or NULL if the interrupt
  53 * parent could not be determined.
  54 */
  55struct device_node *of_irq_find_parent(struct device_node *child)
  56{
  57        struct device_node *p;
  58        phandle parent;
  59
  60        if (!of_node_get(child))
  61                return NULL;
  62
  63        do {
  64                if (of_property_read_u32(child, "interrupt-parent", &parent)) {
  65                        p = of_get_parent(child);
  66                } else  {
  67                        if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
  68                                p = of_node_get(of_irq_dflt_pic);
  69                        else
  70                                p = of_find_node_by_phandle(parent);
  71                }
  72                of_node_put(child);
  73                child = p;
  74        } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
  75
  76        return p;
  77}
  78EXPORT_SYMBOL_GPL(of_irq_find_parent);
  79
  80/**
  81 * of_irq_parse_raw - Low level interrupt tree parsing
  82 * @addr:       address specifier (start of "reg" property of the device) in be32 format
  83 * @out_irq:    structure of_phandle_args updated by this function
  84 *
  85 * Returns 0 on success and a negative number on error
  86 *
  87 * This function is a low-level interrupt tree walking function. It
  88 * can be used to do a partial walk with synthetized reg and interrupts
  89 * properties, for example when resolving PCI interrupts when no device
  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.
  93 */
  94int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
  95{
  96        struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
  97        __be32 initial_match_array[MAX_PHANDLE_ARGS];
  98        const __be32 *match_array = initial_match_array;
  99        const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = cpu_to_be32(~0) };
 100        u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
 101        int imaplen, match, i, rc = -EINVAL;
 102
 103#ifdef DEBUG
 104        of_print_phandle_args("of_irq_parse_raw: ", out_irq);
 105#endif
 106
 107        ipar = of_node_get(out_irq->np);
 108
 109        /* First get the #interrupt-cells property of the current cursor
 110         * that tells us how to interpret the passed-in intspec. If there
 111         * is none, we are nice and just walk up the tree
 112         */
 113        do {
 114                if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize))
 115                        break;
 116                tnode = ipar;
 117                ipar = of_irq_find_parent(ipar);
 118                of_node_put(tnode);
 119        } while (ipar);
 120        if (ipar == NULL) {
 121                pr_debug(" -> no parent found !\n");
 122                goto fail;
 123        }
 124
 125        pr_debug("of_irq_parse_raw: ipar=%pOF, size=%d\n", ipar, intsize);
 126
 127        if (out_irq->args_count != intsize)
 128                goto fail;
 129
 130        /* Look for this #address-cells. We have to implement the old linux
 131         * trick of looking for the parent here as some device-trees rely on it
 132         */
 133        old = of_node_get(ipar);
 134        do {
 135                tmp = of_get_property(old, "#address-cells", NULL);
 136                tnode = of_get_parent(old);
 137                of_node_put(old);
 138                old = tnode;
 139        } while (old && tmp == NULL);
 140        of_node_put(old);
 141        old = NULL;
 142        addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
 143
 144        pr_debug(" -> addrsize=%d\n", addrsize);
 145
 146        /* Range check so that the temporary buffer doesn't overflow */
 147        if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) {
 148                rc = -EFAULT;
 149                goto fail;
 150        }
 151
 152        /* Precalculate the match array - this simplifies match loop */
 153        for (i = 0; i < addrsize; i++)
 154                initial_match_array[i] = addr ? addr[i] : 0;
 155        for (i = 0; i < intsize; i++)
 156                initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
 157
 158        /* Now start the actual "proper" walk of the interrupt tree */
 159        while (ipar != NULL) {
 160                /* Now check if cursor is an interrupt-controller and if it is
 161                 * then we are done
 162                 */
 163                if (of_property_read_bool(ipar, "interrupt-controller")) {
 164                        pr_debug(" -> got it !\n");
 165                        return 0;
 166                }
 167
 168                /*
 169                 * interrupt-map parsing does not work without a reg
 170                 * property when #address-cells != 0
 171                 */
 172                if (addrsize && !addr) {
 173                        pr_debug(" -> no reg passed in when needed !\n");
 174                        goto fail;
 175                }
 176
 177                /* Now look for an interrupt-map */
 178                imap = of_get_property(ipar, "interrupt-map", &imaplen);
 179                /* No interrupt map, check for an interrupt parent */
 180                if (imap == NULL) {
 181                        pr_debug(" -> no map, getting parent\n");
 182                        newpar = of_irq_find_parent(ipar);
 183                        goto skiplevel;
 184                }
 185                imaplen /= sizeof(u32);
 186
 187                /* Look for a mask */
 188                imask = of_get_property(ipar, "interrupt-map-mask", NULL);
 189                if (!imask)
 190                        imask = dummy_imask;
 191
 192                /* Parse interrupt-map */
 193                match = 0;
 194                while (imaplen > (addrsize + intsize + 1) && !match) {
 195                        /* Compare specifiers */
 196                        match = 1;
 197                        for (i = 0; i < (addrsize + intsize); i++, imaplen--)
 198                                match &= !((match_array[i] ^ *imap++) & imask[i]);
 199
 200                        pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
 201
 202                        /* Get the interrupt parent */
 203                        if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
 204                                newpar = of_node_get(of_irq_dflt_pic);
 205                        else
 206                                newpar = of_find_node_by_phandle(be32_to_cpup(imap));
 207                        imap++;
 208                        --imaplen;
 209
 210                        /* Check if not found */
 211                        if (newpar == NULL) {
 212                                pr_debug(" -> imap parent not found !\n");
 213                                goto fail;
 214                        }
 215
 216                        if (!of_device_is_available(newpar))
 217                                match = 0;
 218
 219                        /* Get #interrupt-cells and #address-cells of new
 220                         * parent
 221                         */
 222                        if (of_property_read_u32(newpar, "#interrupt-cells",
 223                                                 &newintsize)) {
 224                                pr_debug(" -> parent lacks #interrupt-cells!\n");
 225                                goto fail;
 226                        }
 227                        if (of_property_read_u32(newpar, "#address-cells",
 228                                                 &newaddrsize))
 229                                newaddrsize = 0;
 230
 231                        pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
 232                            newintsize, newaddrsize);
 233
 234                        /* Check for malformed properties */
 235                        if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)
 236                            || (imaplen < (newaddrsize + newintsize))) {
 237                                rc = -EFAULT;
 238                                goto fail;
 239                        }
 240
 241                        imap += newaddrsize + newintsize;
 242                        imaplen -= newaddrsize + newintsize;
 243
 244                        pr_debug(" -> imaplen=%d\n", imaplen);
 245                }
 246                if (!match)
 247                        goto fail;
 248
 249                /*
 250                 * Successfully parsed an interrrupt-map translation; copy new
 251                 * interrupt specifier into the out_irq structure
 252                 */
 253                match_array = imap - newaddrsize - newintsize;
 254                for (i = 0; i < newintsize; i++)
 255                        out_irq->args[i] = be32_to_cpup(imap - newintsize + i);
 256                out_irq->args_count = intsize = newintsize;
 257                addrsize = newaddrsize;
 258
 259        skiplevel:
 260                /* Iterate again with new parent */
 261                out_irq->np = newpar;
 262                pr_debug(" -> new parent: %pOF\n", newpar);
 263                of_node_put(ipar);
 264                ipar = newpar;
 265                newpar = NULL;
 266        }
 267        rc = -ENOENT; /* No interrupt-map found */
 268
 269 fail:
 270        of_node_put(ipar);
 271        of_node_put(newpar);
 272
 273        return rc;
 274}
 275EXPORT_SYMBOL_GPL(of_irq_parse_raw);
 276
 277/**
 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
 281 * @out_irq: structure of_irq filled by this function
 282 *
 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.
 286 */
 287int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
 288{
 289        struct device_node *p;
 290        const __be32 *addr;
 291        u32 intsize;
 292        int i, res;
 293
 294        pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index);
 295
 296        /* OldWorld mac stuff is "special", handle out of line */
 297        if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
 298                return of_irq_parse_oldworld(device, index, out_irq);
 299
 300        /* Get the reg property (if any) */
 301        addr = of_get_property(device, "reg", NULL);
 302
 303        /* Try the new-style interrupts-extended first */
 304        res = of_parse_phandle_with_args(device, "interrupts-extended",
 305                                        "#interrupt-cells", index, out_irq);
 306        if (!res)
 307                return of_irq_parse_raw(addr, out_irq);
 308
 309        /* Look for the interrupt parent. */
 310        p = of_irq_find_parent(device);
 311        if (p == NULL)
 312                return -EINVAL;
 313
 314        /* Get size of interrupt specifier */
 315        if (of_property_read_u32(p, "#interrupt-cells", &intsize)) {
 316                res = -EINVAL;
 317                goto out;
 318        }
 319
 320        pr_debug(" parent=%pOF, intsize=%d\n", p, intsize);
 321
 322        /* Copy intspec into irq structure */
 323        out_irq->np = p;
 324        out_irq->args_count = intsize;
 325        for (i = 0; i < intsize; i++) {
 326                res = of_property_read_u32_index(device, "interrupts",
 327                                                 (index * intsize) + i,
 328                                                 out_irq->args + i);
 329                if (res)
 330                        goto out;
 331        }
 332
 333        pr_debug(" intspec=%d\n", *out_irq->args);
 334
 335
 336        /* Check if there are any interrupt-map translations to process */
 337        res = of_irq_parse_raw(addr, out_irq);
 338 out:
 339        of_node_put(p);
 340        return res;
 341}
 342EXPORT_SYMBOL_GPL(of_irq_parse_one);
 343
 344/**
 345 * of_irq_to_resource - Decode a node's IRQ and return it as a resource
 346 * @dev: pointer to device tree node
 347 * @index: zero-based index of the irq
 348 * @r: pointer to resource structure to return result into.
 349 */
 350int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
 351{
 352        int irq = of_irq_get(dev, index);
 353
 354        if (irq < 0)
 355                return irq;
 356
 357        /* Only dereference the resource if both the
 358         * resource and the irq are valid. */
 359        if (r && irq) {
 360                const char *name = NULL;
 361
 362                memset(r, 0, sizeof(*r));
 363                /*
 364                 * Get optional "interrupt-names" property to add a name
 365                 * to the resource.
 366                 */
 367                of_property_read_string_index(dev, "interrupt-names", index,
 368                                              &name);
 369
 370                r->start = r->end = irq;
 371                r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq));
 372                r->name = name ? name : of_node_full_name(dev);
 373        }
 374
 375        return irq;
 376}
 377EXPORT_SYMBOL_GPL(of_irq_to_resource);
 378
 379/**
 380 * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
 381 * @dev: pointer to device tree node
 382 * @index: zero-based index of the IRQ
 383 *
 384 * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
 385 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
 386 * of any other failure.
 387 */
 388int of_irq_get(struct device_node *dev, int index)
 389{
 390        int rc;
 391        struct of_phandle_args oirq;
 392        struct irq_domain *domain;
 393
 394        rc = of_irq_parse_one(dev, index, &oirq);
 395        if (rc)
 396                return rc;
 397
 398        domain = irq_find_host(oirq.np);
 399        if (!domain)
 400                return -EPROBE_DEFER;
 401
 402        return irq_create_of_mapping(&oirq);
 403}
 404EXPORT_SYMBOL_GPL(of_irq_get);
 405
 406/**
 407 * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
 408 * @dev: pointer to device tree node
 409 * @name: IRQ name
 410 *
 411 * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
 412 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
 413 * of any other failure.
 414 */
 415int of_irq_get_byname(struct device_node *dev, const char *name)
 416{
 417        int index;
 418
 419        if (unlikely(!name))
 420                return -EINVAL;
 421
 422        index = of_property_match_string(dev, "interrupt-names", name);
 423        if (index < 0)
 424                return index;
 425
 426        return of_irq_get(dev, index);
 427}
 428EXPORT_SYMBOL_GPL(of_irq_get_byname);
 429
 430/**
 431 * of_irq_count - Count the number of IRQs a node uses
 432 * @dev: pointer to device tree node
 433 */
 434int of_irq_count(struct device_node *dev)
 435{
 436        struct of_phandle_args irq;
 437        int nr = 0;
 438
 439        while (of_irq_parse_one(dev, nr, &irq) == 0)
 440                nr++;
 441
 442        return nr;
 443}
 444
 445/**
 446 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
 447 * @dev: pointer to device tree node
 448 * @res: array of resources to fill in
 449 * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
 450 *
 451 * Returns the size of the filled in table (up to @nr_irqs).
 452 */
 453int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
 454                int nr_irqs)
 455{
 456        int i;
 457
 458        for (i = 0; i < nr_irqs; i++, res++)
 459                if (of_irq_to_resource(dev, i, res) <= 0)
 460                        break;
 461
 462        return i;
 463}
 464EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
 465
 466struct of_intc_desc {
 467        struct list_head        list;
 468        of_irq_init_cb_t        irq_init_cb;
 469        struct device_node      *dev;
 470        struct device_node      *interrupt_parent;
 471};
 472
 473/**
 474 * of_irq_init - Scan and init matching interrupt controllers in DT
 475 * @matches: 0 terminated array of nodes to match and init function to call
 476 *
 477 * This function scans the device tree for matching interrupt controller nodes,
 478 * and calls their initialization functions in order with parents first.
 479 */
 480void __init of_irq_init(const struct of_device_id *matches)
 481{
 482        const struct of_device_id *match;
 483        struct device_node *np, *parent = NULL;
 484        struct of_intc_desc *desc, *temp_desc;
 485        struct list_head intc_desc_list, intc_parent_list;
 486
 487        INIT_LIST_HEAD(&intc_desc_list);
 488        INIT_LIST_HEAD(&intc_parent_list);
 489
 490        for_each_matching_node_and_match(np, matches, &match) {
 491                if (!of_property_read_bool(np, "interrupt-controller") ||
 492                                !of_device_is_available(np))
 493                        continue;
 494
 495                if (WARN(!match->data, "of_irq_init: no init function for %s\n",
 496                         match->compatible))
 497                        continue;
 498
 499                /*
 500                 * Here, we allocate and populate an of_intc_desc with the node
 501                 * pointer, interrupt-parent device_node etc.
 502                 */
 503                desc = kzalloc(sizeof(*desc), GFP_KERNEL);
 504                if (WARN_ON(!desc)) {
 505                        of_node_put(np);
 506                        goto err;
 507                }
 508
 509                desc->irq_init_cb = match->data;
 510                desc->dev = of_node_get(np);
 511                desc->interrupt_parent = of_irq_find_parent(np);
 512                if (desc->interrupt_parent == np)
 513                        desc->interrupt_parent = NULL;
 514                list_add_tail(&desc->list, &intc_desc_list);
 515        }
 516
 517        /*
 518         * The root irq controller is the one without an interrupt-parent.
 519         * That one goes first, followed by the controllers that reference it,
 520         * followed by the ones that reference the 2nd level controllers, etc.
 521         */
 522        while (!list_empty(&intc_desc_list)) {
 523                /*
 524                 * Process all controllers with the current 'parent'.
 525                 * First pass will be looking for NULL as the parent.
 526                 * The assumption is that NULL parent means a root controller.
 527                 */
 528                list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
 529                        int ret;
 530
 531                        if (desc->interrupt_parent != parent)
 532                                continue;
 533
 534                        list_del(&desc->list);
 535
 536                        of_node_set_flag(desc->dev, OF_POPULATED);
 537
 538                        pr_debug("of_irq_init: init %pOF (%p), parent %p\n",
 539                                 desc->dev,
 540                                 desc->dev, desc->interrupt_parent);
 541                        ret = desc->irq_init_cb(desc->dev,
 542                                                desc->interrupt_parent);
 543                        if (ret) {
 544                                of_node_clear_flag(desc->dev, OF_POPULATED);
 545                                kfree(desc);
 546                                continue;
 547                        }
 548
 549                        /*
 550                         * This one is now set up; add it to the parent list so
 551                         * its children can get processed in a subsequent pass.
 552                         */
 553                        list_add_tail(&desc->list, &intc_parent_list);
 554                }
 555
 556                /* Get the next pending parent that might have children */
 557                desc = list_first_entry_or_null(&intc_parent_list,
 558                                                typeof(*desc), list);
 559                if (!desc) {
 560                        pr_err("of_irq_init: children remain, but no parents\n");
 561                        break;
 562                }
 563                list_del(&desc->list);
 564                parent = desc->dev;
 565                kfree(desc);
 566        }
 567
 568        list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
 569                list_del(&desc->list);
 570                kfree(desc);
 571        }
 572err:
 573        list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
 574                list_del(&desc->list);
 575                of_node_put(desc->dev);
 576                kfree(desc);
 577        }
 578}
 579
 580static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
 581                            u32 rid_in)
 582{
 583        struct device *parent_dev;
 584        u32 rid_out = rid_in;
 585
 586        /*
 587         * Walk up the device parent links looking for one with a
 588         * "msi-map" property.
 589         */
 590        for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
 591                if (!of_pci_map_rid(parent_dev->of_node, rid_in, "msi-map",
 592                                    "msi-map-mask", np, &rid_out))
 593                        break;
 594        return rid_out;
 595}
 596
 597/**
 598 * of_msi_map_rid - Map a MSI requester ID for a device.
 599 * @dev: device for which the mapping is to be done.
 600 * @msi_np: device node of the expected msi controller.
 601 * @rid_in: unmapped MSI requester ID for the device.
 602 *
 603 * Walk up the device hierarchy looking for devices with a "msi-map"
 604 * property.  If found, apply the mapping to @rid_in.
 605 *
 606 * Returns the mapped MSI requester ID.
 607 */
 608u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
 609{
 610        return __of_msi_map_rid(dev, &msi_np, rid_in);
 611}
 612
 613/**
 614 * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
 615 * @dev: device for which the mapping is to be done.
 616 * @rid: Requester ID for the device.
 617 *
 618 * Walk up the device hierarchy looking for devices with a "msi-map"
 619 * property.
 620 *
 621 * Returns: the MSI domain for this device (or NULL on failure)
 622 */
 623struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)
 624{
 625        struct device_node *np = NULL;
 626
 627        __of_msi_map_rid(dev, &np, rid);
 628        return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
 629}
 630
 631/**
 632 * of_msi_get_domain - Use msi-parent to find the relevant MSI domain
 633 * @dev: device for which the domain is requested
 634 * @np: device node for @dev
 635 * @token: bus type for this domain
 636 *
 637 * Parse the msi-parent property (both the simple and the complex
 638 * versions), and returns the corresponding MSI domain.
 639 *
 640 * Returns: the MSI domain for this device (or NULL on failure).
 641 */
 642struct irq_domain *of_msi_get_domain(struct device *dev,
 643                                     struct device_node *np,
 644                                     enum irq_domain_bus_token token)
 645{
 646        struct device_node *msi_np;
 647        struct irq_domain *d;
 648
 649        /* Check for a single msi-parent property */
 650        msi_np = of_parse_phandle(np, "msi-parent", 0);
 651        if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) {
 652                d = irq_find_matching_host(msi_np, token);
 653                if (!d)
 654                        of_node_put(msi_np);
 655                return d;
 656        }
 657
 658        if (token == DOMAIN_BUS_PLATFORM_MSI) {
 659                /* Check for the complex msi-parent version */
 660                struct of_phandle_args args;
 661                int index = 0;
 662
 663                while (!of_parse_phandle_with_args(np, "msi-parent",
 664                                                   "#msi-cells",
 665                                                   index, &args)) {
 666                        d = irq_find_matching_host(args.np, token);
 667                        if (d)
 668                                return d;
 669
 670                        of_node_put(args.np);
 671                        index++;
 672                }
 673        }
 674
 675        return NULL;
 676}
 677
 678/**
 679 * of_msi_configure - Set the msi_domain field of a device
 680 * @dev: device structure to associate with an MSI irq domain
 681 * @np: device node for that device
 682 */
 683void of_msi_configure(struct device *dev, struct device_node *np)
 684{
 685        dev_set_msi_domain(dev,
 686                           of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
 687}
 688EXPORT_SYMBOL_GPL(of_msi_configure);
 689