From: Greg Kroah-Hartman Date: Sun, 28 Nov 2021 13:13:45 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v5.15.6~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=320937d33cd2cc6bd2a9c56d93849d957250149c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: arm64-dts-marvell-armada-37xx-declare-pcie-reset-pin.patch arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch pci-aardvark-fix-a-leaked-reference-by-adding-missing-of_node_put.patch pci-aardvark-fix-checking-for-link-up-via-ltssm-state.patch pci-aardvark-fix-compilation-on-s390.patch pci-aardvark-fix-link-training.patch pci-aardvark-fix-pcie-max-payload-size-setting.patch pci-aardvark-improve-link-training.patch pci-aardvark-indicate-error-in-val-when-config-read-fails.patch pci-aardvark-issue-perst-via-gpio.patch pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch pci-aardvark-train-link-immediately-after-enabling-training.patch pci-aardvark-update-comment-about-disabling-link-training.patch pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch pinctrl-armada-37xx-add-missing-pin-pcie1-wakeup.patch pinctrl-armada-37xx-correct-mpp-definitions.patch pinctrl-armada-37xx-correct-pwm-pins-definitions.patch proc-vmcore-fix-clearing-user-buffer-by-properly-using-clear_user.patch xtensa-use-config_use_of-instead-of-config_of.patch --- diff --git a/queue-4.19/arm64-dts-marvell-armada-37xx-declare-pcie-reset-pin.patch b/queue-4.19/arm64-dts-marvell-armada-37xx-declare-pcie-reset-pin.patch new file mode 100644 index 00000000000..be3ec786c5a --- /dev/null +++ b/queue-4.19/arm64-dts-marvell-armada-37xx-declare-pcie-reset-pin.patch @@ -0,0 +1,40 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:59 +0100 +Subject: arm64: dts: marvell: armada-37xx: declare PCIe reset pin +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Miquel Raynal" , "Gregory CLEMENT" , "Marek Behún" +Message-ID: <20211124230500.27109-20-kabel@kernel.org> + +From: Miquel Raynal + +commit a5470af981a0cc14a650af8da5186668971a4fc8 upstream. + +One pin can be muxed as PCIe endpoint card reset. + +Signed-off-by: Miquel Raynal +Signed-off-by: Gregory CLEMENT +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +@@ -254,6 +254,15 @@ + function = "mii"; + }; + ++ pcie_reset_pins: pcie-reset-pins { ++ groups = "pcie1"; ++ function = "pcie"; ++ }; ++ ++ pcie_clkreq_pins: pcie-clkreq-pins { ++ groups = "pcie1_clkreq"; ++ function = "pcie"; ++ }; + }; + + eth0: ethernet@30000 { diff --git a/queue-4.19/arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch b/queue-4.19/arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch new file mode 100644 index 00000000000..136e70946b7 --- /dev/null +++ b/queue-4.19/arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch @@ -0,0 +1,86 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:05:00 +0100 +Subject: arm64: dts: marvell: armada-37xx: Set pcie_reset_pin to gpio function +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Remi Pommarel" , "Tomasz Maciej Nowak" , "Thomas Petazzoni" , "Gregory CLEMENT" , "Marek Behún" +Message-ID: <20211124230500.27109-21-kabel@kernel.org> + +From: Marek Behún + +commit 715878016984b2617f6c1f177c50039e12e7bd5b upstream. + +We found out that we are unable to control the PERST# signal via the +default pin dedicated to be PERST# pin (GPIO2[3] pin) on A3700 SOC when +this pin is in EP_PCIE1_Resetn mode. There is a register in the PCIe +register space called PERSTN_GPIO_EN (D0088004[3]), but changing the +value of this register does not change the pin output when measuring +with voltmeter. + +We do not know if this is a bug in the SOC, or if it works only when +PCIe controller is in a certain state. + +Commit f4c7d053d7f7 ("PCI: aardvark: Wait for endpoint to be ready +before training link") says that when this pin changes pinctrl mode +from EP_PCIE1_Resetn to GPIO, the PERST# signal is asserted for a brief +moment. + +So currently the situation is that on A3700 boards the PERST# signal is +asserted in U-Boot (because the code in U-Boot issues reset via this pin +via GPIO mode), and then in Linux by the obscure and undocumented +mechanism described by the above mentioned commit. + +We want to issue PERST# signal in a known way, therefore this patch +changes the pcie_reset_pin function from "pcie" to "gpio" and adds the +reset-gpios property to the PCIe node in device tree files of +EspressoBin and Armada 3720 Dev Board (Turris Mox device tree already +has this property and uDPU does not have a PCIe port). + +Signed-off-by: Marek Behún +Cc: Remi Pommarel +Tested-by: Tomasz Maciej Nowak +Acked-by: Thomas Petazzoni +Signed-off-by: Gregory CLEMENT +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/marvell/armada-3720-db.dts | 3 +++ + arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 3 +++ + arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +- + 3 files changed, 7 insertions(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts +@@ -128,6 +128,9 @@ + + /* CON15(V2.0)/CON17(V1.4) : PCIe / CON15(V2.0)/CON12(V1.4) :mini-PCIe */ + &pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; ++ reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + +--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +@@ -55,6 +55,9 @@ + + /* J9 */ + &pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; ++ reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + +--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +@@ -256,7 +256,7 @@ + + pcie_reset_pins: pcie-reset-pins { + groups = "pcie1"; +- function = "pcie"; ++ function = "gpio"; + }; + + pcie_clkreq_pins: pcie-clkreq-pins { diff --git a/queue-4.19/pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch b/queue-4.19/pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch new file mode 100644 index 00000000000..3438e768c11 --- /dev/null +++ b/queue-4.19/pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch @@ -0,0 +1,297 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:52 +0100 +Subject: PCI: aardvark: Configure PCIe resources from 'ranges' DT property +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211124230500.27109-13-kabel@kernel.org> + +From: Pali Rohár + +commit 64f160e19e9264a7f6d89c516baae1473b6f8359 upstream. + +In commit 6df6ba974a55 ("PCI: aardvark: Remove PCIe outbound window +configuration") was removed aardvark PCIe outbound window configuration and +commit description said that was recommended solution by HW designers. + +But that commit completely removed support for configuring PCIe IO +resources without removing PCIe IO 'ranges' from DTS files. After that +commit PCIe IO space started to be treated as PCIe MEM space and accessing +it just caused kernel crash. + +Moreover implementation of PCIe outbound windows prior that commit was +incorrect. It completely ignored offset between CPU address and PCIe bus +address and expected that in DTS is CPU address always same as PCIe bus +address without doing any checks. Also it completely ignored size of every +PCIe resource specified in 'ranges' DTS property and expected that every +PCIe resource has size 128 MB (also for PCIe IO range). Again without any +check. Apparently none of PCIe resource has in DTS specified size of 128 +MB. So it was completely broken and thanks to how aardvark mask works, +configuration was completely ignored. + +This patch reverts back support for PCIe outbound window configuration but +implementation is a new without issues mentioned above. PCIe outbound +window is required when DTS specify in 'ranges' property non-zero offset +between CPU and PCIe address space. To address recommendation by HW +designers as specified in commit description of 6df6ba974a55, set default +outbound parameters as PCIe MEM access without translation and therefore +for this PCIe 'ranges' it is not needed to configure PCIe outbound window. +For PCIe IO space is needed to configure aardvark PCIe outbound window. + +This patch fixes kernel crash when trying to access PCIe IO space. + +Link: https://lore.kernel.org/r/20210624215546.4015-2-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org # 6df6ba974a55 ("PCI: aardvark: Remove PCIe outbound window configuration") +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 190 +++++++++++++++++++++++++++++++++- + 1 file changed, 189 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -106,6 +106,46 @@ + #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C) + #define PCIE_MSI_DATA_MASK GENMASK(15, 0) + ++/* PCIe window configuration */ ++#define OB_WIN_BASE_ADDR 0x4c00 ++#define OB_WIN_BLOCK_SIZE 0x20 ++#define OB_WIN_COUNT 8 ++#define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ ++ OB_WIN_BLOCK_SIZE * (win) + \ ++ (offset)) ++#define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) ++#define OB_WIN_ENABLE BIT(0) ++#define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) ++#define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) ++#define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) ++#define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) ++#define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) ++#define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) ++#define OB_WIN_DEFAULT_ACTIONS (OB_WIN_ACTIONS(OB_WIN_COUNT-1) + 0x4) ++#define OB_WIN_FUNC_NUM_MASK GENMASK(31, 24) ++#define OB_WIN_FUNC_NUM_SHIFT 24 ++#define OB_WIN_FUNC_NUM_ENABLE BIT(23) ++#define OB_WIN_BUS_NUM_BITS_MASK GENMASK(22, 20) ++#define OB_WIN_BUS_NUM_BITS_SHIFT 20 ++#define OB_WIN_MSG_CODE_ENABLE BIT(22) ++#define OB_WIN_MSG_CODE_MASK GENMASK(21, 14) ++#define OB_WIN_MSG_CODE_SHIFT 14 ++#define OB_WIN_MSG_PAYLOAD_LEN BIT(12) ++#define OB_WIN_ATTR_ENABLE BIT(11) ++#define OB_WIN_ATTR_TC_MASK GENMASK(10, 8) ++#define OB_WIN_ATTR_TC_SHIFT 8 ++#define OB_WIN_ATTR_RELAXED BIT(7) ++#define OB_WIN_ATTR_NOSNOOP BIT(6) ++#define OB_WIN_ATTR_POISON BIT(5) ++#define OB_WIN_ATTR_IDO BIT(4) ++#define OB_WIN_TYPE_MASK GENMASK(3, 0) ++#define OB_WIN_TYPE_SHIFT 0 ++#define OB_WIN_TYPE_MEM 0x0 ++#define OB_WIN_TYPE_IO 0x4 ++#define OB_WIN_TYPE_CONFIG_TYPE0 0x8 ++#define OB_WIN_TYPE_CONFIG_TYPE1 0x9 ++#define OB_WIN_TYPE_MSG 0xc ++ + /* LMI registers base address and register offsets */ + #define LMI_BASE_ADDR 0x6000 + #define CFG_REG (LMI_BASE_ADDR + 0x0) +@@ -174,6 +214,13 @@ struct advk_pcie { + struct platform_device *pdev; + void __iomem *base; + struct list_head resources; ++ struct { ++ phys_addr_t match; ++ phys_addr_t remap; ++ phys_addr_t mask; ++ u32 actions; ++ } wins[OB_WIN_COUNT]; ++ u8 wins_count; + struct irq_domain *irq_domain; + struct irq_chip irq_chip; + raw_spinlock_t irq_lock; +@@ -349,9 +396,39 @@ err: + dev_err(dev, "link never came up\n"); + } + ++/* ++ * Set PCIe address window register which could be used for memory ++ * mapping. ++ */ ++static void advk_pcie_set_ob_win(struct advk_pcie *pcie, u8 win_num, ++ phys_addr_t match, phys_addr_t remap, ++ phys_addr_t mask, u32 actions) ++{ ++ advk_writel(pcie, OB_WIN_ENABLE | ++ lower_32_bits(match), OB_WIN_MATCH_LS(win_num)); ++ advk_writel(pcie, upper_32_bits(match), OB_WIN_MATCH_MS(win_num)); ++ advk_writel(pcie, lower_32_bits(remap), OB_WIN_REMAP_LS(win_num)); ++ advk_writel(pcie, upper_32_bits(remap), OB_WIN_REMAP_MS(win_num)); ++ advk_writel(pcie, lower_32_bits(mask), OB_WIN_MASK_LS(win_num)); ++ advk_writel(pcie, upper_32_bits(mask), OB_WIN_MASK_MS(win_num)); ++ advk_writel(pcie, actions, OB_WIN_ACTIONS(win_num)); ++} ++ ++static void advk_pcie_disable_ob_win(struct advk_pcie *pcie, u8 win_num) ++{ ++ advk_writel(pcie, 0, OB_WIN_MATCH_LS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_MATCH_MS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_REMAP_LS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_REMAP_MS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_MASK_LS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_MASK_MS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_ACTIONS(win_num)); ++} ++ + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; ++ int i; + + /* Set to Direct mode */ + reg = advk_readl(pcie, CTRL_CONFIG_REG); +@@ -415,15 +492,51 @@ static void advk_pcie_setup_hw(struct ad + reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); + advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); + ++ /* ++ * Enable AXI address window location generation: ++ * When it is enabled, the default outbound window ++ * configurations (Default User Field: 0xD0074CFC) ++ * are used to transparent address translation for ++ * the outbound transactions. Thus, PCIe address ++ * windows are not required for transparent memory ++ * access when default outbound window configuration ++ * is set for memory access. ++ */ + reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); + reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE; + advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); + +- /* Bypass the address window mapping for PIO */ ++ /* ++ * Set memory access in Default User Field so it ++ * is not required to configure PCIe address for ++ * transparent memory access. ++ */ ++ advk_writel(pcie, OB_WIN_TYPE_MEM, OB_WIN_DEFAULT_ACTIONS); ++ ++ /* ++ * Bypass the address window mapping for PIO: ++ * Since PIO access already contains all required ++ * info over AXI interface by PIO registers, the ++ * address window is not required. ++ */ + reg = advk_readl(pcie, PIO_CTRL); + reg |= PIO_CTRL_ADDR_WIN_DISABLE; + advk_writel(pcie, reg, PIO_CTRL); + ++ /* ++ * Configure PCIe address windows for non-memory or ++ * non-transparent access as by default PCIe uses ++ * transparent memory access. ++ */ ++ for (i = 0; i < pcie->wins_count; i++) ++ advk_pcie_set_ob_win(pcie, i, ++ pcie->wins[i].match, pcie->wins[i].remap, ++ pcie->wins[i].mask, pcie->wins[i].actions); ++ ++ /* Disable remaining PCIe outbound windows */ ++ for (i = pcie->wins_count; i < OB_WIN_COUNT; i++) ++ advk_pcie_disable_ob_win(pcie, i); ++ + advk_pcie_train_link(pcie); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); +@@ -1038,6 +1151,7 @@ static int advk_pcie_probe(struct platfo + struct advk_pcie *pcie; + struct resource *res; + struct pci_host_bridge *bridge; ++ struct resource_entry *entry; + int ret, irq; + + bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie)); +@@ -1067,6 +1181,80 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ resource_list_for_each_entry(entry, &pcie->resources) { ++ resource_size_t start = entry->res->start; ++ resource_size_t size = resource_size(entry->res); ++ unsigned long type = resource_type(entry->res); ++ u64 win_size; ++ ++ /* ++ * Aardvark hardware allows to configure also PCIe window ++ * for config type 0 and type 1 mapping, but driver uses ++ * only PIO for issuing configuration transfers which does ++ * not use PCIe window configuration. ++ */ ++ if (type != IORESOURCE_MEM && type != IORESOURCE_MEM_64 && ++ type != IORESOURCE_IO) ++ continue; ++ ++ /* ++ * Skip transparent memory resources. Default outbound access ++ * configuration is set to transparent memory access so it ++ * does not need window configuration. ++ */ ++ if ((type == IORESOURCE_MEM || type == IORESOURCE_MEM_64) && ++ entry->offset == 0) ++ continue; ++ ++ /* ++ * The n-th PCIe window is configured by tuple (match, remap, mask) ++ * and an access to address A uses this window if A matches the ++ * match with given mask. ++ * So every PCIe window size must be a power of two and every start ++ * address must be aligned to window size. Minimal size is 64 KiB ++ * because lower 16 bits of mask must be zero. Remapped address ++ * may have set only bits from the mask. ++ */ ++ while (pcie->wins_count < OB_WIN_COUNT && size > 0) { ++ /* Calculate the largest aligned window size */ ++ win_size = (1ULL << (fls64(size)-1)) | ++ (start ? (1ULL << __ffs64(start)) : 0); ++ win_size = 1ULL << __ffs64(win_size); ++ if (win_size < 0x10000) ++ break; ++ ++ dev_dbg(dev, ++ "Configuring PCIe window %d: [0x%llx-0x%llx] as %lu\n", ++ pcie->wins_count, (unsigned long long)start, ++ (unsigned long long)start + win_size, type); ++ ++ if (type == IORESOURCE_IO) { ++ pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_IO; ++ pcie->wins[pcie->wins_count].match = pci_pio_to_address(start); ++ } else { ++ pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_MEM; ++ pcie->wins[pcie->wins_count].match = start; ++ } ++ pcie->wins[pcie->wins_count].remap = start - entry->offset; ++ pcie->wins[pcie->wins_count].mask = ~(win_size - 1); ++ ++ if (pcie->wins[pcie->wins_count].remap & (win_size - 1)) ++ break; ++ ++ start += win_size; ++ size -= win_size; ++ pcie->wins_count++; ++ } ++ ++ if (size > 0) { ++ dev_err(&pcie->pdev->dev, ++ "Invalid PCIe region [0x%llx-0x%llx]\n", ++ (unsigned long long)entry->res->start, ++ (unsigned long long)entry->res->end + 1); ++ return -EINVAL; ++ } ++ } ++ + pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, + "reset-gpios", 0, + GPIOD_OUT_LOW, diff --git a/queue-4.19/pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch b/queue-4.19/pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch new file mode 100644 index 00000000000..414d4b64dcc --- /dev/null +++ b/queue-4.19/pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch @@ -0,0 +1,55 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:48 +0100 +Subject: PCI: aardvark: Don't touch PCIe registers if no card connected +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211124230500.27109-9-kabel@kernel.org> + +From: Pali Rohár + +commit 70e380250c3621c55ff218cbaf2272830d9dbb1d upstream. + +When there is no PCIe card connected and advk_pcie_rd_conf() or +advk_pcie_wr_conf() is called for PCI bus which doesn't belong to emulated +root bridge, the aardvark driver throws the following error message: + + advk-pcie d0070000.pcie: config read/write timed out + +Obviously accessing PCIe registers of disconnected card is not possible. + +Extend check in advk_pcie_valid_device() function for validating +availability of PCIe bus. If PCIe link is down, then the device is marked +as Not Found and the driver does not try to access these registers. + +This is just an optimization to prevent accessing PCIe registers when card +is disconnected. Trying to access PCIe registers of disconnected card does +not cause any crash, kernel just needs to wait for a timeout. So if card +disappear immediately after checking for PCIe link (before accessing PCIe +registers), it does not cause any problems. + +Link: https://lore.kernel.org/r/20200702083036.12230-1-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -525,6 +525,13 @@ static bool advk_pcie_valid_device(struc + if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) + return false; + ++ /* ++ * If the link goes down after we check for link-up, nothing bad ++ * happens but the config access times out. ++ */ ++ if (bus->number != pcie->root_bus_nr && !advk_pcie_link_up(pcie)) ++ return false; ++ + return true; + } + diff --git a/queue-4.19/pci-aardvark-fix-a-leaked-reference-by-adding-missing-of_node_put.patch b/queue-4.19/pci-aardvark-fix-a-leaked-reference-by-adding-missing-of_node_put.patch new file mode 100644 index 00000000000..3006debaa0f --- /dev/null +++ b/queue-4.19/pci-aardvark-fix-a-leaked-reference-by-adding-missing-of_node_put.patch @@ -0,0 +1,74 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:41 +0100 +Subject: PCI: aardvark: Fix a leaked reference by adding missing of_node_put() +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Wen Yang" , "Lorenzo Pieralisi" , "Thomas Petazzoni" , "Bjorn Helgaas" , linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, "Marek Behún" +Message-ID: <20211124230500.27109-2-kabel@kernel.org> + +From: Wen Yang + +commit 3842f5166bf1ef286fe7a39f262b5c9581308366 upstream. + +The call to of_get_next_child() returns a node pointer with refcount +incremented thus it must be explicitly decremented after the last +usage. + +irq_domain_add_linear() also calls of_node_get() to increase refcount, +so irq_domain will not be affected when it is released. + +Detected by coccinelle with the following warnings: + ./drivers/pci/controller/pci-aardvark.c:826:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 798, but without a corresponding object release within this function. + +Signed-off-by: Wen Yang +Signed-off-by: Lorenzo Pieralisi +Cc: Thomas Petazzoni +Cc: Lorenzo Pieralisi +Cc: Bjorn Helgaas +Cc: linux-pci@vger.kernel.org +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -754,6 +754,7 @@ static int advk_pcie_init_irq_domain(str + struct device_node *node = dev->of_node; + struct device_node *pcie_intc_node; + struct irq_chip *irq_chip; ++ int ret = 0; + + raw_spin_lock_init(&pcie->irq_lock); + +@@ -768,8 +769,8 @@ static int advk_pcie_init_irq_domain(str + irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", + dev_name(dev)); + if (!irq_chip->name) { +- of_node_put(pcie_intc_node); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto out_put_node; + } + + irq_chip->irq_mask = advk_pcie_irq_mask; +@@ -781,11 +782,13 @@ static int advk_pcie_init_irq_domain(str + &advk_pcie_irq_domain_ops, pcie); + if (!pcie->irq_domain) { + dev_err(dev, "Failed to get a INTx IRQ domain\n"); +- of_node_put(pcie_intc_node); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto out_put_node; + } + +- return 0; ++out_put_node: ++ of_node_put(pcie_intc_node); ++ return ret; + } + + static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) diff --git a/queue-4.19/pci-aardvark-fix-checking-for-link-up-via-ltssm-state.patch b/queue-4.19/pci-aardvark-fix-checking-for-link-up-via-ltssm-state.patch new file mode 100644 index 00000000000..f5185d60dbc --- /dev/null +++ b/queue-4.19/pci-aardvark-fix-checking-for-link-up-via-ltssm-state.patch @@ -0,0 +1,131 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:55 +0100 +Subject: PCI: aardvark: Fix checking for link up via LTSSM state +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" , "Remi Pommarel" +Message-ID: <20211124230500.27109-16-kabel@kernel.org> + +From: Pali Rohár + +commit 661c399a651c11aaf83c45cbfe0b4a1fb7bc3179 upstream. + +Current implementation of advk_pcie_link_up() is wrong as it marks also +link disabled or hot reset states as link up. + +Fix it by marking link up only to those states which are defined in PCIe +Base specification 3.0, Table 4-14: Link Status Mapped to the LTSSM. + +To simplify implementation, Define macros for every LTSSM state which +aardvark hardware can return in CFG_REG register. + +Fix also checking for link training according to the same Table 4-14. +Define a new function advk_pcie_link_training() for this purpose. + +Link: https://lore.kernel.org/r/20211005180952.6812-13-kabel@kernel.org +Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Cc: stable@vger.kernel.org +Cc: Remi Pommarel +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 71 ++++++++++++++++++++++++++++++++-- + 1 file changed, 67 insertions(+), 4 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -151,9 +151,50 @@ + #define CFG_REG (LMI_BASE_ADDR + 0x0) + #define LTSSM_SHIFT 24 + #define LTSSM_MASK 0x3f +-#define LTSSM_L0 0x10 + #define RC_BAR_CONFIG 0x300 + ++/* LTSSM values in CFG_REG */ ++enum { ++ LTSSM_DETECT_QUIET = 0x0, ++ LTSSM_DETECT_ACTIVE = 0x1, ++ LTSSM_POLLING_ACTIVE = 0x2, ++ LTSSM_POLLING_COMPLIANCE = 0x3, ++ LTSSM_POLLING_CONFIGURATION = 0x4, ++ LTSSM_CONFIG_LINKWIDTH_START = 0x5, ++ LTSSM_CONFIG_LINKWIDTH_ACCEPT = 0x6, ++ LTSSM_CONFIG_LANENUM_ACCEPT = 0x7, ++ LTSSM_CONFIG_LANENUM_WAIT = 0x8, ++ LTSSM_CONFIG_COMPLETE = 0x9, ++ LTSSM_CONFIG_IDLE = 0xa, ++ LTSSM_RECOVERY_RCVR_LOCK = 0xb, ++ LTSSM_RECOVERY_SPEED = 0xc, ++ LTSSM_RECOVERY_RCVR_CFG = 0xd, ++ LTSSM_RECOVERY_IDLE = 0xe, ++ LTSSM_L0 = 0x10, ++ LTSSM_RX_L0S_ENTRY = 0x11, ++ LTSSM_RX_L0S_IDLE = 0x12, ++ LTSSM_RX_L0S_FTS = 0x13, ++ LTSSM_TX_L0S_ENTRY = 0x14, ++ LTSSM_TX_L0S_IDLE = 0x15, ++ LTSSM_TX_L0S_FTS = 0x16, ++ LTSSM_L1_ENTRY = 0x17, ++ LTSSM_L1_IDLE = 0x18, ++ LTSSM_L2_IDLE = 0x19, ++ LTSSM_L2_TRANSMIT_WAKE = 0x1a, ++ LTSSM_DISABLED = 0x20, ++ LTSSM_LOOPBACK_ENTRY_MASTER = 0x21, ++ LTSSM_LOOPBACK_ACTIVE_MASTER = 0x22, ++ LTSSM_LOOPBACK_EXIT_MASTER = 0x23, ++ LTSSM_LOOPBACK_ENTRY_SLAVE = 0x24, ++ LTSSM_LOOPBACK_ACTIVE_SLAVE = 0x25, ++ LTSSM_LOOPBACK_EXIT_SLAVE = 0x26, ++ LTSSM_HOT_RESET = 0x27, ++ LTSSM_RECOVERY_EQUALIZATION_PHASE0 = 0x28, ++ LTSSM_RECOVERY_EQUALIZATION_PHASE1 = 0x29, ++ LTSSM_RECOVERY_EQUALIZATION_PHASE2 = 0x2a, ++ LTSSM_RECOVERY_EQUALIZATION_PHASE3 = 0x2b, ++}; ++ + /* PCIe core controller registers */ + #define CTRL_CORE_BASE_ADDR 0x18000 + #define CTRL_CONFIG_REG (CTRL_CORE_BASE_ADDR + 0x0) +@@ -247,13 +288,35 @@ static inline u32 advk_readl(struct advk + return readl(pcie->base + reg); + } + +-static int advk_pcie_link_up(struct advk_pcie *pcie) ++static u8 advk_pcie_ltssm_state(struct advk_pcie *pcie) + { +- u32 val, ltssm_state; ++ u32 val; ++ u8 ltssm_state; + + val = advk_readl(pcie, CFG_REG); + ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK; +- return ltssm_state >= LTSSM_L0; ++ return ltssm_state; ++} ++ ++static inline bool advk_pcie_link_up(struct advk_pcie *pcie) ++{ ++ /* check if LTSSM is in normal operation - some L* state */ ++ u8 ltssm_state = advk_pcie_ltssm_state(pcie); ++ return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED; ++} ++ ++static inline bool advk_pcie_link_training(struct advk_pcie *pcie) ++{ ++ /* ++ * According to PCIe Base specification 3.0, Table 4-14: Link ++ * Status Mapped to the LTSSM is Link Training mapped to LTSSM ++ * Configuration and Recovery states. ++ */ ++ u8 ltssm_state = advk_pcie_ltssm_state(pcie); ++ return ((ltssm_state >= LTSSM_CONFIG_LINKWIDTH_START && ++ ltssm_state < LTSSM_L0) || ++ (ltssm_state >= LTSSM_RECOVERY_EQUALIZATION_PHASE0 && ++ ltssm_state <= LTSSM_RECOVERY_EQUALIZATION_PHASE3)); + } + + static int advk_pcie_wait_for_link(struct advk_pcie *pcie) diff --git a/queue-4.19/pci-aardvark-fix-compilation-on-s390.patch b/queue-4.19/pci-aardvark-fix-compilation-on-s390.patch new file mode 100644 index 00000000000..d804142c4c3 --- /dev/null +++ b/queue-4.19/pci-aardvark-fix-compilation-on-s390.patch @@ -0,0 +1,45 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:49 +0100 +Subject: PCI: aardvark: Fix compilation on s390 +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "kernel test robot" , "Lorenzo Pieralisi" , "Marek Behún" , "Marek Behún" +Message-ID: <20211124230500.27109-10-kabel@kernel.org> + +From: Pali Rohár + +commit b32c012e4b98f0126aa327be2d1f409963057643 upstream. + +Include linux/gpio/consumer.h instead of linux/gpio.h, as is said in the +latter file. + +This was reported by kernel test bot when compiling for s390. + + drivers/pci/controller/pci-aardvark.c:350:2: error: implicit declaration of function 'gpiod_set_value_cansleep' [-Werror,-Wimplicit-function-declaration] + drivers/pci/controller/pci-aardvark.c:1074:21: error: implicit declaration of function 'devm_gpiod_get_from_of_node' [-Werror,-Wimplicit-function-declaration] + drivers/pci/controller/pci-aardvark.c:1076:14: error: use of undeclared identifier 'GPIOD_OUT_LOW' + +Link: https://lore.kernel.org/r/202006211118.LxtENQfl%25lkp@intel.com +Link: https://lore.kernel.org/r/20200907111038.5811-2-pali@kernel.org +Fixes: 5169a9851daa ("PCI: aardvark: Issue PERST via GPIO") +Reported-by: kernel test robot +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -9,7 +9,7 @@ + */ + + #include +-#include ++#include + #include + #include + #include diff --git a/queue-4.19/pci-aardvark-fix-link-training.patch b/queue-4.19/pci-aardvark-fix-link-training.patch new file mode 100644 index 00000000000..bb039b24d41 --- /dev/null +++ b/queue-4.19/pci-aardvark-fix-link-training.patch @@ -0,0 +1,319 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:54 +0100 +Subject: PCI: aardvark: Fix link training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211124230500.27109-15-kabel@kernel.org> + +From: Pali Rohár + +commit f76b36d40beee0a13aa8f6aa011df0d7cbbb8a7f upstream. + +Fix multiple link training issues in aardvark driver. The main reason of +these issues was misunderstanding of what certain registers do, since their +names and comments were misleading: before commit 96be36dbffac ("PCI: +aardvark: Replace custom macros by standard linux/pci_regs.h macros"), the +pci-aardvark.c driver used custom macros for accessing standard PCIe Root +Bridge registers, and misleading comments did not help to understand what +the code was really doing. + +After doing more tests and experiments I've come to the conclusion that the +SPEED_GEN register in aardvark sets the PCIe revision / generation +compliance and forces maximal link speed. Both GEN3 and GEN2 values set the +read-only PCI_EXP_FLAGS_VERS bits (PCIe capabilities version of Root +Bridge) to value 2, while GEN1 value sets PCI_EXP_FLAGS_VERS to 1, which +matches with PCI Express specifications revisions 3, 2 and 1 respectively. +Changing SPEED_GEN also sets the read-only bits PCI_EXP_LNKCAP_SLS and +PCI_EXP_LNKCAP2_SLS to corresponding speed. + +(Note that PCI Express rev 1 specification does not define PCI_EXP_LNKCAP2 + and PCI_EXP_LNKCTL2 registers and when SPEED_GEN is set to GEN1 (which + also sets PCI_EXP_FLAGS_VERS set to 1), lspci cannot access + PCI_EXP_LNKCAP2 and PCI_EXP_LNKCTL2 registers.) + +Changing PCIe link speed can be done via PCI_EXP_LNKCTL2_TLS bits of +PCI_EXP_LNKCTL2 register. Armada 3700 Functional Specifications says that +the default value of PCI_EXP_LNKCTL2_TLS is based on SPEED_GEN value, but +tests showed that the default value is always 8.0 GT/s, independently of +speed set by SPEED_GEN. So after setting SPEED_GEN, we must also set value +in PCI_EXP_LNKCTL2 register via PCI_EXP_LNKCTL2_TLS bits. + +Triggering PCI_EXP_LNKCTL_RL bit immediately after setting LINK_TRAINING_EN +bit actually doesn't do anything. Tests have shown that a delay is needed +after enabling LINK_TRAINING_EN bit. As triggering PCI_EXP_LNKCTL_RL +currently does nothing, remove it. + +Commit 43fc679ced18 ("PCI: aardvark: Improve link training") introduced +code which sets SPEED_GEN register based on negotiated link speed from +PCI_EXP_LNKSTA_CLS bits of PCI_EXP_LNKSTA register. This code was added to +fix detection of Compex WLE900VX (Atheros QCA9880) WiFi GEN1 PCIe cards, as +otherwise these cards were "invisible" on PCIe bus (probably because they +crashed). But apparently more people reported the same issues with these +cards also with other PCIe controllers [1] and I was able to reproduce this +issue also with other "noname" WiFi cards based on Atheros QCA9890 chip +(with the same PCI vendor/device ids as Atheros QCA9880). So this is not an +issue in aardvark but rather an issue in Atheros QCA98xx chips. Also, this +issue only exists if the kernel is compiled with PCIe ASPM support, and a +generic workaround for this is to change PCIe Bridge to 2.5 GT/s link speed +via PCI_EXP_LNKCTL2_TLS_2_5GT bits in PCI_EXP_LNKCTL2 register [2], before +triggering PCI_EXP_LNKCTL_RL bit. This workaround also works when SPEED_GEN +is set to value GEN2 (5 GT/s). So remove this hack completely in the +aardvark driver and always set SPEED_GEN to value from 'max-link-speed' DT +property. Fix for Atheros QCA98xx chips is handled separately by patch [2]. + +These two things (code for triggering PCI_EXP_LNKCTL_RL bit and changing +SPEED_GEN value) also explain why commit 6964494582f5 ("PCI: aardvark: +Train link immediately after enabling training") somehow fixed detection of +those problematic Compex cards with Atheros chips: if triggering link +retraining (via PCI_EXP_LNKCTL_RL bit) was done immediately after enabling +link training (via LINK_TRAINING_EN), it did nothing. If there was a +specific delay, aardvark HW already initialized PCIe link and therefore +triggering link retraining caused the above issue. Compex cards triggered +link down event and disappeared from the PCIe bus. + +Commit f4c7d053d7f7 ("PCI: aardvark: Wait for endpoint to be ready before +training link") added 100ms sleep before calling 'Start link training' +command and explained that it is a requirement of PCI Express +specification. But the code after this 100ms sleep was not doing 'Start +link training', rather it triggered PCI_EXP_LNKCTL_RL bit via PCIe Root +Bridge to put link into Recovery state. + +The required delay after fundamental reset is already done in function +advk_pcie_wait_for_link() which also checks whether PCIe link is up. +So after removing the code which triggers PCI_EXP_LNKCTL_RL bit on PCIe +Root Bridge, there is no need to wait 100ms again. Remove the extra +msleep() call and update comment about the delay required by the PCI +Express specification. + +According to Marvell Armada 3700 Functional Specifications, Link training +should be enabled via aardvark register LINK_TRAINING_EN after selecting +PCIe generation and x1 lane. There is no need to disable it prior resetting +card via PERST# signal. This disabling code was introduced in commit +5169a9851daa ("PCI: aardvark: Issue PERST via GPIO") as a workaround for +some Atheros cards. It turns out that this also is Atheros specific issue +and affects any PCIe controller, not only aardvark. Moreover this Atheros +issue was triggered by juggling with PCI_EXP_LNKCTL_RL, LINK_TRAINING_EN +and SPEED_GEN bits interleaved with sleeps. Now, after removing triggering +PCI_EXP_LNKCTL_RL, there is no need to explicitly disable LINK_TRAINING_EN +bit. So remove this code too. The problematic Compex cards described in +previous git commits are correctly detected in advk_pcie_train_link() +function even after applying all these changes. + +Note that with this patch, and also prior this patch, some NVMe disks which +support PCIe GEN3 with 8 GT/s speed are negotiated only at the lowest link +speed 2.5 GT/s, independently of SPEED_GEN value. After manually triggering +PCI_EXP_LNKCTL_RL bit (e.g. from userspace via setpci), these NVMe disks +change link speed to 5 GT/s when SPEED_GEN was configured to GEN2. This +issue first needs to be properly investigated. I will send a fix in the +future. + +On the other hand, some other GEN2 PCIe cards with 5 GT/s speed are +autonomously by HW autonegotiated at full 5 GT/s speed without need of any +software interaction. + +Armada 3700 Functional Specifications describes the following steps for +link training: set SPEED_GEN to GEN2, enable LINK_TRAINING_EN, poll until +link training is complete, trigger PCI_EXP_LNKCTL_RL, poll until signal +rate is 5 GT/s, poll until link training is complete, enable ASPM L0s. + +The requirement for triggering PCI_EXP_LNKCTL_RL can be explained by the +need to achieve 5 GT/s speed (as changing link speed is done by throw to +recovery state entered by PCI_EXP_LNKCTL_RL) or maybe as a part of enabling +ASPM L0s (but in this case ASPM L0s should have been enabled prior +PCI_EXP_LNKCTL_RL). + +It is unknown why the original pci-aardvark.c driver was triggering +PCI_EXP_LNKCTL_RL bit before waiting for the link to be up. This does not +align with neither PCIe base specifications nor with Armada 3700 Functional +Specification. (Note that in older versions of aardvark, this bit was +called incorrectly PCIE_CORE_LINK_TRAINING, so this may be the reason.) + +It is also unknown why Armada 3700 Functional Specification says that it is +needed to trigger PCI_EXP_LNKCTL_RL for GEN2 mode, as according to PCIe +base specification 5 GT/s speed negotiation is supposed to be entirely +autonomous, even if initial speed is 2.5 GT/s. + +[1] - https://lore.kernel.org/linux-pci/87h7l8axqp.fsf@toke.dk/ +[2] - https://lore.kernel.org/linux-pci/20210326124326.21163-1-pali@kernel.org/ + +Link: https://lore.kernel.org/r/20211005180952.6812-12-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 119 ++++++++++------------------------ + 1 file changed, 35 insertions(+), 84 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -247,11 +247,6 @@ static inline u32 advk_readl(struct advk + return readl(pcie->base + reg); + } + +-static inline u16 advk_read16(struct advk_pcie *pcie, u64 reg) +-{ +- return advk_readl(pcie, (reg & ~0x3)) >> ((reg & 0x3) * 8); +-} +- + static int advk_pcie_link_up(struct advk_pcie *pcie) + { + u32 val, ltssm_state; +@@ -278,23 +273,9 @@ static int advk_pcie_wait_for_link(struc + + static void advk_pcie_issue_perst(struct advk_pcie *pcie) + { +- u32 reg; +- + if (!pcie->reset_gpio) + return; + +- /* +- * As required by PCI Express spec (PCI Express Base Specification, REV. +- * 4.0 PCI Express, February 19 2014, 6.6.1 Conventional Reset) a delay +- * for at least 100ms after de-asserting PERST# signal is needed before +- * link training is enabled. So ensure that link training is disabled +- * prior de-asserting PERST# signal to fulfill that PCI Express spec +- * requirement. +- */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg &= ~LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- + /* 10ms delay is needed for some cards */ + dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); + gpiod_set_value_cansleep(pcie->reset_gpio, 1); +@@ -302,54 +283,47 @@ static void advk_pcie_issue_perst(struct + gpiod_set_value_cansleep(pcie->reset_gpio, 0); + } + +-static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) ++static void advk_pcie_train_link(struct advk_pcie *pcie) + { +- int ret, neg_gen; ++ struct device *dev = &pcie->pdev->dev; + u32 reg; ++ int ret; + +- /* Setup link speed */ ++ /* ++ * Setup PCIe rev / gen compliance based on device tree property ++ * 'max-link-speed' which also forces maximal link speed. ++ */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~PCIE_GEN_SEL_MSK; +- if (gen == 3) ++ if (pcie->link_gen == 3) + reg |= SPEED_GEN_3; +- else if (gen == 2) ++ else if (pcie->link_gen == 2) + reg |= SPEED_GEN_2; + else + reg |= SPEED_GEN_1; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* +- * Enable link training. This is not needed in every call to this +- * function, just once suffices, but it does not break anything either. +- */ ++ * Set maximal link speed value also into PCIe Link Control 2 register. ++ * Armada 3700 Functional Specification says that default value is based ++ * on SPEED_GEN but tests showed that default value is always 8.0 GT/s. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL2); ++ reg &= ~PCI_EXP_LNKCTL2_TLS; ++ if (pcie->link_gen == 3) ++ reg |= PCI_EXP_LNKCTL2_TLS_8_0GT; ++ else if (pcie->link_gen == 2) ++ reg |= PCI_EXP_LNKCTL2_TLS_5_0GT; ++ else ++ reg |= PCI_EXP_LNKCTL2_TLS_2_5GT; ++ advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL2); ++ ++ /* Enable link training after selecting PCIe generation */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg |= LINK_TRAINING_EN; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* +- * Start link training immediately after enabling it. +- * This solves problems for some buggy cards. +- */ +- reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); +- reg |= PCI_EXP_LNKCTL_RL; +- advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); +- +- ret = advk_pcie_wait_for_link(pcie); +- if (ret) +- return ret; +- +- reg = advk_read16(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKSTA); +- neg_gen = reg & PCI_EXP_LNKSTA_CLS; +- +- return neg_gen; +-} +- +-static void advk_pcie_train_link(struct advk_pcie *pcie) +-{ +- struct device *dev = &pcie->pdev->dev; +- int neg_gen = -1, gen; +- +- /* + * Reset PCIe card via PERST# signal. Some cards are not detected + * during link training when they are in some non-initial state. + */ +@@ -359,41 +333,18 @@ static void advk_pcie_train_link(struct + * PERST# signal could have been asserted by pinctrl subsystem before + * probe() callback has been called or issued explicitly by reset gpio + * function advk_pcie_issue_perst(), making the endpoint going into +- * fundamental reset. As required by PCI Express spec a delay for at +- * least 100ms after such a reset before link training is needed. +- */ +- msleep(PCI_PM_D3COLD_WAIT); +- +- /* +- * Try link training at link gen specified by device tree property +- * 'max-link-speed'. If this fails, iteratively train at lower gen. +- */ +- for (gen = pcie->link_gen; gen > 0; --gen) { +- neg_gen = advk_pcie_train_at_gen(pcie, gen); +- if (neg_gen > 0) +- break; +- } +- +- if (neg_gen < 0) +- goto err; +- +- /* +- * After successful training if negotiated gen is lower than requested, +- * train again on negotiated gen. This solves some stability issues for +- * some buggy gen1 cards. ++ * fundamental reset. As required by PCI Express spec (PCI Express ++ * Base Specification, REV. 4.0 PCI Express, February 19 2014, 6.6.1 ++ * Conventional Reset) a delay for at least 100ms after such a reset ++ * before sending a Configuration Request to the device is needed. ++ * So wait until PCIe link is up. Function advk_pcie_wait_for_link() ++ * waits for link at least 900ms. + */ +- if (neg_gen < gen) { +- gen = neg_gen; +- neg_gen = advk_pcie_train_at_gen(pcie, gen); +- } +- +- if (neg_gen == gen) { +- dev_info(dev, "link up at gen %i\n", gen); +- return; +- } +- +-err: +- dev_err(dev, "link never came up\n"); ++ ret = advk_pcie_wait_for_link(pcie); ++ if (ret < 0) ++ dev_err(dev, "link never came up\n"); ++ else ++ dev_info(dev, "link up\n"); + } + + /* diff --git a/queue-4.19/pci-aardvark-fix-pcie-max-payload-size-setting.patch b/queue-4.19/pci-aardvark-fix-pcie-max-payload-size-setting.patch new file mode 100644 index 00000000000..73193bc33bb --- /dev/null +++ b/queue-4.19/pci-aardvark-fix-pcie-max-payload-size-setting.patch @@ -0,0 +1,51 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:53 +0100 +Subject: PCI: aardvark: Fix PCIe Max Payload Size setting +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211124230500.27109-14-kabel@kernel.org> + +From: Pali Rohár + +commit a4e17d65dafdd3513042d8f00404c9b6068a825c upstream. + +Change PCIe Max Payload Size setting in PCIe Device Control register to 512 +bytes to align with PCIe Link Initialization sequence as defined in Marvell +Armada 3700 Functional Specification. According to the specification, +maximal Max Payload Size supported by this device is 512 bytes. + +Without this kernel prints suspicious line: + + pci 0000:01:00.0: Upstream bridge's Max Payload Size set to 256 (was 16384, max 512) + +With this change it changes to: + + pci 0000:01:00.0: Upstream bridge's Max Payload Size set to 256 (was 512, max 512) + +Link: https://lore.kernel.org/r/20211005180952.6812-3-kabel@kernel.org +Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Cc: stable@vger.kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -452,8 +452,9 @@ static void advk_pcie_setup_hw(struct ad + reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + reg &= ~PCI_EXP_DEVCTL_RELAX_EN; + reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; ++ reg &= ~PCI_EXP_DEVCTL_PAYLOAD; + reg &= ~PCI_EXP_DEVCTL_READRQ; +- reg |= PCI_EXP_DEVCTL_PAYLOAD; /* Set max payload size */ ++ reg |= PCI_EXP_DEVCTL_PAYLOAD_512B; + reg |= PCI_EXP_DEVCTL_READRQ_512B; + advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + diff --git a/queue-4.19/pci-aardvark-improve-link-training.patch b/queue-4.19/pci-aardvark-improve-link-training.patch new file mode 100644 index 00000000000..484aa87d25d --- /dev/null +++ b/queue-4.19/pci-aardvark-improve-link-training.patch @@ -0,0 +1,210 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:44 +0100 +Subject: PCI: aardvark: Improve link training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Rob Herring" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211124230500.27109-5-kabel@kernel.org> + +From: Marek Behún + +commit 43fc679ced18006b12d918d7a8a4af392b7fbfe7 upstream. + +Currently the aardvark driver trains link in PCIe gen2 mode. This may +cause some buggy gen1 cards (such as Compex WLE900VX) to be unstable or +even not detected. Moreover when ASPM code tries to retrain link second +time, these cards may stop responding and link goes down. If gen1 is +used this does not happen. + +Unconditionally forcing gen1 is not a good solution since it may have +performance impact on gen2 cards. + +To overcome this, read 'max-link-speed' property (as defined in PCI +device tree bindings) and use this as max gen mode. Then iteratively try +link training at this mode or lower until successful. After successful +link training choose final controller gen based on Negotiated Link Speed +from Link Status register, which should match card speed. + +Link: https://lore.kernel.org/r/20200430080625.26070-5-pali@kernel.org +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 114 ++++++++++++++++++++++++++-------- + 1 file changed, 89 insertions(+), 25 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -35,6 +35,7 @@ + #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 + #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) + #define PCIE_CORE_LINK_TRAINING BIT(5) ++#define PCIE_CORE_LINK_SPEED_SHIFT 16 + #define PCIE_CORE_LINK_WIDTH_SHIFT 20 + #define PCIE_CORE_ERR_CAPCTL_REG 0x118 + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) +@@ -193,6 +194,7 @@ struct advk_pcie { + struct mutex msi_used_lock; + u16 msi_msg; + int root_bus_nr; ++ int link_gen; + }; + + static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) +@@ -216,23 +218,98 @@ static int advk_pcie_link_up(struct advk + + static int advk_pcie_wait_for_link(struct advk_pcie *pcie) + { +- struct device *dev = &pcie->pdev->dev; + int retries; + + /* check if the link is up or not */ + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { +- if (advk_pcie_link_up(pcie)) { +- dev_info(dev, "link up\n"); ++ if (advk_pcie_link_up(pcie)) + return 0; +- } + + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); + } + +- dev_err(dev, "link never came up\n"); + return -ETIMEDOUT; + } + ++static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) ++{ ++ int ret, neg_gen; ++ u32 reg; ++ ++ /* Setup link speed */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~PCIE_GEN_SEL_MSK; ++ if (gen == 3) ++ reg |= SPEED_GEN_3; ++ else if (gen == 2) ++ reg |= SPEED_GEN_2; ++ else ++ reg |= SPEED_GEN_1; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* ++ * Enable link training. This is not needed in every call to this ++ * function, just once suffices, but it does not break anything either. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg |= LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* ++ * Start link training immediately after enabling it. ++ * This solves problems for some buggy cards. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); ++ reg |= PCIE_CORE_LINK_TRAINING; ++ advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); ++ ++ ret = advk_pcie_wait_for_link(pcie); ++ if (ret) ++ return ret; ++ ++ reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); ++ neg_gen = (reg >> PCIE_CORE_LINK_SPEED_SHIFT) & 0xf; ++ ++ return neg_gen; ++} ++ ++static void advk_pcie_train_link(struct advk_pcie *pcie) ++{ ++ struct device *dev = &pcie->pdev->dev; ++ int neg_gen = -1, gen; ++ ++ /* ++ * Try link training at link gen specified by device tree property ++ * 'max-link-speed'. If this fails, iteratively train at lower gen. ++ */ ++ for (gen = pcie->link_gen; gen > 0; --gen) { ++ neg_gen = advk_pcie_train_at_gen(pcie, gen); ++ if (neg_gen > 0) ++ break; ++ } ++ ++ if (neg_gen < 0) ++ goto err; ++ ++ /* ++ * After successful training if negotiated gen is lower than requested, ++ * train again on negotiated gen. This solves some stability issues for ++ * some buggy gen1 cards. ++ */ ++ if (neg_gen < gen) { ++ gen = neg_gen; ++ neg_gen = advk_pcie_train_at_gen(pcie, gen); ++ } ++ ++ if (neg_gen == gen) { ++ dev_info(dev, "link up at gen %i\n", gen); ++ return; ++ } ++ ++err: ++ dev_err(dev, "link never came up\n"); ++} ++ + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; +@@ -268,12 +345,6 @@ static void advk_pcie_setup_hw(struct ad + PCIE_CORE_CTRL2_TD_ENABLE; + advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); + +- /* Set GEN2 */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg &= ~PCIE_GEN_SEL_MSK; +- reg |= SPEED_GEN_2; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- + /* Set lane X1 */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~LANE_CNT_MSK; +@@ -321,20 +392,7 @@ static void advk_pcie_setup_hw(struct ad + */ + msleep(PCI_PM_D3COLD_WAIT); + +- /* Enable link training */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg |= LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- +- /* +- * Start link training immediately after enabling it. +- * This solves problems for some buggy cards. +- */ +- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); +- reg |= PCIE_CORE_LINK_TRAINING; +- advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); +- +- advk_pcie_wait_for_link(pcie); ++ advk_pcie_train_link(pcie); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | +@@ -968,6 +1026,12 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ ret = of_pci_get_max_link_speed(dev->of_node); ++ if (ret <= 0 || ret > 3) ++ pcie->link_gen = 3; ++ else ++ pcie->link_gen = ret; ++ + advk_pcie_setup_hw(pcie); + + ret = advk_pcie_init_irq_domain(pcie); diff --git a/queue-4.19/pci-aardvark-indicate-error-in-val-when-config-read-fails.patch b/queue-4.19/pci-aardvark-indicate-error-in-val-when-config-read-fails.patch new file mode 100644 index 00000000000..170a4762a1f --- /dev/null +++ b/queue-4.19/pci-aardvark-indicate-error-in-val-when-config-read-fails.patch @@ -0,0 +1,44 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:47 +0100 +Subject: PCI: aardvark: Indicate error in 'val' when config read fails +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Bjorn Helgaas" , "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211124230500.27109-8-kabel@kernel.org> + +From: Pali Rohár + +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 +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -596,8 +596,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); diff --git a/queue-4.19/pci-aardvark-issue-perst-via-gpio.patch b/queue-4.19/pci-aardvark-issue-perst-via-gpio.patch new file mode 100644 index 00000000000..9bd56756458 --- /dev/null +++ b/queue-4.19/pci-aardvark-issue-perst-via-gpio.patch @@ -0,0 +1,129 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:45 +0100 +Subject: PCI: aardvark: Issue PERST via GPIO +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211124230500.27109-6-kabel@kernel.org> + +From: Pali Rohár + +commit 5169a9851daaa2782a7bd2bb83d5b1bd224b2879 upstream. + +Add support for issuing PERST via GPIO specified in 'reset-gpios' +property (as described in PCI device tree bindings). + +Some buggy cards (e.g. Compex WLE900VX or WLE1216) are not detected +after reboot when PERST is not issued during driver initialization. + +If bootloader already enabled link training then issuing PERST has no +effect for some buggy cards (e.g. Compex WLE900VX) and these cards are +not detected. We therefore clear the LINK_TRAINING_EN register before. + +It was observed that Compex WLE900VX card needs to be in PERST reset +for at least 10ms if bootloader enabled link training. + +Tested on Turris MOX. + +Link: https://lore.kernel.org/r/20200430080625.26070-6-pali@kernel.org +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 43 +++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -9,6 +9,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -17,6 +18,7 @@ + #include + #include + #include ++#include + #include + + #include "../pci.h" +@@ -195,6 +197,7 @@ struct advk_pcie { + u16 msi_msg; + int root_bus_nr; + int link_gen; ++ struct gpio_desc *reset_gpio; + }; + + static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) +@@ -310,10 +313,31 @@ err: + dev_err(dev, "link never came up\n"); + } + ++static void advk_pcie_issue_perst(struct advk_pcie *pcie) ++{ ++ u32 reg; ++ ++ if (!pcie->reset_gpio) ++ return; ++ ++ /* PERST does not work for some cards when link training is enabled */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* 10ms delay is needed for some cards */ ++ dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 1); ++ usleep_range(10000, 11000); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 0); ++} ++ + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; + ++ advk_pcie_issue_perst(pcie); ++ + /* Set to Direct mode */ + reg = advk_readl(pcie, CTRL_CONFIG_REG); + reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); +@@ -386,7 +410,8 @@ static void advk_pcie_setup_hw(struct ad + + /* + * PERST# signal could have been asserted by pinctrl subsystem before +- * probe() callback has been called, making the endpoint going into ++ * probe() callback has been called or issued explicitly by reset gpio ++ * function advk_pcie_issue_perst(), making the endpoint going into + * fundamental reset. As required by PCI Express spec a delay for at + * least 100ms after such a reset before link training is needed. + */ +@@ -1026,6 +1051,22 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, ++ "reset-gpios", 0, ++ GPIOD_OUT_LOW, ++ "pcie1-reset"); ++ ret = PTR_ERR_OR_ZERO(pcie->reset_gpio); ++ if (ret) { ++ if (ret == -ENOENT) { ++ pcie->reset_gpio = NULL; ++ } else { ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get reset-gpio: %i\n", ++ ret); ++ return ret; ++ } ++ } ++ + ret = of_pci_get_max_link_speed(dev->of_node); + if (ret <= 0 || ret > 3) + pcie->link_gen = 3; diff --git a/queue-4.19/pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch b/queue-4.19/pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch new file mode 100644 index 00000000000..fe35085bf0e --- /dev/null +++ b/queue-4.19/pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch @@ -0,0 +1,130 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:50 +0100 +Subject: PCI: aardvark: Move PCIe reset card code to advk_pcie_train_link() +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211124230500.27109-11-kabel@kernel.org> + +From: Pali Rohár + +commit d0c6a3475b033960e85ae2bf176b14cab0a627d2 upstream. + +Move code which belongs to link training (delays and resets) into +advk_pcie_train_link() function, so everything related to link training, +including timings is at one place. + +After experiments it can be observed that link training in aardvark +hardware is very sensitive to timings and delays, so it is a good idea to +have this code at the same place as link training calls. + +This patch does not change behavior of aardvark initialization. + +Link: https://lore.kernel.org/r/20200907111038.5811-6-pali@kernel.org +Tested-by: Marek Behún +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 64 ++++++++++++++++++---------------- + 1 file changed, 34 insertions(+), 30 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -229,6 +229,25 @@ static int advk_pcie_wait_for_link(struc + return -ETIMEDOUT; + } + ++static void advk_pcie_issue_perst(struct advk_pcie *pcie) ++{ ++ u32 reg; ++ ++ if (!pcie->reset_gpio) ++ return; ++ ++ /* PERST does not work for some cards when link training is enabled */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* 10ms delay is needed for some cards */ ++ dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 1); ++ usleep_range(10000, 11000); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 0); ++} ++ + static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) + { + int ret, neg_gen; +@@ -277,6 +296,21 @@ static void advk_pcie_train_link(struct + int neg_gen = -1, gen; + + /* ++ * Reset PCIe card via PERST# signal. Some cards are not detected ++ * during link training when they are in some non-initial state. ++ */ ++ advk_pcie_issue_perst(pcie); ++ ++ /* ++ * PERST# signal could have been asserted by pinctrl subsystem before ++ * probe() callback has been called or issued explicitly by reset gpio ++ * function advk_pcie_issue_perst(), making the endpoint going into ++ * fundamental reset. As required by PCI Express spec a delay for at ++ * least 100ms after such a reset before link training is needed. ++ */ ++ msleep(PCI_PM_D3COLD_WAIT); ++ ++ /* + * Try link training at link gen specified by device tree property + * 'max-link-speed'. If this fails, iteratively train at lower gen. + */ +@@ -308,31 +342,10 @@ err: + dev_err(dev, "link never came up\n"); + } + +-static void advk_pcie_issue_perst(struct advk_pcie *pcie) +-{ +- u32 reg; +- +- if (!pcie->reset_gpio) +- return; +- +- /* PERST does not work for some cards when link training is enabled */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg &= ~LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- +- /* 10ms delay is needed for some cards */ +- dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); +- gpiod_set_value_cansleep(pcie->reset_gpio, 1); +- usleep_range(10000, 11000); +- gpiod_set_value_cansleep(pcie->reset_gpio, 0); +-} +- + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; + +- advk_pcie_issue_perst(pcie); +- + /* Set to Direct mode */ + reg = advk_readl(pcie, CTRL_CONFIG_REG); + reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); +@@ -404,15 +417,6 @@ static void advk_pcie_setup_hw(struct ad + reg |= PIO_CTRL_ADDR_WIN_DISABLE; + advk_writel(pcie, reg, PIO_CTRL); + +- /* +- * PERST# signal could have been asserted by pinctrl subsystem before +- * probe() callback has been called or issued explicitly by reset gpio +- * function advk_pcie_issue_perst(), making the endpoint going into +- * fundamental reset. As required by PCI Express spec a delay for at +- * least 100ms after such a reset before link training is needed. +- */ +- msleep(PCI_PM_D3COLD_WAIT); +- + advk_pcie_train_link(pcie); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); diff --git a/queue-4.19/pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch b/queue-4.19/pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch new file mode 100644 index 00000000000..8dbd367b1e1 --- /dev/null +++ b/queue-4.19/pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch @@ -0,0 +1,104 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:46 +0100 +Subject: PCI: aardvark: Replace custom macros by standard linux/pci_regs.h macros +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Rob Herring" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211124230500.27109-7-kabel@kernel.org> + +From: Pali Rohár + +commit 96be36dbffacea0aa9e6ec4839583e79faa141a1 upstream. + +PCI-E capability macros are already defined in linux/pci_regs.h. +Remove their reimplementation in pcie-aardvark. + +Link: https://lore.kernel.org/r/20200430080625.26070-9-pali@kernel.org +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 42 +++++++++++++++------------------- + 1 file changed, 19 insertions(+), 23 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -28,17 +28,7 @@ + #define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) + #define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) + #define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) +-#define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 +-#define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) +-#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 +-#define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) +-#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 +-#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 +-#define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 +-#define PCIE_CORE_LINK_L0S_ENTRY BIT(0) +-#define PCIE_CORE_LINK_TRAINING BIT(5) +-#define PCIE_CORE_LINK_SPEED_SHIFT 16 +-#define PCIE_CORE_LINK_WIDTH_SHIFT 20 ++#define PCIE_CORE_PCIEXP_CAP 0xc0 + #define PCIE_CORE_ERR_CAPCTL_REG 0x118 + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6) +@@ -210,6 +200,11 @@ static inline u32 advk_readl(struct advk + return readl(pcie->base + reg); + } + ++static inline u16 advk_read16(struct advk_pcie *pcie, u64 reg) ++{ ++ return advk_readl(pcie, (reg & ~0x3)) >> ((reg & 0x3) * 8); ++} ++ + static int advk_pcie_link_up(struct advk_pcie *pcie) + { + u32 val, ltssm_state; +@@ -262,16 +257,16 @@ static int advk_pcie_train_at_gen(struct + * Start link training immediately after enabling it. + * This solves problems for some buggy cards. + */ +- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); +- reg |= PCIE_CORE_LINK_TRAINING; +- advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); ++ reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); ++ reg |= PCI_EXP_LNKCTL_RL; ++ advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); + + ret = advk_pcie_wait_for_link(pcie); + if (ret) + return ret; + +- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); +- neg_gen = (reg >> PCIE_CORE_LINK_SPEED_SHIFT) & 0xf; ++ reg = advk_read16(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKSTA); ++ neg_gen = reg & PCI_EXP_LNKSTA_CLS; + + return neg_gen; + } +@@ -356,13 +351,14 @@ static void advk_pcie_setup_hw(struct ad + PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV; + advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); + +- /* Set PCIe Device Control and Status 1 PF0 register */ +- reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | +- (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | +- PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | +- (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << +- PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); +- advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); ++ /* Set PCIe Device Control register */ ++ reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); ++ reg &= ~PCI_EXP_DEVCTL_RELAX_EN; ++ reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; ++ reg &= ~PCI_EXP_DEVCTL_READRQ; ++ reg |= PCI_EXP_DEVCTL_PAYLOAD; /* Set max payload size */ ++ reg |= PCI_EXP_DEVCTL_READRQ_512B; ++ advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + + /* Program PCIe Control 2 to disable strict ordering */ + reg = PCIE_CORE_CTRL2_RESERVED | diff --git a/queue-4.19/pci-aardvark-train-link-immediately-after-enabling-training.patch b/queue-4.19/pci-aardvark-train-link-immediately-after-enabling-training.patch new file mode 100644 index 00000000000..f045b8b9e38 --- /dev/null +++ b/queue-4.19/pci-aardvark-train-link-immediately-after-enabling-training.patch @@ -0,0 +1,66 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:43 +0100 +Subject: PCI: aardvark: Train link immediately after enabling training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Rob Herring" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211124230500.27109-4-kabel@kernel.org> + +From: Pali Rohár + +commit 6964494582f56a3882c2c53b0edbfe99eb32b2e1 upstream. + +Adding even 100ms (PCI_PM_D3COLD_WAIT) delay between enabling link +training and starting link training causes detection issues with some +buggy cards (such as Compex WLE900VX). + +Move the code which enables link training immediately before the one +which starts link traning. + +This fixes detection issues of Compex WLE900VX card on Turris MOX after +cold boot. + +Link: https://lore.kernel.org/r/20200430080625.26070-2-pali@kernel.org +Fixes: f4c7d053d7f7 ("PCI: aardvark: Wait for endpoint to be ready...") +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Acked-by: Rob Herring +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -280,11 +280,6 @@ static void advk_pcie_setup_hw(struct ad + reg |= LANE_COUNT_1; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + +- /* Enable link training */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg |= LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- + /* Enable MSI */ + reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); + reg |= PCIE_CORE_CTRL2_MSI_ENABLE; +@@ -326,7 +321,15 @@ static void advk_pcie_setup_hw(struct ad + */ + msleep(PCI_PM_D3COLD_WAIT); + +- /* Start link training */ ++ /* Enable link training */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg |= LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* ++ * Start link training immediately after enabling it. ++ * This solves problems for some buggy cards. ++ */ + reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); + reg |= PCIE_CORE_LINK_TRAINING; + advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); diff --git a/queue-4.19/pci-aardvark-update-comment-about-disabling-link-training.patch b/queue-4.19/pci-aardvark-update-comment-about-disabling-link-training.patch new file mode 100644 index 00000000000..9d513ab3934 --- /dev/null +++ b/queue-4.19/pci-aardvark-update-comment-about-disabling-link-training.patch @@ -0,0 +1,45 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:51 +0100 +Subject: PCI: aardvark: Update comment about disabling link training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211124230500.27109-12-kabel@kernel.org> + +From: Pali Rohár + +commit 1d1cd163d0de22a4041a6f1aeabcf78f80076539 upstream. + +According to PCI Express Base Specifications (rev 4.0, 6.6.1 +"Conventional reset"), after fundamental reset a 100ms delay is needed +prior to enabling link training. + +Update comment in code to reflect this requirement. + +Link: https://lore.kernel.org/r/20201202184659.3795-1-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -236,7 +236,14 @@ static void advk_pcie_issue_perst(struct + if (!pcie->reset_gpio) + return; + +- /* PERST does not work for some cards when link training is enabled */ ++ /* ++ * As required by PCI Express spec (PCI Express Base Specification, REV. ++ * 4.0 PCI Express, February 19 2014, 6.6.1 Conventional Reset) a delay ++ * for at least 100ms after de-asserting PERST# signal is needed before ++ * link training is enabled. So ensure that link training is disabled ++ * prior de-asserting PERST# signal to fulfill that PCI Express spec ++ * requirement. ++ */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~LINK_TRAINING_EN; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); diff --git a/queue-4.19/pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch b/queue-4.19/pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch new file mode 100644 index 00000000000..b7d9515ab52 --- /dev/null +++ b/queue-4.19/pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch @@ -0,0 +1,58 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:42 +0100 +Subject: PCI: aardvark: Wait for endpoint to be ready before training link +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Remi Pommarel" , "Lorenzo Pieralisi" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211124230500.27109-3-kabel@kernel.org> + +From: Remi Pommarel + +commit f4c7d053d7f77cd5c1a1ba7c7ce085ddba13d1d7 upstream. + +When configuring pcie reset pin from gpio (e.g. initially set by +u-boot) to pcie function this pin goes low for a brief moment +asserting the PERST# signal. Thus connected device enters fundamental +reset process and link configuration can only begin after a minimal +100ms delay (see [1]). + +Because the pin configuration comes from the "default" pinctrl it is +implicitly configured before the probe callback is called: + +driver_probe_device() + really_probe() + ... + pinctrl_bind_pins() /* Here pin goes from gpio to PCIE reset + function and PERST# is asserted */ + ... + drv->probe() + +[1] "PCI Express Base Specification", REV. 4.0 + PCI Express, February 19 2014, 6.6.1 Conventional Reset + +Signed-off-by: Remi Pommarel +Signed-off-by: Lorenzo Pieralisi +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -318,6 +318,14 @@ static void advk_pcie_setup_hw(struct ad + reg |= PIO_CTRL_ADDR_WIN_DISABLE; + advk_writel(pcie, reg, PIO_CTRL); + ++ /* ++ * PERST# signal could have been asserted by pinctrl subsystem before ++ * probe() callback has been called, making the endpoint going into ++ * fundamental reset. As required by PCI Express spec a delay for at ++ * least 100ms after such a reset before link training is needed. ++ */ ++ msleep(PCI_PM_D3COLD_WAIT); ++ + /* Start link training */ + reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); + reg |= PCIE_CORE_LINK_TRAINING; diff --git a/queue-4.19/pinctrl-armada-37xx-add-missing-pin-pcie1-wakeup.patch b/queue-4.19/pinctrl-armada-37xx-add-missing-pin-pcie1-wakeup.patch new file mode 100644 index 00000000000..9b8c1eef98c --- /dev/null +++ b/queue-4.19/pinctrl-armada-37xx-add-missing-pin-pcie1-wakeup.patch @@ -0,0 +1,33 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:57 +0100 +Subject: pinctrl: armada-37xx: add missing pin: PCIe1 Wakeup +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Gregory CLEMENT" , "Miquel Raynal" , "Linus Walleij" , "Marek Behún" +Message-ID: <20211124230500.27109-18-kabel@kernel.org> + +From: Gregory CLEMENT + +commit 4d98fbaacd79a82f408febb66a9c42fe42361b16 upstream. + +Declare the PCIe1 Wakeup which was initially missing. + +Signed-off-by: Gregory CLEMENT +Tested-by: Miquel Raynal +Signed-off-by: Linus Walleij +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -198,6 +198,7 @@ static struct armada_37xx_pin_group arma + PIN_GRP_GPIO("smi", 18, 2, BIT(4), "smi"), + PIN_GRP_GPIO("pcie1", 3, 1, BIT(5), "pcie"), + PIN_GRP_GPIO("pcie1_clkreq", 4, 1, BIT(9), "pcie"), ++ PIN_GRP_GPIO("pcie1_wakeup", 5, 1, BIT(10), "pcie"), + PIN_GRP_GPIO("ptp", 20, 3, BIT(11) | BIT(12) | BIT(13), "ptp"), + PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"), + PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"), diff --git a/queue-4.19/pinctrl-armada-37xx-correct-mpp-definitions.patch b/queue-4.19/pinctrl-armada-37xx-correct-mpp-definitions.patch new file mode 100644 index 00000000000..e7b5e111ab5 --- /dev/null +++ b/queue-4.19/pinctrl-armada-37xx-correct-mpp-definitions.patch @@ -0,0 +1,108 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:56 +0100 +Subject: pinctrl: armada-37xx: Correct mpp definitions +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Gregory CLEMENT" , "Miquel Raynal" , "Linus Walleij" , "Marek Behún" +Message-ID: <20211124230500.27109-17-kabel@kernel.org> + +From: Marek Behún + +commit 823868fceae3bac07cf5eccb128d6916e7a5ae9d upstream. + +This is a cleanup and fix of the patch by Ken Ma . + +Fix the mpp definitions according to newest revision of the +specification: + - northbridge: + fix pmic1 gpio number to 7 + fix pmic0 gpio number to 6 + - southbridge + split pcie1 group bit mask to BIT(5) and BIT(9) + fix ptp group bit mask to BIT(11) | BIT(12) | BIT(13) + add smi group with bit mask BIT(4) + +[gregory: split the pcie group in 2, as at hardware level they can be +configured separately] +Signed-off-by: Marek Behún +Signed-off-by: Gregory CLEMENT +Tested-by: Miquel Raynal +Signed-off-by: Linus Walleij +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt | 18 +++++++--- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 10 +++-- + 2 files changed, 19 insertions(+), 9 deletions(-) + +--- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt ++++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +@@ -58,11 +58,11 @@ group pwm3 + - functions pwm, gpio + + group pmic1 +- - pin 17 ++ - pin 7 + - functions pmic, gpio + + group pmic0 +- - pin 16 ++ - pin 6 + - functions pmic, gpio + + group i2c2 +@@ -112,17 +112,25 @@ group usb2_drvvbus1 + - functions drvbus, gpio + + group sdio_sb +- - pins 60-64 ++ - pins 60-65 + - functions sdio, gpio + + group rgmii +- - pins 42-55 ++ - pins 42-53 + - functions mii, gpio + + group pcie1 +- - pins 39-40 ++ - pins 39 ++ - functions pcie, gpio ++ ++group pcie1_clkreq ++ - pins 40 + - functions pcie, gpio + ++group smi ++ - pins 54-55 ++ - functions smi, gpio ++ + group ptp + - pins 56-58 + - functions ptp, gpio +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -170,8 +170,8 @@ static struct armada_37xx_pin_group arma + PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"), + PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"), + PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"), +- PIN_GRP_GPIO("pmic1", 17, 1, BIT(7), "pmic"), +- PIN_GRP_GPIO("pmic0", 16, 1, BIT(8), "pmic"), ++ PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), ++ PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), + PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), + PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"), + PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"), +@@ -195,8 +195,10 @@ static struct armada_37xx_pin_group arma + PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"), + PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"), + PIN_GRP_GPIO("rgmii", 6, 12, BIT(3), "mii"), +- PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"), +- PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"), ++ PIN_GRP_GPIO("smi", 18, 2, BIT(4), "smi"), ++ PIN_GRP_GPIO("pcie1", 3, 1, BIT(5), "pcie"), ++ PIN_GRP_GPIO("pcie1_clkreq", 4, 1, BIT(9), "pcie"), ++ PIN_GRP_GPIO("ptp", 20, 3, BIT(11) | BIT(12) | BIT(13), "ptp"), + PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"), + PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"), + PIN_GRP_GPIO_3("mii_col", 23, 1, BIT(8) | BIT(14), 0, BIT(8), BIT(14), diff --git a/queue-4.19/pinctrl-armada-37xx-correct-pwm-pins-definitions.patch b/queue-4.19/pinctrl-armada-37xx-correct-pwm-pins-definitions.patch new file mode 100644 index 00000000000..061eaf5b2ed --- /dev/null +++ b/queue-4.19/pinctrl-armada-37xx-correct-pwm-pins-definitions.patch @@ -0,0 +1,101 @@ +From foo@baz Sun Nov 28 02:10:56 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 00:04:58 +0100 +Subject: pinctrl: armada-37xx: Correct PWM pins definitions +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Rob Herring" , "Linus Walleij" +Message-ID: <20211124230500.27109-19-kabel@kernel.org> + +From: "Marek Behún" + +commit baf8d6899b1e8906dc076ef26cc633e96a8bb0c3 upstream. + +The PWM pins on North Bridge on Armada 37xx can be configured into PWM +or GPIO functions. When in PWM function, each pin can also be configured +to drive low on 0 and tri-state on 1 (LED mode). + +The current definitions handle this by declaring two pin groups for each +pin: +- group "pwmN" with functions "pwm" and "gpio" +- group "ledN_od" ("od" for open drain) with functions "led" and "gpio" + +This is semantically incorrect. The correct definition for each pin +should be one group with three functions: "pwm", "led" and "gpio". + +Change the "pwmN" groups to support "led" function. + +Remove "ledN_od" groups. This cannot break backwards compatibility with +older device trees: no device tree uses it since there is no PWM driver +for this SOC yet. Also "ledN_od" groups are not even documented. + +Fixes: b835d6953009 ("pinctrl: armada-37xx: swap polarity on LED group") +Signed-off-by: Marek Behún +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20210719112938.27594-1-kabel@kernel.org +Signed-off-by: Linus Walleij +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt | 8 ++-- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 17 ++++------ + 2 files changed, 12 insertions(+), 13 deletions(-) + +--- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt ++++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +@@ -43,19 +43,19 @@ group emmc_nb + + group pwm0 + - pin 11 (GPIO1-11) +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pwm1 + - pin 12 +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pwm2 + - pin 13 +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pwm3 + - pin 14 +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pmic1 + - pin 7 +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -166,10 +166,14 @@ static struct armada_37xx_pin_group arma + PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"), + PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"), + PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"), +- PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"), +- PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"), +- PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"), +- PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"), ++ PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3), ++ "pwm", "led"), ++ PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4), ++ "pwm", "led"), ++ PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5), ++ "pwm", "led"), ++ PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6), ++ "pwm", "led"), + PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), + PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), + PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), +@@ -183,11 +187,6 @@ static struct armada_37xx_pin_group arma + PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19), + BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19), + 18, 2, "gpio", "uart"), +- PIN_GRP_GPIO_2("led0_od", 11, 1, BIT(20), BIT(20), 0, "led"), +- PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), +- PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), +- PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), +- + }; + + static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { diff --git a/queue-4.19/proc-vmcore-fix-clearing-user-buffer-by-properly-using-clear_user.patch b/queue-4.19/proc-vmcore-fix-clearing-user-buffer-by-properly-using-clear_user.patch new file mode 100644 index 00000000000..93270488e66 --- /dev/null +++ b/queue-4.19/proc-vmcore-fix-clearing-user-buffer-by-properly-using-clear_user.patch @@ -0,0 +1,98 @@ +From c1e63117711977cc4295b2ce73de29dd17066c82 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 19 Nov 2021 16:43:58 -0800 +Subject: proc/vmcore: fix clearing user buffer by properly using clear_user() + +From: David Hildenbrand + +commit c1e63117711977cc4295b2ce73de29dd17066c82 upstream. + +To clear a user buffer we cannot simply use memset, we have to use +clear_user(). With a virtio-mem device that registers a vmcore_cb and +has some logically unplugged memory inside an added Linux memory block, +I can easily trigger a BUG by copying the vmcore via "cp": + + systemd[1]: Starting Kdump Vmcore Save Service... + kdump[420]: Kdump is using the default log level(3). + kdump[453]: saving to /sysroot/var/crash/127.0.0.1-2021-11-11-14:59:22/ + kdump[458]: saving vmcore-dmesg.txt to /sysroot/var/crash/127.0.0.1-2021-11-11-14:59:22/ + kdump[465]: saving vmcore-dmesg.txt complete + kdump[467]: saving vmcore + BUG: unable to handle page fault for address: 00007f2374e01000 + #PF: supervisor write access in kernel mode + #PF: error_code(0x0003) - permissions violation + PGD 7a523067 P4D 7a523067 PUD 7a528067 PMD 7a525067 PTE 800000007048f867 + Oops: 0003 [#1] PREEMPT SMP NOPTI + CPU: 0 PID: 468 Comm: cp Not tainted 5.15.0+ #6 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-27-g64f37cc530f1-prebuilt.qemu.org 04/01/2014 + RIP: 0010:read_from_oldmem.part.0.cold+0x1d/0x86 + Code: ff ff ff e8 05 ff fe ff e9 b9 e9 7f ff 48 89 de 48 c7 c7 38 3b 60 82 e8 f1 fe fe ff 83 fd 08 72 3c 49 8d 7d 08 4c 89 e9 89 e8 <49> c7 45 00 00 00 00 00 49 c7 44 05 f8 00 00 00 00 48 83 e7 f81 + RSP: 0018:ffffc9000073be08 EFLAGS: 00010212 + RAX: 0000000000001000 RBX: 00000000002fd000 RCX: 00007f2374e01000 + RDX: 0000000000000001 RSI: 00000000ffffdfff RDI: 00007f2374e01008 + RBP: 0000000000001000 R08: 0000000000000000 R09: ffffc9000073bc50 + R10: ffffc9000073bc48 R11: ffffffff829461a8 R12: 000000000000f000 + R13: 00007f2374e01000 R14: 0000000000000000 R15: ffff88807bd421e8 + FS: 00007f2374e12140(0000) GS:ffff88807f000000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007f2374e01000 CR3: 000000007a4aa000 CR4: 0000000000350eb0 + Call Trace: + read_vmcore+0x236/0x2c0 + proc_reg_read+0x55/0xa0 + vfs_read+0x95/0x190 + ksys_read+0x4f/0xc0 + do_syscall_64+0x3b/0x90 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +Some x86-64 CPUs have a CPU feature called "Supervisor Mode Access +Prevention (SMAP)", which is used to detect wrong access from the kernel +to user buffers like this: SMAP triggers a permissions violation on +wrong access. In the x86-64 variant of clear_user(), SMAP is properly +handled via clac()+stac(). + +To fix, properly use clear_user() when we're dealing with a user buffer. + +Link: https://lkml.kernel.org/r/20211112092750.6921-1-david@redhat.com +Fixes: 997c136f518c ("fs/proc/vmcore.c: add hook to read_from_oldmem() to check for non-ram pages") +Signed-off-by: David Hildenbrand +Acked-by: Baoquan He +Cc: Dave Young +Cc: Baoquan He +Cc: Vivek Goyal +Cc: Philipp Rudo +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: David Hildenbrand +Signed-off-by: Greg Kroah-Hartman +--- + fs/proc/vmcore.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/fs/proc/vmcore.c ++++ b/fs/proc/vmcore.c +@@ -117,14 +117,19 @@ static ssize_t read_from_oldmem(char *bu + nr_bytes = count; + + /* If pfn is not ram, return zeros for sparse dump files */ +- if (pfn_is_ram(pfn) == 0) +- memset(buf, 0, nr_bytes); +- else { ++ if (pfn_is_ram(pfn) == 0) { ++ tmp = 0; ++ if (!userbuf) ++ memset(buf, 0, nr_bytes); ++ else if (clear_user(buf, nr_bytes)) ++ tmp = -EFAULT; ++ } else { + tmp = copy_oldmem_page(pfn, buf, nr_bytes, + offset, userbuf); +- if (tmp < 0) +- return tmp; + } ++ if (tmp < 0) ++ return tmp; ++ + *ppos += nr_bytes; + count -= nr_bytes; + buf += nr_bytes; diff --git a/queue-4.19/series b/queue-4.19/series index b39349d43e0..2f56cab18b3 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -12,3 +12,25 @@ fuse-fix-page-stealing.patch xen-don-t-continue-xenstore-initialization-in-case-of-errors.patch xen-detect-uninitialized-xenbus-in-xenbus_init.patch tracing-fix-pid-filtering-when-triggers-are-attached.patch +xtensa-use-config_use_of-instead-of-config_of.patch +proc-vmcore-fix-clearing-user-buffer-by-properly-using-clear_user.patch +pci-aardvark-fix-a-leaked-reference-by-adding-missing-of_node_put.patch +pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch +pci-aardvark-train-link-immediately-after-enabling-training.patch +pci-aardvark-improve-link-training.patch +pci-aardvark-issue-perst-via-gpio.patch +pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch +pci-aardvark-indicate-error-in-val-when-config-read-fails.patch +pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch +pci-aardvark-fix-compilation-on-s390.patch +pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch +pci-aardvark-update-comment-about-disabling-link-training.patch +pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch +pci-aardvark-fix-pcie-max-payload-size-setting.patch +pci-aardvark-fix-link-training.patch +pci-aardvark-fix-checking-for-link-up-via-ltssm-state.patch +pinctrl-armada-37xx-correct-mpp-definitions.patch +pinctrl-armada-37xx-add-missing-pin-pcie1-wakeup.patch +pinctrl-armada-37xx-correct-pwm-pins-definitions.patch +arm64-dts-marvell-armada-37xx-declare-pcie-reset-pin.patch +arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch diff --git a/queue-4.19/xtensa-use-config_use_of-instead-of-config_of.patch b/queue-4.19/xtensa-use-config_use_of-instead-of-config_of.patch new file mode 100644 index 00000000000..9acae80e07f --- /dev/null +++ b/queue-4.19/xtensa-use-config_use_of-instead-of-config_of.patch @@ -0,0 +1,115 @@ +From d67ed2510d28a1eb33171010d35cf52178cfcbdd Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Fri, 24 Sep 2021 20:29:51 -0700 +Subject: xtensa: use CONFIG_USE_OF instead of CONFIG_OF +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Randy Dunlap + +commit d67ed2510d28a1eb33171010d35cf52178cfcbdd upstream. + +CONFIG_OF can be set by a randconfig or by a user -- without setting the +early flattree option (OF_EARLY_FLATTREE). This causes build errors. +However, if randconfig or a user sets USE_OF in the Xtensa config, +the right kconfig symbols are set to fix the build. + +Fixes these build errors: + +../arch/xtensa/kernel/setup.c:67:19: error: ‘__dtb_start’ undeclared here (not in a function); did you mean ‘dtb_start’? + 67 | void *dtb_start = __dtb_start; + | ^~~~~~~~~~~ +../arch/xtensa/kernel/setup.c: In function 'xtensa_dt_io_area': +../arch/xtensa/kernel/setup.c:201:14: error: implicit declaration of function 'of_flat_dt_is_compatible'; did you mean 'of_machine_is_compatible'? [-Werror=implicit-function-declaration] + 201 | if (!of_flat_dt_is_compatible(node, "simple-bus")) +../arch/xtensa/kernel/setup.c:204:18: error: implicit declaration of function 'of_get_flat_dt_prop' [-Werror=implicit-function-declaration] + 204 | ranges = of_get_flat_dt_prop(node, "ranges", &len); +../arch/xtensa/kernel/setup.c:204:16: error: assignment to 'const __be32 *' {aka 'const unsigned int *'} from 'int' makes pointer from integer without a cast [-Werror=int-conversion] + 204 | ranges = of_get_flat_dt_prop(node, "ranges", &len); + | ^ +../arch/xtensa/kernel/setup.c: In function 'early_init_devtree': +../arch/xtensa/kernel/setup.c:228:9: error: implicit declaration of function 'early_init_dt_scan'; did you mean 'early_init_devtree'? [-Werror=implicit-function-declaration] + 228 | early_init_dt_scan(params); +../arch/xtensa/kernel/setup.c:229:9: error: implicit declaration of function 'of_scan_flat_dt' [-Werror=implicit-function-declaration] + 229 | of_scan_flat_dt(xtensa_dt_io_area, NULL); + +xtensa-elf-ld: arch/xtensa/mm/mmu.o:(.text+0x0): undefined reference to `xtensa_kio_paddr' + +Fixes: da844a81779e ("xtensa: add device trees support") +Fixes: 6cb971114f63 ("xtensa: remap io area defined in device tree") +Signed-off-by: Randy Dunlap +Signed-off-by: Max Filippov +Signed-off-by: Greg Kroah-Hartman +--- + arch/xtensa/kernel/setup.c | 12 ++++++------ + arch/xtensa/mm/mmu.c | 2 +- + 2 files changed, 7 insertions(+), 7 deletions(-) + +--- a/arch/xtensa/kernel/setup.c ++++ b/arch/xtensa/kernel/setup.c +@@ -65,7 +65,7 @@ int initrd_is_mapped = 0; + extern int initrd_below_start_ok; + #endif + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + void *dtb_start = __dtb_start; + #endif + +@@ -127,7 +127,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_init + + #endif /* CONFIG_BLK_DEV_INITRD */ + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + + static int __init parse_tag_fdt(const bp_tag_t *tag) + { +@@ -137,7 +137,7 @@ static int __init parse_tag_fdt(const bp + + __tagtable(BP_TAG_FDT, parse_tag_fdt); + +-#endif /* CONFIG_OF */ ++#endif /* CONFIG_USE_OF */ + + static int __init parse_tag_cmdline(const bp_tag_t* tag) + { +@@ -185,7 +185,7 @@ static int __init parse_bootparam(const + } + #endif + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + + #if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY + unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR; +@@ -234,7 +234,7 @@ void __init early_init_devtree(void *par + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); + } + +-#endif /* CONFIG_OF */ ++#endif /* CONFIG_USE_OF */ + + /* + * Initialize architecture. (Early stage) +@@ -255,7 +255,7 @@ void __init init_arch(bp_tag_t *bp_start + if (bp_start) + parse_bootparam(bp_start); + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + early_init_devtree(dtb_start); + #endif + +--- a/arch/xtensa/mm/mmu.c ++++ b/arch/xtensa/mm/mmu.c +@@ -98,7 +98,7 @@ void init_mmu(void) + + void init_kio(void) + { +-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) ++#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_USE_OF) + /* + * Update the IO area mapping in case xtensa_kio_paddr has changed + */