diff options
Diffstat (limited to 'pkgs/patches-linux-5.15/0019-PCI-mvebu-Set-PCI_BRIDGE_EMUL_NO_IO_FORWARD-when-IO-.patch')
-rw-r--r-- | pkgs/patches-linux-5.15/0019-PCI-mvebu-Set-PCI_BRIDGE_EMUL_NO_IO_FORWARD-when-IO-.patch | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/pkgs/patches-linux-5.15/0019-PCI-mvebu-Set-PCI_BRIDGE_EMUL_NO_IO_FORWARD-when-IO-.patch b/pkgs/patches-linux-5.15/0019-PCI-mvebu-Set-PCI_BRIDGE_EMUL_NO_IO_FORWARD-when-IO-.patch new file mode 100644 index 0000000..02e364a --- /dev/null +++ b/pkgs/patches-linux-5.15/0019-PCI-mvebu-Set-PCI_BRIDGE_EMUL_NO_IO_FORWARD-when-IO-.patch @@ -0,0 +1,114 @@ +From 1269339f0ff159e788117fb1329159b527da490f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Tue, 16 Nov 2021 17:22:03 +0100 +Subject: [PATCH 19/90] PCI: mvebu: Set PCI_BRIDGE_EMUL_NO_IO_FORWARD when IO + is unsupported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This will make PCI bridge to return zeros when accessing IO base and limit +registers, as required by PCIe base specification. + +This allows to remove adhoc checks around mvebu_pcie_handle_iobase_change() +function for unsupported IO ranges. PCI_BRIDGE_EMUL_NO_IO_FORWARD ensures +that there will be no non-zeros write to IO registers when IO is not +supported. + +Signed-off-by: Pali Rohár <pali@kernel.org> +--- + drivers/pci/controller/pci-mvebu.c | 29 ++++++++++------------------- + 1 file changed, 10 insertions(+), 19 deletions(-) + +diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c +index 016f709b3067..551f55af5226 100644 +--- a/drivers/pci/controller/pci-mvebu.c ++++ b/drivers/pci/controller/pci-mvebu.c +@@ -438,12 +438,6 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) + return mvebu_pcie_set_window(port, port->io_target, port->io_attr, + &desired, &port->iowin); + +- if (!mvebu_has_ioport(port)) { +- dev_WARN(&port->pcie->pdev->dev, +- "Attempt to set IO when IO is disabled\n"); +- return -EOPNOTSUPP; +- } +- + /* + * We read the PCI-to-PCI bridge emulated registers, and + * calculate the base address and size of the address decoding +@@ -599,24 +593,18 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, + + switch (reg) { + case PCI_COMMAND: +- if (!mvebu_has_ioport(port)) { +- conf->command = cpu_to_le16( +- le16_to_cpu(conf->command) & ~PCI_COMMAND_IO); +- new &= ~PCI_COMMAND_IO; +- } +- + mvebu_writel(port, new, PCIE_CMD_OFF); + break; + + case PCI_IO_BASE: +- if ((mask & 0xffff) && mvebu_pcie_handle_iobase_change(port)) { ++ if ((mask & 0xffff) && mvebu_has_ioport(port) && ++ mvebu_pcie_handle_iobase_change(port)) { + /* On error disable IO range */ + conf->iobase &= ~0xf0; + conf->iolimit &= ~0xf0; ++ conf->iobase |= 0xf0; + conf->iobaseupper = cpu_to_le16(0x0000); + conf->iolimitupper = cpu_to_le16(0x0000); +- if (mvebu_has_ioport(port)) +- conf->iobase |= 0xf0; + } + break; + +@@ -630,14 +618,14 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, + break; + + case PCI_IO_BASE_UPPER16: +- if (mvebu_pcie_handle_iobase_change(port)) { ++ if (mvebu_has_ioport(port) && ++ mvebu_pcie_handle_iobase_change(port)) { + /* On error disable IO range */ + conf->iobase &= ~0xf0; + conf->iolimit &= ~0xf0; ++ conf->iobase |= 0xf0; + conf->iobaseupper = cpu_to_le16(0x0000); + conf->iolimitupper = cpu_to_le16(0x0000); +- if (mvebu_has_ioport(port)) +- conf->iobase |= 0xf0; + } + break; + +@@ -722,6 +710,7 @@ static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = { + */ + static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) + { ++ unsigned int bridge_flags = PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD; + struct pci_bridge_emul *bridge = &port->bridge; + u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP); + u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS); +@@ -735,6 +724,8 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) + /* We support 32 bits I/O addressing */ + bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; + bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; ++ } else { ++ bridge_flags |= PCI_BRIDGE_EMUL_NO_IO_FORWARD; + } + + /* +@@ -747,7 +738,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) + bridge->data = port; + bridge->ops = &mvebu_pci_bridge_emul_ops; + +- return pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD); ++ return pci_bridge_emul_init(bridge, bridge_flags); + } + + static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) +-- +2.34.1 + |