Skip to content

Commit 112aba9

Browse files
Richard Zhubjorn-helgaas
authored andcommitted
PCI: dwc: Remove LTSSM state test in dw_pcie_suspend_noirq()
It's safe to send PME_TURN_OFF message regardless of whether the link is up or down, so don't test the LTSSM state before sending the PME_TURN_OFF message. Only print an error message when the LTSSM is not in DETECT or POLL. There shouldn't be an error when no Endpoint is connected at all. Link: https://lore.kernel.org/r/20241210081557.163555-3-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
1 parent 86a016e commit 112aba9

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
924924
{
925925
u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
926926
u32 val;
927-
int ret = 0;
927+
int ret;
928928

929929
/*
930930
* If L1SS is supported, then do not put the link into L2 as some
@@ -933,25 +933,32 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
933933
if (dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKCTL) & PCI_EXP_LNKCTL_ASPM_L1)
934934
return 0;
935935

936-
if (dw_pcie_get_ltssm(pci) <= DW_PCIE_LTSSM_DETECT_ACT)
937-
return 0;
938-
939-
if (pci->pp.ops->pme_turn_off)
936+
if (pci->pp.ops->pme_turn_off) {
940937
pci->pp.ops->pme_turn_off(&pci->pp);
941-
else
938+
} else {
942939
ret = dw_pcie_pme_turn_off(pci);
940+
if (ret)
941+
return ret;
942+
}
943943

944-
if (ret)
945-
return ret;
946-
947-
ret = read_poll_timeout(dw_pcie_get_ltssm, val, val == DW_PCIE_LTSSM_L2_IDLE,
944+
ret = read_poll_timeout(dw_pcie_get_ltssm, val,
945+
val == DW_PCIE_LTSSM_L2_IDLE ||
946+
val <= DW_PCIE_LTSSM_DETECT_WAIT,
948947
PCIE_PME_TO_L2_TIMEOUT_US/10,
949948
PCIE_PME_TO_L2_TIMEOUT_US, false, pci);
950949
if (ret) {
950+
/* Only log message when LTSSM isn't in DETECT or POLL */
951951
dev_err(pci->dev, "Timeout waiting for L2 entry! LTSSM: 0x%x\n", val);
952952
return ret;
953953
}
954954

955+
/*
956+
* Per PCIe r6.0, sec 5.3.3.2.1, software should wait at least
957+
* 100ns after L2/L3 Ready before turning off refclock and
958+
* main power. This is harmless when no endpoint is connected.
959+
*/
960+
udelay(1);
961+
955962
dw_pcie_stop_link(pci);
956963
if (pci->pp.ops->deinit)
957964
pci->pp.ops->deinit(&pci->pp);

drivers/pci/controller/dwc/pcie-designware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ enum dw_pcie_ltssm {
330330
/* Need to align with PCIE_PORT_DEBUG0 bits 0:5 */
331331
DW_PCIE_LTSSM_DETECT_QUIET = 0x0,
332332
DW_PCIE_LTSSM_DETECT_ACT = 0x1,
333+
DW_PCIE_LTSSM_DETECT_WAIT = 0x6,
333334
DW_PCIE_LTSSM_L0 = 0x11,
334335
DW_PCIE_LTSSM_L2_IDLE = 0x15,
335336

0 commit comments

Comments
 (0)