Commit ceb1412c authored by Om Prakash Singh's avatar Om Prakash Singh Committed by Lorenzo Pieralisi
Browse files

PCI: tegra194: Fix handling BME_CHGED event

In tegra_pcie_ep_hard_irq(), APPL_INTR_STATUS_L0 is stored in val and again
APPL_INTR_STATUS_L1_0_0 is also stored in val. So when execution reaches
"if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT)", val is not correct.

Link: https://lore.kernel.org/r/20210623100525.19944-2-omp@nvidia.com


Signed-off-by: default avatarOm Prakash Singh <omp@nvidia.com>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarVidya Sagar <vidyas@nvidia.com>
parent e73f0f0e
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -497,19 +497,19 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
	struct tegra_pcie_dw *pcie = arg;
	struct dw_pcie_ep *ep = &pcie->pci.ep;
	int spurious = 1;
	u32 val, tmp;
	u32 status_l0, status_l1, link_status;

	val = appl_readl(pcie, APPL_INTR_STATUS_L0);
	if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
		val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
		appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
	status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0);
	if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
		status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
		appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0);

		if (val & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE)
		if (status_l1 & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE)
			pex_ep_event_hot_rst_done(pcie);

		if (val & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) {
			tmp = appl_readl(pcie, APPL_LINK_STATUS);
			if (tmp & APPL_LINK_STATUS_RDLH_LINK_UP) {
		if (status_l1 & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) {
			link_status = appl_readl(pcie, APPL_LINK_STATUS);
			if (link_status & APPL_LINK_STATUS_RDLH_LINK_UP) {
				dev_dbg(pcie->dev, "Link is up with Host\n");
				dw_pcie_ep_linkup(ep);
			}
@@ -518,11 +518,11 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
		spurious = 0;
	}

	if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) {
		val = appl_readl(pcie, APPL_INTR_STATUS_L1_15);
		appl_writel(pcie, val, APPL_INTR_STATUS_L1_15);
	if (status_l0 & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) {
		status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_15);
		appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_15);

		if (val & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED)
		if (status_l1 & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED)
			return IRQ_WAKE_THREAD;

		spurious = 0;
@@ -530,8 +530,8 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)

	if (spurious) {
		dev_warn(pcie->dev, "Random interrupt (STATUS = 0x%08X)\n",
			 val);
		appl_writel(pcie, val, APPL_INTR_STATUS_L0);
			 status_l0);
		appl_writel(pcie, status_l0, APPL_INTR_STATUS_L0);
	}

	return IRQ_HANDLED;