root/arch/arm64/kernel/pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcibios_alloc_irq
  2. raw_pci_read
  3. raw_pci_write
  4. pcibus_to_node
  5. acpi_pci_bus_find_domain_nr
  6. pcibios_root_bridge_prepare
  7. pci_acpi_root_prepare_resources
  8. pci_acpi_setup_ecam_mapping
  9. pci_acpi_generic_release_info
  10. pci_acpi_scan_root
  11. pcibios_add_bus
  12. pcibios_remove_bus

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Code borrowed from powerpc/kernel/pci-common.c
   4  *
   5  * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
   6  * Copyright (C) 2014 ARM Ltd.
   7  */
   8 
   9 #include <linux/acpi.h>
  10 #include <linux/init.h>
  11 #include <linux/io.h>
  12 #include <linux/kernel.h>
  13 #include <linux/mm.h>
  14 #include <linux/of_pci.h>
  15 #include <linux/of_platform.h>
  16 #include <linux/pci.h>
  17 #include <linux/pci-acpi.h>
  18 #include <linux/pci-ecam.h>
  19 #include <linux/slab.h>
  20 
  21 #ifdef CONFIG_ACPI
  22 /*
  23  * Try to assign the IRQ number when probing a new device
  24  */
  25 int pcibios_alloc_irq(struct pci_dev *dev)
  26 {
  27         if (!acpi_disabled)
  28                 acpi_pci_irq_enable(dev);
  29 
  30         return 0;
  31 }
  32 #endif
  33 
  34 /*
  35  * raw_pci_read/write - Platform-specific PCI config space access.
  36  */
  37 int raw_pci_read(unsigned int domain, unsigned int bus,
  38                   unsigned int devfn, int reg, int len, u32 *val)
  39 {
  40         struct pci_bus *b = pci_find_bus(domain, bus);
  41 
  42         if (!b)
  43                 return PCIBIOS_DEVICE_NOT_FOUND;
  44         return b->ops->read(b, devfn, reg, len, val);
  45 }
  46 
  47 int raw_pci_write(unsigned int domain, unsigned int bus,
  48                 unsigned int devfn, int reg, int len, u32 val)
  49 {
  50         struct pci_bus *b = pci_find_bus(domain, bus);
  51 
  52         if (!b)
  53                 return PCIBIOS_DEVICE_NOT_FOUND;
  54         return b->ops->write(b, devfn, reg, len, val);
  55 }
  56 
  57 #ifdef CONFIG_NUMA
  58 
  59 int pcibus_to_node(struct pci_bus *bus)
  60 {
  61         return dev_to_node(&bus->dev);
  62 }
  63 EXPORT_SYMBOL(pcibus_to_node);
  64 
  65 #endif
  66 
  67 #ifdef CONFIG_ACPI
  68 
  69 struct acpi_pci_generic_root_info {
  70         struct acpi_pci_root_info       common;
  71         struct pci_config_window        *cfg;   /* config space mapping */
  72 };
  73 
  74 int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
  75 {
  76         struct pci_config_window *cfg = bus->sysdata;
  77         struct acpi_device *adev = to_acpi_device(cfg->parent);
  78         struct acpi_pci_root *root = acpi_driver_data(adev);
  79 
  80         return root->segment;
  81 }
  82 
  83 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
  84 {
  85         if (!acpi_disabled) {
  86                 struct pci_config_window *cfg = bridge->bus->sysdata;
  87                 struct acpi_device *adev = to_acpi_device(cfg->parent);
  88                 struct device *bus_dev = &bridge->bus->dev;
  89 
  90                 ACPI_COMPANION_SET(&bridge->dev, adev);
  91                 set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev)));
  92         }
  93 
  94         return 0;
  95 }
  96 
  97 static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
  98 {
  99         struct resource_entry *entry, *tmp;
 100         int status;
 101 
 102         status = acpi_pci_probe_root_resources(ci);
 103         resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
 104                 if (!(entry->res->flags & IORESOURCE_WINDOW))
 105                         resource_list_destroy_entry(entry);
 106         }
 107         return status;
 108 }
 109 
 110 /*
 111  * Lookup the bus range for the domain in MCFG, and set up config space
 112  * mapping.
 113  */
 114 static struct pci_config_window *
 115 pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
 116 {
 117         struct device *dev = &root->device->dev;
 118         struct resource *bus_res = &root->secondary;
 119         u16 seg = root->segment;
 120         struct pci_ecam_ops *ecam_ops;
 121         struct resource cfgres;
 122         struct acpi_device *adev;
 123         struct pci_config_window *cfg;
 124         int ret;
 125 
 126         ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
 127         if (ret) {
 128                 dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res);
 129                 return NULL;
 130         }
 131 
 132         adev = acpi_resource_consumer(&cfgres);
 133         if (adev)
 134                 dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres,
 135                          dev_name(&adev->dev));
 136         else
 137                 dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n",
 138                          &cfgres);
 139 
 140         cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
 141         if (IS_ERR(cfg)) {
 142                 dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res,
 143                         PTR_ERR(cfg));
 144                 return NULL;
 145         }
 146 
 147         return cfg;
 148 }
 149 
 150 /* release_info: free resources allocated by init_info */
 151 static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
 152 {
 153         struct acpi_pci_generic_root_info *ri;
 154 
 155         ri = container_of(ci, struct acpi_pci_generic_root_info, common);
 156         pci_ecam_free(ri->cfg);
 157         kfree(ci->ops);
 158         kfree(ri);
 159 }
 160 
 161 /* Interface called from ACPI code to setup PCI host controller */
 162 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 163 {
 164         struct acpi_pci_generic_root_info *ri;
 165         struct pci_bus *bus, *child;
 166         struct acpi_pci_root_ops *root_ops;
 167         struct pci_host_bridge *host;
 168 
 169         ri = kzalloc(sizeof(*ri), GFP_KERNEL);
 170         if (!ri)
 171                 return NULL;
 172 
 173         root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL);
 174         if (!root_ops) {
 175                 kfree(ri);
 176                 return NULL;
 177         }
 178 
 179         ri->cfg = pci_acpi_setup_ecam_mapping(root);
 180         if (!ri->cfg) {
 181                 kfree(ri);
 182                 kfree(root_ops);
 183                 return NULL;
 184         }
 185 
 186         root_ops->release_info = pci_acpi_generic_release_info;
 187         root_ops->prepare_resources = pci_acpi_root_prepare_resources;
 188         root_ops->pci_ops = &ri->cfg->ops->pci_ops;
 189         bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
 190         if (!bus)
 191                 return NULL;
 192 
 193         /* If we must preserve the resource configuration, claim now */
 194         host = pci_find_host_bridge(bus);
 195         if (host->preserve_config)
 196                 pci_bus_claim_resources(bus);
 197 
 198         /*
 199          * Assign whatever was left unassigned. If we didn't claim above,
 200          * this will reassign everything.
 201          */
 202         pci_assign_unassigned_root_bus_resources(bus);
 203 
 204         list_for_each_entry(child, &bus->children, node)
 205                 pcie_bus_configure_settings(child);
 206 
 207         return bus;
 208 }
 209 
 210 void pcibios_add_bus(struct pci_bus *bus)
 211 {
 212         acpi_pci_add_bus(bus);
 213 }
 214 
 215 void pcibios_remove_bus(struct pci_bus *bus)
 216 {
 217         acpi_pci_remove_bus(bus);
 218 }
 219 
 220 #endif

/* [<][>][^][v][top][bottom][index][help] */