Commit 4a4547db authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/tegra194'

- Fix handling BME_CHGED event (Om Prakash Singh)

- Fix MSI-X programming (Om Prakash Singh)

- Disable interrupts before entering L2 (Om Prakash Singh)

- Don't allow suspend when Tegra PCIe is in EP mode (Om Prakash Singh)

* remotes/lorenzo/pci/tegra194:
  PCI: tegra194: Cleanup unused code
  PCI: tegra194: Don't allow suspend when Tegra PCIe is in EP mode
  PCI: tegra194: Disable interrupts before entering L2
  PCI: tegra194: Fix MSI-X programming
  PCI: tegra194: Fix handling BME_CHGED event
parents db2d64f8 f62750e6
Loading
Loading
Loading
Loading
+31 −23
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;
@@ -1493,6 +1493,16 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
		return;
	}

	/*
	 * PCIe controller exits from L2 only if reset is applied, so
	 * controller doesn't handle interrupts. But in cases where
	 * L2 entry fails, PERST# is asserted which can trigger surprise
	 * link down AER. However this function call happens in
	 * suspend_noirq(), so AER interrupt will not be processed.
	 * Disable all interrupts to avoid such a scenario.
	 */
	appl_writel(pcie, 0x0, APPL_INTR_EN_L0_0);

	if (tegra_pcie_try_link_l2(pcie)) {
		dev_info(pcie->dev, "Link didn't transition to L2 state\n");
		/*
@@ -1763,7 +1773,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
	val = (ep->msi_mem_phys & MSIX_ADDR_MATCH_LOW_OFF_MASK);
	val |= MSIX_ADDR_MATCH_LOW_OFF_EN;
	dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_LOW_OFF, val);
	val = (lower_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
	val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
	dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val);

	ret = dw_pcie_ep_init_complete(ep);
@@ -1935,13 +1945,6 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
		return ret;
	}

	name = devm_kasprintf(dev, GFP_KERNEL, "tegra_pcie_%u_ep_work",
			      pcie->cid);
	if (!name) {
		dev_err(dev, "Failed to create PCIe EP work thread string\n");
		return -ENOMEM;
	}

	pm_runtime_enable(dev);

	ret = dw_pcie_ep_init(ep);
@@ -2236,6 +2239,11 @@ static int tegra_pcie_dw_resume_early(struct device *dev)
	struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
	u32 val;

	if (pcie->mode == DW_PCIE_EP_TYPE) {
		dev_err(dev, "Suspend is not supported in EP mode");
		return -ENOTSUPP;
	}

	if (!pcie->link_state)
		return 0;