From 1fa051018d85b829e4b9a7ed20147df8760293ee Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 21 Jun 2016 10:54:29 -0500 Subject: ARM: Make PCI I/O space optional For callers of pci_common_init_dev(), we previously always required a PCI I/O port resource. If the caller's ->setup() function had added an I/O resource, we used that; otherwise, we added a default 64K I/O port space for it. There are PCI host bridges that do not support I/O port space, and we should not add fictitious spaces for them. If a caller sets struct hw_pci.io_optional, assume it is responsible for adding any I/O port resource it desires, and do not add any default I/O port space. Tested-by: Geert Uytterhoeven Signed-off-by: Bjorn Helgaas --- arch/arm/kernel/bios32.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 05e61a2eeabe..65f12ef6aa62 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -410,7 +410,8 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq; } -static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) +static int pcibios_init_resource(int busnr, struct pci_sys_data *sys, + int io_optional) { int ret; struct resource_entry *window; @@ -420,6 +421,14 @@ static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) &iomem_resource, sys->mem_offset); } + /* + * If a platform says I/O port support is optional, we don't add + * the default I/O space. The platform is responsible for adding + * any I/O space it needs. + */ + if (io_optional) + return 0; + resource_list_for_each_entry(window, &sys->resources) if (resource_type(window->res) == IORESOURCE_IO) return 0; @@ -466,7 +475,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, if (ret > 0) { struct pci_host_bridge *host_bridge; - ret = pcibios_init_resources(nr, sys); + ret = pcibios_init_resource(nr, sys, hw->io_optional); if (ret) { kfree(sys); break; -- cgit v1.2.3 From b30742aa307ac9d7db846c0823685e064dc66aaf Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Thu, 23 Jun 2016 11:36:22 +0100 Subject: ARM/PCI: Claim bus resources on PCI_PROBE_ONLY set-ups We claim PCI BAR and bridge window resources in pci_bus_assign_resources(), but when PCI_PROBE_ONLY is set, we treat those resources as immutable and don't call pci_bus_assign_resources(), so the resources aren't put in the resource tree. When the resources aren't in the tree, they don't show up in /proc/iomem, we can't detect conflicts, and we need special cases elsewhere for PCI_PROBE_ONLY or resources without a parent pointer. Claim all PCI BAR and window resources in the PCI_PROBE_ONLY case. If a PCI_PROBE_ONLY platform assigns conflicting resources, Linux can't fix the conflicts. Previously we didn't notice the conflicts, but now we will, which may expose new failures. [bhelgaas: changelog, add resource comment, remove size/assign comments] Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas CC: Russell King --- arch/arm/kernel/bios32.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 05e61a2eeabe..ad4710e9da3e 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -515,25 +515,23 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) list_for_each_entry(sys, &head, node) { struct pci_bus *bus = sys->bus; - if (!pci_has_flag(PCI_PROBE_ONLY)) { + /* + * We insert PCI resources into the iomem_resource and + * ioport_resource trees in either pci_bus_claim_resources() + * or pci_bus_assign_resources(). + */ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { struct pci_bus *child; - /* - * Size the bridge windows. - */ pci_bus_size_bridges(bus); - - /* - * Assign resources. - */ pci_bus_assign_resources(bus); list_for_each_entry(child, &bus->children, node) pcie_bus_configure_settings(child); } - /* - * Tell drivers about devices found. - */ + pci_bus_add_devices(bus); } } -- cgit v1.2.3 From 313cb90285d8715302d79069700d78770ee91e9a Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 8 Jun 2016 12:04:50 +0100 Subject: ARM/PCI: Remove arch-specific pcibios_enable_device() On systems with PCI_PROBE_ONLY set, we rely on BAR assignments from firmware. Previously we did not insert those resources into the resource tree, so we had to skip pci_enable_resources() because it fails if resources are not in the resource tree. Now that we *do* insert resources even when PCI_PROBE_ONLY is set, we no longer need the ARM-specific pcibios_enable_device(). Remove it so we use the generic version. [bhelgaas: changelog] Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Acked-by: Will Deacon CC: Arnd Bergmann CC: Russell King --- arch/arm/kernel/bios32.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index ad4710e9da3e..af8e4668fbf9 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -588,18 +588,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, return start; } -/** - * pcibios_enable_device - Enable I/O and memory. - * @dev: PCI device to be enabled - */ -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - if (pci_has_flag(PCI_PROBE_ONLY)) - return 0; - - return pci_enable_resources(dev, mask); -} - int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { -- cgit v1.2.3