Skip to content

Commit fa81d60

Browse files
bruelcbjorn-helgaas
authored andcommitted
PCI: stm32: Fix LTSSM EP race with start link
If the host has deasserted PERST# and started link training before the link is started on EP side, enabling LTSSM before the endpoint registers are initialized in the perst_irq handler results in probing incorrect values. Thus, wait for the PERST# level-triggered interrupt to start link training at the end of initialization and cleanup the stm32_pcie_[start stop]_link functions. Fixes: 151f3d2 ("PCI: stm32-ep: Add PCIe Endpoint support for STM32MP25") Signed-off-by: Christian Bruel <christian.bruel@foss.st.com> [mani: added fixes tag] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> [bhelgaas: wrap line] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://patch.msgid.link/20251114-perst_ep-v1-1-e7976317a890@foss.st.com
1 parent 3a86608 commit fa81d60

1 file changed

Lines changed: 8 additions & 31 deletions

File tree

drivers/pci/controller/dwc/pcie-stm32-ep.c

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,9 @@ static void stm32_pcie_ep_init(struct dw_pcie_ep *ep)
3737
dw_pcie_ep_reset_bar(pci, bar);
3838
}
3939

40-
static int stm32_pcie_enable_link(struct dw_pcie *pci)
41-
{
42-
struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
43-
44-
regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
45-
STM32MP25_PCIECR_LTSSM_EN,
46-
STM32MP25_PCIECR_LTSSM_EN);
47-
48-
return dw_pcie_wait_for_link(pci);
49-
}
50-
51-
static void stm32_pcie_disable_link(struct dw_pcie *pci)
52-
{
53-
struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
54-
55-
regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, STM32MP25_PCIECR_LTSSM_EN, 0);
56-
}
57-
5840
static int stm32_pcie_start_link(struct dw_pcie *pci)
5941
{
6042
struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
61-
int ret;
62-
63-
dev_dbg(pci->dev, "Enable link\n");
64-
65-
ret = stm32_pcie_enable_link(pci);
66-
if (ret) {
67-
dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
68-
return ret;
69-
}
7043

7144
enable_irq(stm32_pcie->perst_irq);
7245

@@ -77,11 +50,7 @@ static void stm32_pcie_stop_link(struct dw_pcie *pci)
7750
{
7851
struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
7952

80-
dev_dbg(pci->dev, "Disable link\n");
81-
8253
disable_irq(stm32_pcie->perst_irq);
83-
84-
stm32_pcie_disable_link(pci);
8554
}
8655

8756
static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -152,6 +121,9 @@ static void stm32_pcie_perst_assert(struct dw_pcie *pci)
152121

153122
dev_dbg(dev, "PERST asserted by host\n");
154123

124+
regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
125+
STM32MP25_PCIECR_LTSSM_EN, 0);
126+
155127
pci_epc_deinit_notify(ep->epc);
156128

157129
stm32_pcie_disable_resources(stm32_pcie);
@@ -192,6 +164,11 @@ static void stm32_pcie_perst_deassert(struct dw_pcie *pci)
192164

193165
pci_epc_init_notify(ep->epc);
194166

167+
/* Enable link training */
168+
regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
169+
STM32MP25_PCIECR_LTSSM_EN,
170+
STM32MP25_PCIECR_LTSSM_EN);
171+
195172
return;
196173

197174
err_disable_resources:

0 commit comments

Comments
 (0)