Skip to content

Commit 6646e99

Browse files
Vidya Sagarbjorn-helgaas
authored andcommitted
PCI: tegra194: Fix Root Port interrupt handling
As part of Root Port interrupt handling, level-0 register is read first and based on the bits set in that, corresponding level-1 registers are read for further interrupt processing. Since both these values are currently read into the same 'val' variable, checking level-0 bits the second time around is happening on the 'val' variable value of level-1 register contents instead of freshly reading the level-0 value again. Fix by using different variables to store level-0 and level-1 registers contents. Link: https://lore.kernel.org/r/20220721142052.25971-11-vidyas@nvidia.com Fixes: 56e15a2 ("PCI: tegra: Add Tegra194 PCIe support") Signed-off-by: Vidya Sagar <vidyas@nvidia.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
1 parent 997b99e commit 6646e99

1 file changed

Lines changed: 22 additions & 24 deletions

File tree

drivers/pci/controller/dwc/pcie-tegra194.c

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -338,15 +338,14 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
338338
struct tegra_pcie_dw *pcie = arg;
339339
struct dw_pcie *pci = &pcie->pci;
340340
struct pcie_port *pp = &pci->pp;
341-
u32 val, tmp;
341+
u32 val, status_l0, status_l1;
342342
u16 val_w;
343343

344-
val = appl_readl(pcie, APPL_INTR_STATUS_L0);
345-
if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
346-
val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
347-
if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
348-
appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
349-
344+
status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0);
345+
if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
346+
status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
347+
appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0);
348+
if (status_l1 & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
350349
/* SBR & Surprise Link Down WAR */
351350
val = appl_readl(pcie, APPL_CAR_RESET_OVRD);
352351
val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;
@@ -362,15 +361,15 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
362361
}
363362
}
364363

365-
if (val & APPL_INTR_STATUS_L0_INT_INT) {
366-
val = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0);
367-
if (val & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) {
364+
if (status_l0 & APPL_INTR_STATUS_L0_INT_INT) {
365+
status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0);
366+
if (status_l1 & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) {
368367
appl_writel(pcie,
369368
APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS,
370369
APPL_INTR_STATUS_L1_8_0);
371370
apply_bad_link_workaround(pp);
372371
}
373-
if (val & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) {
372+
if (status_l1 & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) {
374373
appl_writel(pcie,
375374
APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS,
376375
APPL_INTR_STATUS_L1_8_0);
@@ -382,25 +381,24 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
382381
}
383382
}
384383

385-
val = appl_readl(pcie, APPL_INTR_STATUS_L0);
386-
if (val & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) {
387-
val = appl_readl(pcie, APPL_INTR_STATUS_L1_18);
388-
tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
389-
if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) {
384+
if (status_l0 & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) {
385+
status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_18);
386+
val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
387+
if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) {
390388
dev_info(pci->dev, "CDM check complete\n");
391-
tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE;
389+
val |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE;
392390
}
393-
if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) {
391+
if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) {
394392
dev_err(pci->dev, "CDM comparison mismatch\n");
395-
tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR;
393+
val |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR;
396394
}
397-
if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) {
395+
if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) {
398396
dev_err(pci->dev, "CDM Logic error\n");
399-
tmp |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR;
397+
val |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR;
400398
}
401-
dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, tmp);
402-
tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR);
403-
dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", tmp);
399+
dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
400+
val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR);
401+
dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", val);
404402
}
405403

406404
return IRQ_HANDLED;

0 commit comments

Comments
 (0)