diff options
author | Bjorn Helgaas | 2020-04-02 14:26:43 -0500 |
---|---|---|
committer | Bjorn Helgaas | 2020-04-02 14:26:43 -0500 |
commit | 86845e37aca4c80eace290a727a49caa8390febb (patch) | |
tree | 56b644c875bd1db5a5ab4023a4efd370e4b4166c /drivers/pci | |
parent | de71a000a15fc7beb2dedc84f7ea9c25d89e368d (diff) | |
parent | 5799dac9c38a9585bc021bcb965623b835f24b1f (diff) |
Merge branch 'pci/resource'
- Use ioremap(), not phys_to_virt() for platform ROM, to fix video ROM
mapping with CONFIG_HIGHMEM (Mikel Rychliski)
- Add support for root bus sizing so we don't have to assume host bridge
windows are known a priori (Ivan Kokshaysky)
- Fix alpha Nautilus PCI setup, which has been broken since we started
enforcing window limits in resource allocation (Ivan Kokshaysky)
* pci/resource:
alpha: Fix nautilus PCI setup
PCI: Add support for root bus sizing
PCI: Use ioremap(), not phys_to_virt() for platform ROM
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/rom.c | 17 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 34 |
2 files changed, 22 insertions, 29 deletions
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 137bf0cee897..8fc9a4e911e3 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -195,20 +195,3 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) pci_disable_rom(pdev); } EXPORT_SYMBOL(pci_unmap_rom); - -/** - * pci_platform_rom - provides a pointer to any ROM image provided by the - * platform - * @pdev: pointer to pci device struct - * @size: pointer to receive size of pci window over ROM - */ -void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size) -{ - if (pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt((phys_addr_t)pdev->rom); - } - - return NULL; -} -EXPORT_SYMBOL(pci_platform_rom); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index f2461bf9243d..bbcef1a053ab 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -846,7 +846,7 @@ static resource_size_t window_alignment(struct pci_bus *bus, unsigned long type) * Per spec, I/O windows are 4K-aligned, but some bridges have * an extension to support 1K alignment. */ - if (bus->self->io_window_1k) + if (bus->self && bus->self->io_window_1k) align = PCI_P2P_DEFAULT_IO_ALIGN_1K; else align = PCI_P2P_DEFAULT_IO_ALIGN; @@ -920,7 +920,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, calculate_iosize(size, min_size, size1, add_size, children_add_size, resource_size(b_res), min_align); if (!size0 && !size1) { - if (b_res->start || b_res->end) + if (bus->self && (b_res->start || b_res->end)) pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n", b_res, &bus->busn_res); b_res->flags = 0; @@ -930,7 +930,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, b_res->start = min_align; b_res->end = b_res->start + size0 - 1; b_res->flags |= IORESOURCE_STARTALIGN; - if (size1 > size0 && realloc_head) { + if (bus->self && size1 > size0 && realloc_head) { add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); pci_info(bus->self, "bridge window %pR to %pR add_size %llx\n", @@ -1073,7 +1073,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, calculate_memsize(size, min_size, add_size, children_add_size, resource_size(b_res), add_align); if (!size0 && !size1) { - if (b_res->start || b_res->end) + if (bus->self && (b_res->start || b_res->end)) pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n", b_res, &bus->busn_res); b_res->flags = 0; @@ -1082,7 +1082,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, b_res->start = min_align; b_res->end = size0 + min_align - 1; b_res->flags |= IORESOURCE_STARTALIGN; - if (size1 > size0 && realloc_head) { + if (bus->self && size1 > size0 && realloc_head) { add_to_list(realloc_head, bus->self, b_res, size1-size0, add_align); pci_info(bus->self, "bridge window %pR to %pR add_size %llx add_align %llx\n", b_res, &bus->busn_res, @@ -1196,8 +1196,9 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) unsigned long mask, prefmask, type2 = 0, type3 = 0; resource_size_t additional_io_size = 0, additional_mmio_size = 0, additional_mmio_pref_size = 0; - struct resource *b_res; - int ret; + struct resource *pref; + struct pci_host_bridge *host; + int hdr_type, i, ret; list_for_each_entry(dev, &bus->devices, bus_list) { struct pci_bus *b = dev->subordinate; @@ -1217,10 +1218,20 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) } /* The root bus? */ - if (pci_is_root_bus(bus)) - return; + if (pci_is_root_bus(bus)) { + host = to_pci_host_bridge(bus->bridge); + if (!host->size_windows) + return; + pci_bus_for_each_resource(bus, pref, i) + if (pref && (pref->flags & IORESOURCE_PREFETCH)) + break; + hdr_type = -1; /* Intentionally invalid - not a PCI device. */ + } else { + pref = &bus->self->resource[PCI_BRIDGE_RESOURCES + 2]; + hdr_type = bus->self->hdr_type; + } - switch (bus->self->hdr_type) { + switch (hdr_type) { case PCI_HEADER_TYPE_CARDBUS: /* Don't size CardBuses yet */ break; @@ -1242,10 +1253,9 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) * the size required to put all 64-bit prefetchable * resources in it. */ - b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES]; mask = IORESOURCE_MEM; prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; - if (b_res[2].flags & IORESOURCE_MEM_64) { + if (pref && (pref->flags & IORESOURCE_MEM_64)) { prefmask |= IORESOURCE_MEM_64; ret = pbus_size_mem(bus, prefmask, prefmask, prefmask, prefmask, |