[PATCH 1/3] ARM: pci: make bus I/O resources optional

Russell King rmk+kernel at armlinux.org.uk
Fri Mar 26 12:18:08 GMT 2021


Adding a bus I/O resource that extends from pcibios_min_io to the top
of PCI space breaks Footbridge based platforms, which may have ISA
southbridges and IDE controllers that are in legacy mode.

The PCI I/O space on these machines really does cover port addresses
from zero upwards, even when pcibios_min_io is non-zero.

Fix this by making Rob's changes optional - Rob's change is probably
based on a misunderstanding of what pcibios_min_io is - it is the
minimum IO port address that we wish to start allocating bus resources
which may not be the same as the minimum IO port address for the bus.

Fixes: 3c5d1699887b ("ARM: move PCI i/o resource setup into common code")
Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
---
 arch/arm/include/asm/mach/pci.h |  1 +
 arch/arm/kernel/bios32.c        | 37 ++++++++++++++++++++-------------
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 83d340702680..0f96c2462ee5 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -21,6 +21,7 @@ struct hw_pci {
 	struct pci_ops	*ops;
 	int		nr_controllers;
 	unsigned int	io_optional:1;
+	unsigned int	no_bus_ioport_resource:1;
 	void		**private_data;
 	int		(*setup)(int nr, struct pci_sys_data *);
 	int		(*scan)(int nr, struct pci_host_bridge *);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index ed46ca69813d..c48476193687 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -412,10 +412,11 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 }
 
 static int pcibios_init_resource(int busnr, struct pci_sys_data *sys,
-				 int io_optional)
+				 int io_optional, int bus_ioport_resource)
 {
-	int ret;
 	struct resource_entry *window;
+	struct resource *res;
+	int ret;
 
 	if (list_empty(&sys->resources)) {
 		pci_add_resource_offset(&sys->resources,
@@ -434,19 +435,25 @@ static int pcibios_init_resource(int busnr, struct pci_sys_data *sys,
 		if (resource_type(window->res) == IORESOURCE_IO)
 			return 0;
 
-	sys->io_res.start = (busnr * SZ_64K) ?  : pcibios_min_io;
-	sys->io_res.end = (busnr + 1) * SZ_64K - 1;
-	sys->io_res.flags = IORESOURCE_IO;
-	sys->io_res.name = sys->io_res_name;
-	sprintf(sys->io_res_name, "PCI%d I/O", busnr);
+	if (bus_ioport_resource) {
+		sys->io_res.start = (busnr * SZ_64K) ?  : pcibios_min_io;
+		sys->io_res.end = (busnr + 1) * SZ_64K - 1;
+		sys->io_res.flags = IORESOURCE_IO;
+		sys->io_res.name = sys->io_res_name;
+		sprintf(sys->io_res_name, "PCI%d I/O", busnr);
+
+		ret = request_resource(&ioport_resource, &sys->io_res);
+		if (ret) {
+			pr_err("PCI: unable to allocate I/O port region (%d)\n", ret);
+			return ret;
+		}
 
-	ret = request_resource(&ioport_resource, &sys->io_res);
-	if (ret) {
-		pr_err("PCI: unable to allocate I/O port region (%d)\n", ret);
-		return ret;
+		res = &sys->io_res;
+	} else {
+		res = &ioport_resource;
 	}
-	pci_add_resource_offset(&sys->resources, &sys->io_res,
-				sys->io_offset);
+
+	pci_add_resource_offset(&sys->resources, res, sys->io_offset);
 
 	return 0;
 }
@@ -478,8 +485,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		ret = hw->setup(nr, sys);
 
 		if (ret > 0) {
-
-			ret = pcibios_init_resource(nr, sys, hw->io_optional);
+			ret = pcibios_init_resource(nr, sys, hw->io_optional,
+						  !hw->no_bus_ioport_resource);
 			if (ret)  {
 				pci_free_host_bridge(bridge);
 				break;
-- 
2.20.1




More information about the linux-arm-kernel mailing list