clk_enable_bulk(), reset_deassert_bulk() and the outbound iATU setup can all fail, and the probe ignores all three. A controller whose clocks or resets did not come up is then accessed anyway, and a failed memory window is reported as a successful probe.
Fail the probe with the error instead, as Linux's driver does for its clocks and resets, and undo the clock enable when the resets fail. Signed-off-by: Dave Klotz <[email protected]> --- drivers/pci/pcie_dw_spacemit.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pcie_dw_spacemit.c b/drivers/pci/pcie_dw_spacemit.c index b85de73ad3..5e0871986b 100644 --- a/drivers/pci/pcie_dw_spacemit.c +++ b/drivers/pci/pcie_dw_spacemit.c @@ -230,8 +230,18 @@ static int pcie_dw_spacemit_probe(struct udevice *dev) spacemit_pcie_toggle_soft_reset(pci); /* enable pcie clk and deassert resets */ - clk_enable_bulk(&pci->clks); - reset_deassert_bulk(&pci->rsts); + ret = clk_enable_bulk(&pci->clks); + if (ret) { + dev_err(dev, "failed to enable clocks: %d\n", ret); + return ret; + } + + ret = reset_deassert_bulk(&pci->rsts); + if (ret) { + dev_err(dev, "failed to deassert resets: %d\n", ret); + clk_disable_bulk(&pci->clks); + return ret; + } reg = spacemit_pcie_readl(pci, PCIECTRL_K1X_CONF_DEVICE_CMD); reg &= ~LTSSM_EN; @@ -317,6 +327,8 @@ static int pcie_dw_spacemit_probe(struct udevice *dev) pci->dw.mem.phys_start, pci->dw.mem.bus_start, pci->dw.mem.size); + if (ret) + return -EIO; return 0; } -- 2.55.0
