PCI: pci-bridge-emul: Add support for new flag PCI_BRIDGE_EMUL_NO_IO_FORWARD
authorPali Rohár <pali@kernel.org>
Tue, 4 Jan 2022 15:35:22 +0000 (16:35 +0100)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Thu, 3 Feb 2022 10:52:22 +0000 (10:52 +0000)
Like PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD, this new flag specifies that
emulated PCI bridge does not support forwarding of IO requests in given
range between primary and secondary buses. This flag should be used as
argument for pci_bridge_emul_init() for hardware setup without IO support.

Setting this flag cause that IO base and limit registers are read-only.

Link: https://lore.kernel.org/r/20220104153529.31647-5-pali@kernel.org
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Rob Herring <robh@kernel.org>
drivers/pci/pci-bridge-emul.c
drivers/pci/pci-bridge-emul.h

index ceacba0..a16f9e3 100644 (file)
@@ -382,6 +382,15 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
                bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0;
        }
 
+       if (flags & PCI_BRIDGE_EMUL_NO_IO_FORWARD) {
+               bridge->pci_regs_behavior[PCI_COMMAND / 4].ro |= PCI_COMMAND_IO;
+               bridge->pci_regs_behavior[PCI_COMMAND / 4].rw &= ~PCI_COMMAND_IO;
+               bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro |= GENMASK(15, 0);
+               bridge->pci_regs_behavior[PCI_IO_BASE / 4].rw &= ~GENMASK(15, 0);
+               bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].ro = ~0;
+               bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].rw = 0;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(pci_bridge_emul_init);
index 087b5fa..4953274 100644 (file)
@@ -125,6 +125,12 @@ enum {
         * requests between primary and secondary buses.
         */
        PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD = BIT(0),
+
+       /*
+        * PCI bridge does not support forwarding of IO requests between
+        * primary and secondary buses.
+        */
+       PCI_BRIDGE_EMUL_NO_IO_FORWARD = BIT(1),
 };
 
 int pci_bridge_emul_init(struct pci_bridge_emul *bridge,