aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-5.4/002-PCI-aardvark-Don-t-rely-on-jiffies-while-holding-spi.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-5.4/002-PCI-aardvark-Don-t-rely-on-jiffies-while-holding-spi.patch')
-rw-r--r--target/linux/mvebu/patches-5.4/002-PCI-aardvark-Don-t-rely-on-jiffies-while-holding-spi.patch54
1 files changed, 54 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-5.4/002-PCI-aardvark-Don-t-rely-on-jiffies-while-holding-spi.patch b/target/linux/mvebu/patches-5.4/002-PCI-aardvark-Don-t-rely-on-jiffies-while-holding-spi.patch
new file mode 100644
index 0000000000..db4afd22a2
--- /dev/null
+++ b/target/linux/mvebu/patches-5.4/002-PCI-aardvark-Don-t-rely-on-jiffies-while-holding-spi.patch
@@ -0,0 +1,54 @@
+From 7fbcb5da811be7d47468417c7795405058abb3da Mon Sep 17 00:00:00 2001
+From: Remi Pommarel <repk@triplefau.lt>
+Date: Fri, 27 Sep 2019 10:55:02 +0200
+Subject: [PATCH] PCI: aardvark: Don't rely on jiffies while holding spinlock
+
+advk_pcie_wait_pio() can be called while holding a spinlock (from
+pci_bus_read_config_dword()), then depends on jiffies in order to
+timeout while polling on PIO state registers. In the case the PIO
+transaction failed, the timeout will never happen and will also cause
+the cpu to stall.
+
+This decrements a variable and wait instead of using jiffies.
+
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Andrew Murray <andrew.murray@arm.com>
+Acked-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+---
+ drivers/pci/controller/pci-aardvark.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -175,7 +175,8 @@
+ (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn)) | \
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where))
+
+-#define PIO_TIMEOUT_MS 1
++#define PIO_RETRY_CNT 500
++#define PIO_RETRY_DELAY 2 /* 2 us*/
+
+ #define LINK_WAIT_MAX_RETRIES 10
+ #define LINK_WAIT_USLEEP_MIN 90000
+@@ -400,17 +401,16 @@ static void advk_pcie_check_pio_status(s
+ static int advk_pcie_wait_pio(struct advk_pcie *pcie)
+ {
+ struct device *dev = &pcie->pdev->dev;
+- unsigned long timeout;
++ int i;
+
+- timeout = jiffies + msecs_to_jiffies(PIO_TIMEOUT_MS);
+-
+- while (time_before(jiffies, timeout)) {
++ for (i = 0; i < PIO_RETRY_CNT; i++) {
+ u32 start, isr;
+
+ start = advk_readl(pcie, PIO_START);
+ isr = advk_readl(pcie, PIO_ISR);
+ if (!start && isr)
+ return 0;
++ udelay(PIO_RETRY_DELAY);
+ }
+
+ dev_err(dev, "config read/write timed out\n");