linux/drivers/pci/of.c
<<
>>
Prefs
   1/*
   2 * PCI <-> OF mapping helpers
   3 *
   4 * Copyright 2011 IBM Corp.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/irqdomain.h>
  13#include <linux/kernel.h>
  14#include <linux/pci.h>
  15#include <linux/of.h>
  16#include <linux/of_irq.h>
  17#include <linux/of_pci.h>
  18#include "pci.h"
  19
  20void pci_set_of_node(struct pci_dev *dev)
  21{
  22        if (!dev->bus->dev.of_node)
  23                return;
  24        dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node,
  25                                                    dev->devfn);
  26}
  27
  28void pci_release_of_node(struct pci_dev *dev)
  29{
  30        of_node_put(dev->dev.of_node);
  31        dev->dev.of_node = NULL;
  32}
  33
  34void pci_set_bus_of_node(struct pci_bus *bus)
  35{
  36        if (bus->self == NULL)
  37                bus->dev.of_node = pcibios_get_phb_of_node(bus);
  38        else
  39                bus->dev.of_node = of_node_get(bus->self->dev.of_node);
  40}
  41
  42void pci_release_bus_of_node(struct pci_bus *bus)
  43{
  44        of_node_put(bus->dev.of_node);
  45        bus->dev.of_node = NULL;
  46}
  47
  48struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
  49{
  50        /* This should only be called for PHBs */
  51        if (WARN_ON(bus->self || bus->parent))
  52                return NULL;
  53
  54        /* Look for a node pointer in either the intermediary device we
  55         * create above the root bus or it's own parent. Normally only
  56         * the later is populated.
  57         */
  58        if (bus->bridge->of_node)
  59                return of_node_get(bus->bridge->of_node);
  60        if (bus->bridge->parent && bus->bridge->parent->of_node)
  61                return of_node_get(bus->bridge->parent->of_node);
  62        return NULL;
  63}
  64
  65struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
  66{
  67#ifdef CONFIG_IRQ_DOMAIN
  68        struct irq_domain *d;
  69
  70        if (!bus->dev.of_node)
  71                return NULL;
  72
  73        /* Start looking for a phandle to an MSI controller. */
  74        d = of_msi_get_domain(&bus->dev, bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
  75        if (d)
  76                return d;
  77
  78        /*
  79         * If we don't have an msi-parent property, look for a domain
  80         * directly attached to the host bridge.
  81         */
  82        d = irq_find_matching_host(bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
  83        if (d)
  84                return d;
  85
  86        return irq_find_host(bus->dev.of_node);
  87#else
  88        return NULL;
  89#endif
  90}
  91