aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-07-10 10:36:09 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-07-10 10:36:09 -0400
commit6ee53f4c38e70ba34777ad38807a50c1812ff36f (patch)
tree8a4eeef5923d28c2e4ab14f4559e686cc1fce455 /drivers/pci/probe.c
parentd68e70c6e59ad08feca291c2790164d3231c425e (diff)
parent1c975931128c1128892981095a64fb8eabf240eb (diff)
Merge branch 'pci/bjorn-p2p-bridge-windows' into next
* pci/bjorn-p2p-bridge-windows: sparc/PCI: replace pci_cfg_fake_ranges() with pci_read_bridge_bases() PCI: support sizing P2P bridge I/O windows with 1K granularity PCI: reimplement P2P bridge 1K I/O windows (Intel P64H2) PCI: allow P2P bridge windows starting at PCI bus address zero Conflicts: drivers/pci/probe.c include/linux/pci.h
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5e5358a3dd92..6c143b4497ca 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -306,15 +306,23 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
306{ 306{
307 struct pci_dev *dev = child->self; 307 struct pci_dev *dev = child->self;
308 u8 io_base_lo, io_limit_lo; 308 u8 io_base_lo, io_limit_lo;
309 unsigned long base, limit; 309 unsigned long io_mask, io_granularity, base, limit;
310 struct pci_bus_region region; 310 struct pci_bus_region region;
311 struct resource *res, res2; 311 struct resource *res;
312
313 io_mask = PCI_IO_RANGE_MASK;
314 io_granularity = 0x1000;
315 if (dev->io_window_1k) {
316 /* Support 1K I/O space granularity */
317 io_mask = PCI_IO_1K_RANGE_MASK;
318 io_granularity = 0x400;
319 }
312 320
313 res = child->resource[0]; 321 res = child->resource[0];
314 pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); 322 pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
315 pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); 323 pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
316 base = (io_base_lo & PCI_IO_RANGE_MASK) << 8; 324 base = (io_base_lo & io_mask) << 8;
317 limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8; 325 limit = (io_limit_lo & io_mask) << 8;
318 326
319 if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { 327 if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
320 u16 io_base_hi, io_limit_hi; 328 u16 io_base_hi, io_limit_hi;
@@ -325,16 +333,11 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
325 limit |= ((unsigned long) io_limit_hi << 16); 333 limit |= ((unsigned long) io_limit_hi << 16);
326 } 334 }
327 335
328 if (base && base <= limit) { 336 if (base <= limit) {
329 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; 337 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
330 res2.flags = res->flags;
331 region.start = base; 338 region.start = base;
332 region.end = limit + 0xfff; 339 region.end = limit + io_granularity - 1;
333 pcibios_bus_to_resource(dev, &res2, &region); 340 pcibios_bus_to_resource(dev, res, &region);
334 if (!res->start)
335 res->start = res2.start;
336 if (!res->end)
337 res->end = res2.end;
338 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 341 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
339 } 342 }
340} 343}
@@ -352,7 +355,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
352 pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); 355 pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
353 base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; 356 base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
354 limit = ((unsigned long) mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; 357 limit = ((unsigned long) mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
355 if (base && base <= limit) { 358 if (base <= limit) {
356 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; 359 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
357 region.start = base; 360 region.start = base;
358 region.end = limit + 0xfffff; 361 region.end = limit + 0xfffff;
@@ -399,7 +402,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
399#endif 402#endif
400 } 403 }
401 } 404 }
402 if (base && base <= limit) { 405 if (base <= limit) {
403 res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | 406 res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
404 IORESOURCE_MEM | IORESOURCE_PREFETCH; 407 IORESOURCE_MEM | IORESOURCE_PREFETCH;
405 if (res->flags & PCI_PREF_RANGE_TYPE_64) 408 if (res->flags & PCI_PREF_RANGE_TYPE_64)