[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