1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * New-style PCI core. 4 * 5 * Copyright (c) 2004 - 2009 Paul Mundt 6 * Copyright (c) 2002 M. R. Brown 7 * 8 * Modelled after arch/mips/pci/pci.c: 9 * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org) 10 */ 11 #include <linux/kernel.h> 12 #include <linux/mm.h> 13 #include <linux/pci.h> 14 #include <linux/init.h> 15 #include <linux/types.h> 16 #include <linux/io.h> 17 #include <linux/mutex.h> 18 #include <linux/spinlock.h> 19 #include <linux/export.h> 20 21 unsigned long PCIBIOS_MIN_IO = 0x0000; 22 unsigned long PCIBIOS_MIN_MEM = 0; 23 24 /* 25 * The PCI controller list. 26 */ 27 static struct pci_channel *hose_head, **hose_tail = &hose_head; 28 29 static int pci_initialized; 30 31 static void pcibios_scanbus(struct pci_channel *hose) 32 { 33 static int next_busno; 34 static int need_domain_info; 35 LIST_HEAD(resources); 36 struct resource *res; 37 resource_size_t offset; 38 int i, ret; 39 struct pci_host_bridge *bridge; 40 41 bridge = pci_alloc_host_bridge(0); 42 if (!bridge) 43 return; 44 45 for (i = 0; i < hose->nr_resources; i++) { 46 res = hose->resources + i; 47 offset = 0; 48 if (res->flags & IORESOURCE_DISABLED) 49 continue; 50 if (res->flags & IORESOURCE_IO) 51 offset = hose->io_offset; 52 else if (res->flags & IORESOURCE_MEM) 53 offset = hose->mem_offset; 54 pci_add_resource_offset(&resources, res, offset); 55 } 56 57 list_splice_init(&resources, &bridge->windows); 58 bridge->dev.parent = NULL; 59 bridge->sysdata = hose; 60 bridge->busnr = next_busno; 61 bridge->ops = hose->pci_ops; 62 bridge->swizzle_irq = pci_common_swizzle; 63 bridge->map_irq = pcibios_map_platform_irq; 64 65 ret = pci_scan_root_bus_bridge(bridge); 66 if (ret) { 67 pci_free_host_bridge(bridge); 68 return; 69 } 70 71 hose->bus = bridge->bus; 72 73 need_domain_info = need_domain_info || hose->index; 74 hose->need_domain_info = need_domain_info; 75 76 next_busno = hose->bus->busn_res.end + 1; 77 /* Don't allow 8-bit bus number overflow inside the hose - 78 reserve some space for bridges. */ 79 if (next_busno > 224) { 80 next_busno = 0; 81 need_domain_info = 1; 82 } 83 84 pci_bus_size_bridges(hose->bus); 85 pci_bus_assign_resources(hose->bus); 86 pci_bus_add_devices(hose->bus); 87 } 88 89 /* 90 * This interrupt-safe spinlock protects all accesses to PCI 91 * configuration space. 92 */ 93 DEFINE_RAW_SPINLOCK(pci_config_lock); 94 static DEFINE_MUTEX(pci_scan_mutex); 95 96 int register_pci_controller(struct pci_channel *hose) 97 { 98 int i; 99 100 for (i = 0; i < hose->nr_resources; i++) { 101 struct resource *res = hose->resources + i; 102 103 if (res->flags & IORESOURCE_DISABLED) 104 continue; 105 106 if (res->flags & IORESOURCE_IO) { 107 if (request_resource(&ioport_resource, res) < 0) 108 goto out; 109 } else { 110 if (request_resource(&iomem_resource, res) < 0) 111 goto out; 112 } 113 } 114 115 *hose_tail = hose; 116 hose_tail = &hose->next; 117 118 /* 119 * Do not panic here but later - this might happen before console init. 120 */ 121 if (!hose->io_map_base) { 122 pr_warn("registering PCI controller with io_map_base unset\n"); 123 } 124 125 /* 126 * Setup the ERR/PERR and SERR timers, if available. 127 */ 128 pcibios_enable_timers(hose); 129 130 /* 131 * Scan the bus if it is register after the PCI subsystem 132 * initialization. 133 */ 134 if (pci_initialized) { 135 mutex_lock(&pci_scan_mutex); 136 pcibios_scanbus(hose); 137 mutex_unlock(&pci_scan_mutex); 138 } 139 140 return 0; 141 142 out: 143 for (--i; i >= 0; i--) 144 release_resource(&hose->resources[i]); 145 146 pr_warn("Skipping PCI bus scan due to resource conflict\n"); 147 return -1; 148 } 149 150 static int __init pcibios_init(void) 151 { 152 struct pci_channel *hose; 153 154 /* Scan all of the recorded PCI controllers. */ 155 for (hose = hose_head; hose; hose = hose->next) 156 pcibios_scanbus(hose); 157 158 pci_initialized = 1; 159 160 return 0; 161 } 162 subsys_initcall(pcibios_init); 163 164 /* 165 * We need to avoid collisions with `mirrored' VGA ports 166 * and other strange ISA hardware, so we always want the 167 * addresses to be allocated in the 0x000-0x0ff region 168 * modulo 0x400. 169 */ 170 resource_size_t pcibios_align_resource(void *data, const struct resource *res, 171 const struct resource *empty_res, 172 resource_size_t size, 173 resource_size_t align) 174 { 175 struct pci_dev *dev = data; 176 struct pci_channel *hose = dev->sysdata; 177 resource_size_t start = res->start; 178 179 if (res->flags & IORESOURCE_IO) { 180 if (start < PCIBIOS_MIN_IO + hose->resources[0].start) 181 start = PCIBIOS_MIN_IO + hose->resources[0].start; 182 183 /* 184 * Put everything into 0x00-0xff region modulo 0x400. 185 */ 186 if (start & 0x300) 187 start = (start + 0x3ff) & ~0x3ff; 188 } else if (res->flags & IORESOURCE_MEM) { 189 start = pci_align_resource(dev, res, empty_res, size, align); 190 } 191 192 return start; 193 } 194 195 static void __init 196 pcibios_bus_report_status_early(struct pci_channel *hose, 197 int top_bus, int current_bus, 198 unsigned int status_mask, int warn) 199 { 200 unsigned int pci_devfn; 201 u16 status; 202 int ret; 203 204 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { 205 if (PCI_FUNC(pci_devfn)) 206 continue; 207 ret = early_read_config_word(hose, top_bus, current_bus, 208 pci_devfn, PCI_STATUS, &status); 209 if (ret != PCIBIOS_SUCCESSFUL) 210 continue; 211 if (status == 0xffff) 212 continue; 213 214 early_write_config_word(hose, top_bus, current_bus, 215 pci_devfn, PCI_STATUS, 216 status & status_mask); 217 if (warn) 218 pr_cont("(%02x:%02x: %04X) ", current_bus, pci_devfn, 219 status); 220 } 221 } 222 223 /* 224 * We can't use pci_find_device() here since we are 225 * called from interrupt context. 226 */ 227 static void __ref 228 pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask, 229 int warn) 230 { 231 struct pci_dev *dev; 232 233 list_for_each_entry(dev, &bus->devices, bus_list) { 234 u16 status; 235 236 /* 237 * ignore host bridge - we handle 238 * that separately 239 */ 240 if (dev->bus->number == 0 && dev->devfn == 0) 241 continue; 242 243 pci_read_config_word(dev, PCI_STATUS, &status); 244 if (status == 0xffff) 245 continue; 246 247 if ((status & status_mask) == 0) 248 continue; 249 250 /* clear the status errors */ 251 pci_write_config_word(dev, PCI_STATUS, status & status_mask); 252 253 if (warn) 254 pr_cont("(%s: %04X) ", pci_name(dev), status); 255 } 256 257 list_for_each_entry(dev, &bus->devices, bus_list) 258 if (dev->subordinate) 259 pcibios_bus_report_status(dev->subordinate, status_mask, warn); 260 } 261 262 void __ref pcibios_report_status(unsigned int status_mask, int warn) 263 { 264 struct pci_channel *hose; 265 266 for (hose = hose_head; hose; hose = hose->next) { 267 if (unlikely(!hose->bus)) 268 pcibios_bus_report_status_early(hose, hose_head->index, 269 hose->index, status_mask, warn); 270 else 271 pcibios_bus_report_status(hose->bus, status_mask, warn); 272 } 273 } 274 275 #ifndef CONFIG_GENERIC_IOMAP 276 277 void __iomem *__pci_ioport_map(struct pci_dev *dev, 278 unsigned long port, unsigned int nr) 279 { 280 struct pci_channel *chan = dev->sysdata; 281 282 if (unlikely(!chan->io_map_base)) { 283 chan->io_map_base = sh_io_port_base; 284 285 if (pci_domains_supported) 286 panic("To avoid data corruption io_map_base MUST be " 287 "set with multiple PCI domains."); 288 } 289 290 return (void __iomem *)(chan->io_map_base + port); 291 } 292 293 void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 294 { 295 iounmap(addr); 296 } 297 EXPORT_SYMBOL(pci_iounmap); 298 299 #endif /* CONFIG_GENERIC_IOMAP */ 300 301 EXPORT_SYMBOL(PCIBIOS_MIN_IO); 302 EXPORT_SYMBOL(PCIBIOS_MIN_MEM); 303