pci.c (5503B)
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 */ 25int 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 */ 37int 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 47int 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 59int pcibus_to_node(struct pci_bus *bus) 60{ 61 return dev_to_node(&bus->dev); 62} 63EXPORT_SYMBOL(pcibus_to_node); 64 65#endif 66 67#ifdef CONFIG_ACPI 68 69struct acpi_pci_generic_root_info { 70 struct acpi_pci_root_info common; 71 struct pci_config_window *cfg; /* config space mapping */ 72}; 73 74int 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 83int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) 84{ 85 struct pci_config_window *cfg; 86 struct acpi_device *adev; 87 struct device *bus_dev; 88 89 if (acpi_disabled) 90 return 0; 91 92 cfg = bridge->bus->sysdata; 93 94 /* 95 * On Hyper-V there is no corresponding ACPI device for a root bridge, 96 * therefore ->parent is set as NULL by the driver. And set 'adev' as 97 * NULL in this case because there is no proper ACPI device. 98 */ 99 if (!cfg->parent) 100 adev = NULL; 101 else 102 adev = to_acpi_device(cfg->parent); 103 104 bus_dev = &bridge->bus->dev; 105 106 ACPI_COMPANION_SET(&bridge->dev, adev); 107 set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev))); 108 109 return 0; 110} 111 112static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci) 113{ 114 struct resource_entry *entry, *tmp; 115 int status; 116 117 status = acpi_pci_probe_root_resources(ci); 118 resource_list_for_each_entry_safe(entry, tmp, &ci->resources) { 119 if (!(entry->res->flags & IORESOURCE_WINDOW)) 120 resource_list_destroy_entry(entry); 121 } 122 return status; 123} 124 125/* 126 * Lookup the bus range for the domain in MCFG, and set up config space 127 * mapping. 128 */ 129static struct pci_config_window * 130pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) 131{ 132 struct device *dev = &root->device->dev; 133 struct resource *bus_res = &root->secondary; 134 u16 seg = root->segment; 135 const struct pci_ecam_ops *ecam_ops; 136 struct resource cfgres; 137 struct acpi_device *adev; 138 struct pci_config_window *cfg; 139 int ret; 140 141 ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops); 142 if (ret) { 143 dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res); 144 return NULL; 145 } 146 147 adev = acpi_resource_consumer(&cfgres); 148 if (adev) 149 dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres, 150 dev_name(&adev->dev)); 151 else 152 dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n", 153 &cfgres); 154 155 cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops); 156 if (IS_ERR(cfg)) { 157 dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, 158 PTR_ERR(cfg)); 159 return NULL; 160 } 161 162 return cfg; 163} 164 165/* release_info: free resources allocated by init_info */ 166static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) 167{ 168 struct acpi_pci_generic_root_info *ri; 169 170 ri = container_of(ci, struct acpi_pci_generic_root_info, common); 171 pci_ecam_free(ri->cfg); 172 kfree(ci->ops); 173 kfree(ri); 174} 175 176/* Interface called from ACPI code to setup PCI host controller */ 177struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) 178{ 179 struct acpi_pci_generic_root_info *ri; 180 struct pci_bus *bus, *child; 181 struct acpi_pci_root_ops *root_ops; 182 struct pci_host_bridge *host; 183 184 ri = kzalloc(sizeof(*ri), GFP_KERNEL); 185 if (!ri) 186 return NULL; 187 188 root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL); 189 if (!root_ops) { 190 kfree(ri); 191 return NULL; 192 } 193 194 ri->cfg = pci_acpi_setup_ecam_mapping(root); 195 if (!ri->cfg) { 196 kfree(ri); 197 kfree(root_ops); 198 return NULL; 199 } 200 201 root_ops->release_info = pci_acpi_generic_release_info; 202 root_ops->prepare_resources = pci_acpi_root_prepare_resources; 203 root_ops->pci_ops = (struct pci_ops *)&ri->cfg->ops->pci_ops; 204 bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg); 205 if (!bus) 206 return NULL; 207 208 /* If we must preserve the resource configuration, claim now */ 209 host = pci_find_host_bridge(bus); 210 if (host->preserve_config) 211 pci_bus_claim_resources(bus); 212 213 /* 214 * Assign whatever was left unassigned. If we didn't claim above, 215 * this will reassign everything. 216 */ 217 pci_assign_unassigned_root_bus_resources(bus); 218 219 list_for_each_entry(child, &bus->children, node) 220 pcie_bus_configure_settings(child); 221 222 return bus; 223} 224 225void pcibios_add_bus(struct pci_bus *bus) 226{ 227 acpi_pci_add_bus(bus); 228} 229 230void pcibios_remove_bus(struct pci_bus *bus) 231{ 232 acpi_pci_remove_bus(bus); 233} 234 235#endif