linux/drivers/of/of_pci.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include <linux/export.h>
   3#include <linux/of.h>
   4#include <linux/of_address.h>
   5#include <linux/of_device.h>
   6#include <linux/of_pci.h>
   7#include <linux/slab.h>
   8#include <asm-generic/pci-bridge.h>
   9
  10static inline int __of_pci_pci_compare(struct device_node *node,
  11                                       unsigned int data)
  12{
  13        int devfn;
  14
  15        devfn = of_pci_get_devfn(node);
  16        if (devfn < 0)
  17                return 0;
  18
  19        return devfn == data;
  20}
  21
  22struct device_node *of_pci_find_child_device(struct device_node *parent,
  23                                             unsigned int devfn)
  24{
  25        struct device_node *node, *node2;
  26
  27        for_each_child_of_node(parent, node) {
  28                if (__of_pci_pci_compare(node, devfn))
  29                        return node;
  30                /*
  31                 * Some OFs create a parent node "multifunc-device" as
  32                 * a fake root for all functions of a multi-function
  33                 * device we go down them as well.
  34                 */
  35                if (!strcmp(node->name, "multifunc-device")) {
  36                        for_each_child_of_node(node, node2) {
  37                                if (__of_pci_pci_compare(node2, devfn)) {
  38                                        of_node_put(node);
  39                                        return node2;
  40                                }
  41                        }
  42                }
  43        }
  44        return NULL;
  45}
  46EXPORT_SYMBOL_GPL(of_pci_find_child_device);
  47
  48/**
  49 * of_pci_get_devfn() - Get device and function numbers for a device node
  50 * @np: device node
  51 *
  52 * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
  53 * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
  54 * and function numbers respectively. On error a negative error code is
  55 * returned.
  56 */
  57int of_pci_get_devfn(struct device_node *np)
  58{
  59        unsigned int size;
  60        const __be32 *reg;
  61
  62        reg = of_get_property(np, "reg", &size);
  63
  64        if (!reg || size < 5 * sizeof(__be32))
  65                return -EINVAL;
  66
  67        return (be32_to_cpup(reg) >> 8) & 0xff;
  68}
  69EXPORT_SYMBOL_GPL(of_pci_get_devfn);
  70
  71/**
  72 * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
  73 * @node: device node
  74 * @res: address to a struct resource to return the bus-range
  75 *
  76 * Returns 0 on success or a negative error-code on failure.
  77 */
  78int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
  79{
  80        const __be32 *values;
  81        int len;
  82
  83        values = of_get_property(node, "bus-range", &len);
  84        if (!values || len < sizeof(*values) * 2)
  85                return -EINVAL;
  86
  87        res->name = node->name;
  88        res->start = be32_to_cpup(values++);
  89        res->end = be32_to_cpup(values);
  90        res->flags = IORESOURCE_BUS;
  91
  92        return 0;
  93}
  94EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
  95
  96/**
  97 * This function will try to obtain the host bridge domain number by
  98 * finding a property called "linux,pci-domain" of the given device node.
  99 *
 100 * @node: device tree node with the domain information
 101 *
 102 * Returns the associated domain number from DT in the range [0-0xffff], or
 103 * a negative value if the required property is not found.
 104 */
 105int of_get_pci_domain_nr(struct device_node *node)
 106{
 107        const __be32 *value;
 108        int len;
 109        u16 domain;
 110
 111        value = of_get_property(node, "linux,pci-domain", &len);
 112        if (!value || len < sizeof(*value))
 113                return -EINVAL;
 114
 115        domain = (u16)be32_to_cpup(value);
 116
 117        return domain;
 118}
 119EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 120
 121/**
 122 * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
 123 *                           is present and valid
 124 */
 125void of_pci_check_probe_only(void)
 126{
 127        u32 val;
 128        int ret;
 129
 130        ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
 131        if (ret) {
 132                if (ret == -ENODATA || ret == -EOVERFLOW)
 133                        pr_warn("linux,pci-probe-only without valid value, ignoring\n");
 134                return;
 135        }
 136
 137        if (val)
 138                pci_add_flags(PCI_PROBE_ONLY);
 139        else
 140                pci_clear_flags(PCI_PROBE_ONLY);
 141
 142        pr_info("PCI: PROBE_ONLY %sabled\n", val ? "en" : "dis");
 143}
 144EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
 145
 146#if defined(CONFIG_OF_ADDRESS)
 147/**
 148 * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
 149 * @dev: device node of the host bridge having the range property
 150 * @busno: bus number associated with the bridge root bus
 151 * @bus_max: maximum number of buses for this bridge
 152 * @resources: list where the range of resources will be added after DT parsing
 153 * @io_base: pointer to a variable that will contain on return the physical
 154 * address for the start of the I/O range. Can be NULL if the caller doesn't
 155 * expect IO ranges to be present in the device tree.
 156 *
 157 * It is the caller's job to free the @resources list.
 158 *
 159 * This function will parse the "ranges" property of a PCI host bridge device
 160 * node and setup the resource mapping based on its content. It is expected
 161 * that the property conforms with the Power ePAPR document.
 162 *
 163 * It returns zero if the range parsing has been successful or a standard error
 164 * value if it failed.
 165 */
 166int of_pci_get_host_bridge_resources(struct device_node *dev,
 167                        unsigned char busno, unsigned char bus_max,
 168                        struct list_head *resources, resource_size_t *io_base)
 169{
 170        struct resource_entry *window;
 171        struct resource *res;
 172        struct resource *bus_range;
 173        struct of_pci_range range;
 174        struct of_pci_range_parser parser;
 175        char range_type[4];
 176        int err;
 177
 178        if (io_base)
 179                *io_base = (resource_size_t)OF_BAD_ADDR;
 180
 181        bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
 182        if (!bus_range)
 183                return -ENOMEM;
 184
 185        pr_info("PCI host bridge %s ranges:\n", dev->full_name);
 186
 187        err = of_pci_parse_bus_range(dev, bus_range);
 188        if (err) {
 189                bus_range->start = busno;
 190                bus_range->end = bus_max;
 191                bus_range->flags = IORESOURCE_BUS;
 192                pr_info("  No bus range found for %s, using %pR\n",
 193                        dev->full_name, bus_range);
 194        } else {
 195                if (bus_range->end > bus_range->start + bus_max)
 196                        bus_range->end = bus_range->start + bus_max;
 197        }
 198        pci_add_resource(resources, bus_range);
 199
 200        /* Check for ranges property */
 201        err = of_pci_range_parser_init(&parser, dev);
 202        if (err)
 203                goto parse_failed;
 204
 205        pr_debug("Parsing ranges property...\n");
 206        for_each_of_pci_range(&parser, &range) {
 207                /* Read next ranges element */
 208                if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
 209                        snprintf(range_type, 4, " IO");
 210                else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
 211                        snprintf(range_type, 4, "MEM");
 212                else
 213                        snprintf(range_type, 4, "err");
 214                pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
 215                        range.cpu_addr, range.cpu_addr + range.size - 1,
 216                        range.pci_addr);
 217
 218                /*
 219                 * If we failed translation or got a zero-sized region
 220                 * then skip this range
 221                 */
 222                if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
 223                        continue;
 224
 225                res = kzalloc(sizeof(struct resource), GFP_KERNEL);
 226                if (!res) {
 227                        err = -ENOMEM;
 228                        goto parse_failed;
 229                }
 230
 231                err = of_pci_range_to_resource(&range, dev, res);
 232                if (err) {
 233                        kfree(res);
 234                        continue;
 235                }
 236
 237                if (resource_type(res) == IORESOURCE_IO) {
 238                        if (!io_base) {
 239                                pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
 240                                        dev->full_name);
 241                                err = -EINVAL;
 242                                goto conversion_failed;
 243                        }
 244                        if (*io_base != (resource_size_t)OF_BAD_ADDR)
 245                                pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
 246                                        dev->full_name);
 247                        *io_base = range.cpu_addr;
 248                }
 249
 250                pci_add_resource_offset(resources, res, res->start - range.pci_addr);
 251        }
 252
 253        return 0;
 254
 255conversion_failed:
 256        kfree(res);
 257parse_failed:
 258        resource_list_for_each_entry(window, resources)
 259                kfree(window->res);
 260        pci_free_resource_list(resources);
 261        return err;
 262}
 263EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
 264#endif /* CONFIG_OF_ADDRESS */
 265
 266#ifdef CONFIG_PCI_MSI
 267
 268static LIST_HEAD(of_pci_msi_chip_list);
 269static DEFINE_MUTEX(of_pci_msi_chip_mutex);
 270
 271int of_pci_msi_chip_add(struct msi_controller *chip)
 272{
 273        if (!of_property_read_bool(chip->of_node, "msi-controller"))
 274                return -EINVAL;
 275
 276        mutex_lock(&of_pci_msi_chip_mutex);
 277        list_add(&chip->list, &of_pci_msi_chip_list);
 278        mutex_unlock(&of_pci_msi_chip_mutex);
 279
 280        return 0;
 281}
 282EXPORT_SYMBOL_GPL(of_pci_msi_chip_add);
 283
 284void of_pci_msi_chip_remove(struct msi_controller *chip)
 285{
 286        mutex_lock(&of_pci_msi_chip_mutex);
 287        list_del(&chip->list);
 288        mutex_unlock(&of_pci_msi_chip_mutex);
 289}
 290EXPORT_SYMBOL_GPL(of_pci_msi_chip_remove);
 291
 292struct msi_controller *of_pci_find_msi_chip_by_node(struct device_node *of_node)
 293{
 294        struct msi_controller *c;
 295
 296        mutex_lock(&of_pci_msi_chip_mutex);
 297        list_for_each_entry(c, &of_pci_msi_chip_list, list) {
 298                if (c->of_node == of_node) {
 299                        mutex_unlock(&of_pci_msi_chip_mutex);
 300                        return c;
 301                }
 302        }
 303        mutex_unlock(&of_pci_msi_chip_mutex);
 304
 305        return NULL;
 306}
 307EXPORT_SYMBOL_GPL(of_pci_find_msi_chip_by_node);
 308
 309#endif /* CONFIG_PCI_MSI */
 310