Commit 7fbcb5da authored by Remi Pommarel's avatar Remi Pommarel Committed by Lorenzo Pieralisi

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: default avatarRemi Pommarel <repk@triplefau.lt>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: default avatarAndrew Murray <andrew.murray@arm.com>
Acked-by: default avatarThomas Petazzoni <thomas.petazzoni@bootlin.com>
parent c0f05a6a
......@@ -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
......@@ -404,17 +405,16 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie)
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");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment