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