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