--- /dev/null
+From 43f5c77bcbd27cce70bf33c2b86d6726ce95dd66 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Thu, 22 Jul 2021 16:40:41 +0200
+Subject: PCI: aardvark: Fix reporting CRS value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+commit 43f5c77bcbd27cce70bf33c2b86d6726ce95dd66 upstream.
+
+Set CRSVIS flag in emulated root PCI bridge to indicate support for
+Completion Retry Status.
+
+Add check for CRSSVE flag from root PCI brige when issuing Configuration
+Read Request via PIO to correctly returns fabricated CRS value as it is
+required by PCIe spec.
+
+Link: https://lore.kernel.org/r/20210722144041.12661-5-pali@kernel.org
+Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: stable@vger.kernel.org # e0d9d30b7354 ("PCI: pci-bridge-emul: Fix big-endian support")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pci-aardvark.c | 67 +++++++++++++++++++++++++++++++---
+ 1 file changed, 63 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -188,6 +188,8 @@
+
+ #define MSI_IRQ_NUM 32
+
++#define CFG_RD_CRS_VAL 0xffff0001
++
+ struct advk_pcie {
+ struct platform_device *pdev;
+ void __iomem *base;
+@@ -365,7 +367,7 @@ static void advk_pcie_setup_hw(struct ad
+ advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);
+ }
+
+-static int advk_pcie_check_pio_status(struct advk_pcie *pcie, u32 *val)
++static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u32 *val)
+ {
+ struct device *dev = &pcie->pdev->dev;
+ u32 reg;
+@@ -407,9 +409,30 @@ static int advk_pcie_check_pio_status(st
+ strcomp_status = "UR";
+ break;
+ case PIO_COMPLETION_STATUS_CRS:
++ if (allow_crs && val) {
++ /* PCIe r4.0, sec 2.3.2, says:
++ * If CRS Software Visibility is enabled:
++ * For a Configuration Read Request that includes both
++ * bytes of the Vendor ID field of a device Function's
++ * Configuration Space Header, the Root Complex must
++ * complete the Request to the host by returning a
++ * read-data value of 0001h for the Vendor ID field and
++ * all '1's for any additional bytes included in the
++ * request.
++ *
++ * So CRS in this case is not an error status.
++ */
++ *val = CFG_RD_CRS_VAL;
++ strcomp_status = NULL;
++ break;
++ }
+ /* PCIe r4.0, sec 2.3.2, says:
+ * If CRS Software Visibility is not enabled, the Root Complex
+ * must re-issue the Configuration Request as a new Request.
++ * If CRS Software Visibility is enabled: For a Configuration
++ * Write Request or for any other Configuration Read Request,
++ * the Root Complex must re-issue the Configuration Request as
++ * a new Request.
+ * A Root Complex implementation may choose to limit the number
+ * of Configuration Request/CRS Completion Status loops before
+ * determining that something is wrong with the target of the
+@@ -478,6 +501,7 @@ advk_pci_bridge_emul_pcie_conf_read(stru
+ case PCI_EXP_RTCTL: {
+ u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+ *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE;
++ *value |= PCI_EXP_RTCAP_CRSVIS << 16;
+ return PCI_BRIDGE_EMUL_HANDLED;
+ }
+
+@@ -559,6 +583,7 @@ static struct pci_bridge_emul_ops advk_p
+ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
+ {
+ struct pci_bridge_emul *bridge = &pcie->bridge;
++ int ret;
+
+ bridge->conf.vendor = advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff;
+ bridge->conf.device = advk_readl(pcie, PCIE_CORE_DEV_ID_REG) >> 16;
+@@ -580,7 +605,15 @@ static int advk_sw_pci_bridge_init(struc
+ bridge->data = pcie;
+ bridge->ops = &advk_pci_bridge_emul_ops;
+
+- return pci_bridge_emul_init(bridge, 0);
++ /* PCIe config space can be initialized after pci_bridge_emul_init() */
++ ret = pci_bridge_emul_init(bridge, 0);
++ if (ret < 0)
++ return ret;
++
++ /* Indicates supports for Completion Retry Status */
++ bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS);
++
++ return 0;
+ }
+
+ static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus,
+@@ -625,6 +658,7 @@ static int advk_pcie_rd_conf(struct pci_
+ int where, int size, u32 *val)
+ {
+ struct advk_pcie *pcie = bus->sysdata;
++ bool allow_crs;
+ u32 reg;
+ int ret;
+
+@@ -637,7 +671,24 @@ static int advk_pcie_rd_conf(struct pci_
+ return pci_bridge_emul_conf_read(&pcie->bridge, where,
+ size, val);
+
++ /*
++ * Completion Retry Status is possible to return only when reading all
++ * 4 bytes from PCI_VENDOR_ID and PCI_DEVICE_ID registers at once and
++ * CRSSVE flag on Root Bridge is enabled.
++ */
++ allow_crs = (where == PCI_VENDOR_ID) && (size == 4) &&
++ (le16_to_cpu(pcie->bridge.pcie_conf.rootctl) &
++ PCI_EXP_RTCTL_CRSSVE);
++
+ if (advk_pcie_pio_is_running(pcie)) {
++ /*
++ * If it is possible return Completion Retry Status so caller
++ * tries to issue the request again instead of failing.
++ */
++ if (allow_crs) {
++ *val = CFG_RD_CRS_VAL;
++ return PCIBIOS_SUCCESSFUL;
++ }
+ *val = 0xffffffff;
+ return PCIBIOS_SET_FAILED;
+ }
+@@ -665,12 +716,20 @@ static int advk_pcie_rd_conf(struct pci_
+
+ ret = advk_pcie_wait_pio(pcie);
+ if (ret < 0) {
++ /*
++ * If it is possible return Completion Retry Status so caller
++ * tries to issue the request again instead of failing.
++ */
++ if (allow_crs) {
++ *val = CFG_RD_CRS_VAL;
++ return PCIBIOS_SUCCESSFUL;
++ }
+ *val = 0xffffffff;
+ return PCIBIOS_SET_FAILED;
+ }
+
+ /* Check PIO status and get the read result */
+- ret = advk_pcie_check_pio_status(pcie, val);
++ ret = advk_pcie_check_pio_status(pcie, allow_crs, val);
+ if (ret < 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_SET_FAILED;
+@@ -739,7 +798,7 @@ static int advk_pcie_wr_conf(struct pci_
+ if (ret < 0)
+ return PCIBIOS_SET_FAILED;
+
+- ret = advk_pcie_check_pio_status(pcie, NULL);
++ ret = advk_pcie_check_pio_status(pcie, false, NULL);
+ if (ret < 0)
+ return PCIBIOS_SET_FAILED;
+
--- /dev/null
+From b1bd5714472cc72e14409f5659b154c765a76c65 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Mon, 1 Jun 2020 15:03:15 +0200
+Subject: PCI: aardvark: Indicate error in 'val' when config read fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+commit b1bd5714472cc72e14409f5659b154c765a76c65 upstream.
+
+Most callers of config read do not check for return value. But most of the
+ones that do, checks for error indication in 'val' variable.
+
+This patch updates error handling in advk_pcie_rd_conf() function. If PIO
+transfer fails then 'val' variable is set to 0xffffffff which indicates
+failture.
+
+Link: https://lore.kernel.org/r/20200528162604.GA323482@bjorn-Precision-5520
+Link: https://lore.kernel.org/r/20200601130315.18895-1-pali@kernel.org
+Reported-by: Bjorn Helgaas <helgaas@kernel.org>
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pci-aardvark.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -664,8 +664,10 @@ static int advk_pcie_rd_conf(struct pci_
+ advk_writel(pcie, 1, PIO_START);
+
+ ret = advk_pcie_wait_pio(pcie);
+- if (ret < 0)
++ if (ret < 0) {
++ *val = 0xffffffff;
+ return PCIBIOS_SET_FAILED;
++ }
+
+ /* Check PIO status and get the read result */
+ ret = advk_pcie_check_pio_status(pcie, val);
--- /dev/null
+From e902bb7c24a7099d0eb0eb4cba06f2d91e9299f3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Thu, 22 Jul 2021 16:40:40 +0200
+Subject: PCI: pci-bridge-emul: Add PCIe Root Capabilities Register
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+commit e902bb7c24a7099d0eb0eb4cba06f2d91e9299f3 upstream.
+
+The 16-bit Root Capabilities register is at offset 0x1e in the PCIe
+Capability. Rename current 'rsvd' struct member to 'rootcap'.
+
+Link: https://lore.kernel.org/r/20210722144041.12661-4-pali@kernel.org
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/pci-bridge-emul.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/pci-bridge-emul.h
++++ b/drivers/pci/pci-bridge-emul.h
+@@ -54,7 +54,7 @@ struct pci_bridge_emul_pcie_conf {
+ __le16 slotctl;
+ __le16 slotsta;
+ __le16 rootctl;
+- __le16 rsvd;
++ __le16 rootcap;
+ __le32 rootsta;
+ __le32 devcap2;
+ __le16 devctl2;
--- /dev/null
+From e0d9d30b73548fbfe5c024ed630169bdc9a08aee Mon Sep 17 00:00:00 2001
+From: Grzegorz Jaszczyk <jaz@semihalf.com>
+Date: Tue, 16 Jul 2019 14:13:46 +0200
+Subject: PCI: pci-bridge-emul: Fix big-endian support
+
+From: Grzegorz Jaszczyk <jaz@semihalf.com>
+
+commit e0d9d30b73548fbfe5c024ed630169bdc9a08aee upstream.
+
+Perform conversion to little-endian before every write to configuration
+space and convert it back to CPU endianness on reads.
+
+Additionally, initialise every multiple byte field of config space with
+the cpu_to_le* macro, which is required since the structure describing
+config space of emulated bridge assumes little-endian convention.
+
+Signed-off-by: Grzegorz Jaszczyk <jaz@semihalf.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/pci-bridge-emul.c | 25 +++++++------
+ drivers/pci/pci-bridge-emul.h | 78 +++++++++++++++++++++---------------------
+ 2 files changed, 52 insertions(+), 51 deletions(-)
+
+--- a/drivers/pci/pci-bridge-emul.c
++++ b/drivers/pci/pci-bridge-emul.c
+@@ -270,10 +270,10 @@ static const struct pci_bridge_reg_behav
+ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
+ unsigned int flags)
+ {
+- bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16;
++ bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16);
+ bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
+ bridge->conf.cache_line_size = 0x10;
+- bridge->conf.status = PCI_STATUS_CAP_LIST;
++ bridge->conf.status = cpu_to_le16(PCI_STATUS_CAP_LIST);
+ bridge->pci_regs_behavior = kmemdup(pci_regs_behavior,
+ sizeof(pci_regs_behavior),
+ GFP_KERNEL);
+@@ -284,8 +284,9 @@ int pci_bridge_emul_init(struct pci_brid
+ bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
+ bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
+ /* Set PCIe v2, root port, slot support */
+- bridge->pcie_conf.cap = PCI_EXP_TYPE_ROOT_PORT << 4 | 2 |
+- PCI_EXP_FLAGS_SLOT;
++ bridge->pcie_conf.cap =
++ cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4 | 2 |
++ PCI_EXP_FLAGS_SLOT);
+ bridge->pcie_cap_regs_behavior =
+ kmemdup(pcie_cap_regs_behavior,
+ sizeof(pcie_cap_regs_behavior),
+@@ -327,7 +328,7 @@ int pci_bridge_emul_conf_read(struct pci
+ int reg = where & ~3;
+ pci_bridge_emul_read_status_t (*read_op)(struct pci_bridge_emul *bridge,
+ int reg, u32 *value);
+- u32 *cfgspace;
++ __le32 *cfgspace;
+ const struct pci_bridge_reg_behavior *behavior;
+
+ if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END) {
+@@ -343,11 +344,11 @@ int pci_bridge_emul_conf_read(struct pci
+ if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) {
+ reg -= PCI_CAP_PCIE_START;
+ read_op = bridge->ops->read_pcie;
+- cfgspace = (u32 *) &bridge->pcie_conf;
++ cfgspace = (__le32 *) &bridge->pcie_conf;
+ behavior = bridge->pcie_cap_regs_behavior;
+ } else {
+ read_op = bridge->ops->read_base;
+- cfgspace = (u32 *) &bridge->conf;
++ cfgspace = (__le32 *) &bridge->conf;
+ behavior = bridge->pci_regs_behavior;
+ }
+
+@@ -357,7 +358,7 @@ int pci_bridge_emul_conf_read(struct pci
+ ret = PCI_BRIDGE_EMUL_NOT_HANDLED;
+
+ if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED)
+- *value = cfgspace[reg / 4];
++ *value = le32_to_cpu(cfgspace[reg / 4]);
+
+ /*
+ * Make sure we never return any reserved bit with a value
+@@ -387,7 +388,7 @@ int pci_bridge_emul_conf_write(struct pc
+ int mask, ret, old, new, shift;
+ void (*write_op)(struct pci_bridge_emul *bridge, int reg,
+ u32 old, u32 new, u32 mask);
+- u32 *cfgspace;
++ __le32 *cfgspace;
+ const struct pci_bridge_reg_behavior *behavior;
+
+ if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END)
+@@ -414,11 +415,11 @@ int pci_bridge_emul_conf_write(struct pc
+ if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) {
+ reg -= PCI_CAP_PCIE_START;
+ write_op = bridge->ops->write_pcie;
+- cfgspace = (u32 *) &bridge->pcie_conf;
++ cfgspace = (__le32 *) &bridge->pcie_conf;
+ behavior = bridge->pcie_cap_regs_behavior;
+ } else {
+ write_op = bridge->ops->write_base;
+- cfgspace = (u32 *) &bridge->conf;
++ cfgspace = (__le32 *) &bridge->conf;
+ behavior = bridge->pci_regs_behavior;
+ }
+
+@@ -431,7 +432,7 @@ int pci_bridge_emul_conf_write(struct pc
+ /* Clear the W1C bits */
+ new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
+
+- cfgspace[reg / 4] = new;
++ cfgspace[reg / 4] = cpu_to_le32(new);
+
+ if (write_op)
+ write_op(bridge, reg, old, new, mask);
+--- a/drivers/pci/pci-bridge-emul.h
++++ b/drivers/pci/pci-bridge-emul.h
+@@ -6,65 +6,65 @@
+
+ /* PCI configuration space of a PCI-to-PCI bridge. */
+ struct pci_bridge_emul_conf {
+- u16 vendor;
+- u16 device;
+- u16 command;
+- u16 status;
+- u32 class_revision;
++ __le16 vendor;
++ __le16 device;
++ __le16 command;
++ __le16 status;
++ __le32 class_revision;
+ u8 cache_line_size;
+ u8 latency_timer;
+ u8 header_type;
+ u8 bist;
+- u32 bar[2];
++ __le32 bar[2];
+ u8 primary_bus;
+ u8 secondary_bus;
+ u8 subordinate_bus;
+ u8 secondary_latency_timer;
+ u8 iobase;
+ u8 iolimit;
+- u16 secondary_status;
+- u16 membase;
+- u16 memlimit;
+- u16 pref_mem_base;
+- u16 pref_mem_limit;
+- u32 prefbaseupper;
+- u32 preflimitupper;
+- u16 iobaseupper;
+- u16 iolimitupper;
++ __le16 secondary_status;
++ __le16 membase;
++ __le16 memlimit;
++ __le16 pref_mem_base;
++ __le16 pref_mem_limit;
++ __le32 prefbaseupper;
++ __le32 preflimitupper;
++ __le16 iobaseupper;
++ __le16 iolimitupper;
+ u8 capabilities_pointer;
+ u8 reserve[3];
+- u32 romaddr;
++ __le32 romaddr;
+ u8 intline;
+ u8 intpin;
+- u16 bridgectrl;
++ __le16 bridgectrl;
+ };
+
+ /* PCI configuration space of the PCIe capabilities */
+ struct pci_bridge_emul_pcie_conf {
+ u8 cap_id;
+ u8 next;
+- u16 cap;
+- u32 devcap;
+- u16 devctl;
+- u16 devsta;
+- u32 lnkcap;
+- u16 lnkctl;
+- u16 lnksta;
+- u32 slotcap;
+- u16 slotctl;
+- u16 slotsta;
+- u16 rootctl;
+- u16 rsvd;
+- u32 rootsta;
+- u32 devcap2;
+- u16 devctl2;
+- u16 devsta2;
+- u32 lnkcap2;
+- u16 lnkctl2;
+- u16 lnksta2;
+- u32 slotcap2;
+- u16 slotctl2;
+- u16 slotsta2;
++ __le16 cap;
++ __le32 devcap;
++ __le16 devctl;
++ __le16 devsta;
++ __le32 lnkcap;
++ __le16 lnkctl;
++ __le16 lnksta;
++ __le32 slotcap;
++ __le16 slotctl;
++ __le16 slotsta;
++ __le16 rootctl;
++ __le16 rsvd;
++ __le32 rootsta;
++ __le32 devcap2;
++ __le16 devctl2;
++ __le16 devsta2;
++ __le32 lnkcap2;
++ __le16 lnkctl2;
++ __le16 lnksta2;
++ __le32 slotcap2;
++ __le16 slotctl2;
++ __le16 slotsta2;
+ };
+
+ struct pci_bridge_emul;
+pci-pci-bridge-emul-fix-big-endian-support.patch
+pci-aardvark-indicate-error-in-val-when-config-read-fails.patch
+pci-pci-bridge-emul-add-pcie-root-capabilities-register.patch
+pci-aardvark-fix-reporting-crs-value.patch