Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+31 -23
+31 -23
drivers/pci/controller/dwc/pcie-tegra194.c
··· 497 497 struct tegra_pcie_dw *pcie = arg; 498 498 struct dw_pcie_ep *ep = &pcie->pci.ep; 499 499 int spurious = 1; 500 - u32 val, tmp; 500 + u32 status_l0, status_l1, link_status; 501 501 502 - val = appl_readl(pcie, APPL_INTR_STATUS_L0); 503 - if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) { 504 - val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); 505 - appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0); 502 + status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0); 503 + if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) { 504 + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); 505 + appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0); 506 506 507 - if (val & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE) 507 + if (status_l1 & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE) 508 508 pex_ep_event_hot_rst_done(pcie); 509 509 510 - if (val & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) { 511 - tmp = appl_readl(pcie, APPL_LINK_STATUS); 512 - if (tmp & APPL_LINK_STATUS_RDLH_LINK_UP) { 510 + if (status_l1 & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) { 511 + link_status = appl_readl(pcie, APPL_LINK_STATUS); 512 + if (link_status & APPL_LINK_STATUS_RDLH_LINK_UP) { 513 513 dev_dbg(pcie->dev, "Link is up with Host\n"); 514 514 dw_pcie_ep_linkup(ep); 515 515 } ··· 518 518 spurious = 0; 519 519 } 520 520 521 - if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) { 522 - val = appl_readl(pcie, APPL_INTR_STATUS_L1_15); 523 - appl_writel(pcie, val, APPL_INTR_STATUS_L1_15); 521 + if (status_l0 & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) { 522 + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_15); 523 + appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_15); 524 524 525 - if (val & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED) 525 + if (status_l1 & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED) 526 526 return IRQ_WAKE_THREAD; 527 527 528 528 spurious = 0; ··· 530 530 531 531 if (spurious) { 532 532 dev_warn(pcie->dev, "Random interrupt (STATUS = 0x%08X)\n", 533 - val); 534 - appl_writel(pcie, val, APPL_INTR_STATUS_L0); 533 + status_l0); 534 + appl_writel(pcie, status_l0, APPL_INTR_STATUS_L0); 535 535 } 536 536 537 537 return IRQ_HANDLED; ··· 1493 1493 return; 1494 1494 } 1495 1495 1496 + /* 1497 + * PCIe controller exits from L2 only if reset is applied, so 1498 + * controller doesn't handle interrupts. But in cases where 1499 + * L2 entry fails, PERST# is asserted which can trigger surprise 1500 + * link down AER. However this function call happens in 1501 + * suspend_noirq(), so AER interrupt will not be processed. 1502 + * Disable all interrupts to avoid such a scenario. 1503 + */ 1504 + appl_writel(pcie, 0x0, APPL_INTR_EN_L0_0); 1505 + 1496 1506 if (tegra_pcie_try_link_l2(pcie)) { 1497 1507 dev_info(pcie->dev, "Link didn't transition to L2 state\n"); 1498 1508 /* ··· 1773 1763 val = (ep->msi_mem_phys & MSIX_ADDR_MATCH_LOW_OFF_MASK); 1774 1764 val |= MSIX_ADDR_MATCH_LOW_OFF_EN; 1775 1765 dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_LOW_OFF, val); 1776 - val = (lower_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK); 1766 + val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK); 1777 1767 dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val); 1778 1768 1779 1769 ret = dw_pcie_ep_init_complete(ep); ··· 1943 1933 if (ret < 0) { 1944 1934 dev_err(dev, "Failed to request IRQ for PERST: %d\n", ret); 1945 1935 return ret; 1946 - } 1947 - 1948 - name = devm_kasprintf(dev, GFP_KERNEL, "tegra_pcie_%u_ep_work", 1949 - pcie->cid); 1950 - if (!name) { 1951 - dev_err(dev, "Failed to create PCIe EP work thread string\n"); 1952 - return -ENOMEM; 1953 1936 } 1954 1937 1955 1938 pm_runtime_enable(dev); ··· 2238 2235 { 2239 2236 struct tegra_pcie_dw *pcie = dev_get_drvdata(dev); 2240 2237 u32 val; 2238 + 2239 + if (pcie->mode == DW_PCIE_EP_TYPE) { 2240 + dev_err(dev, "Suspend is not supported in EP mode"); 2241 + return -ENOTSUPP; 2242 + } 2241 2243 2242 2244 if (!pcie->link_state) 2243 2245 return 0;