* [PATCH v4 1/5] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found
2026-01-20 17:47 [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam via B4 Relay
@ 2026-01-20 17:47 ` Manivannan Sadhasivam via B4 Relay
2026-01-21 8:22 ` Niklas Cassel
2026-01-20 17:47 ` [PATCH v4 2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active Manivannan Sadhasivam via B4 Relay
` (4 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-01-20 17:47 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, vincent.guittot, zhangsenchuan,
Shawn Lin, Niklas Cassel, Richard Zhu, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
The dw_pcie_wait_for_link() function waits up to 1 second for the PCIe link
to come up and returns -ETIMEDOUT for all failures without distinguishing
cases where no device is present on the bus. But the callers may want to
just skip the failure if the device is not found on the bus and handle
failure for other reasons.
So after timeout, if the LTSSM is in Detect.Quiet or Detect.Active state,
return -ENODEV to indicate the callers that the device is not found on the
bus and return -ETIMEDOUT otherwise.
Also add kernel doc to document the parameter and return values.
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-designware.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 345365ea97c7..55c1c60f7f8f 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -692,9 +692,16 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0);
}
+/**
+ * dw_pcie_wait_for_link - Wait for the PCIe link to be up
+ * @pci: DWC instance
+ *
+ * Returns: 0 if link is up, -ENODEV if device is not found, -ETIMEDOUT if the
+ * link fails to come up for other reasons.
+ */
int dw_pcie_wait_for_link(struct dw_pcie *pci)
{
- u32 offset, val;
+ u32 offset, val, ltssm;
int retries;
/* Check if the link is up or not */
@@ -706,6 +713,17 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
}
if (retries >= PCIE_LINK_WAIT_MAX_RETRIES) {
+ /*
+ * If the link is in Detect.Quiet or Detect.Active state, it
+ * indicates that no device is detected.
+ */
+ ltssm = dw_pcie_get_ltssm(pci);
+ if (ltssm == DW_PCIE_LTSSM_DETECT_QUIET ||
+ ltssm == DW_PCIE_LTSSM_DETECT_ACT) {
+ dev_info(pci->dev, "Device not found\n");
+ return -ENODEV;
+ }
+
dev_info(pci->dev, "Phy link never came up\n");
return -ETIMEDOUT;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 1/5] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found
2026-01-20 17:47 ` [PATCH v4 1/5] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found Manivannan Sadhasivam via B4 Relay
@ 2026-01-21 8:22 ` Niklas Cassel
0 siblings, 0 replies; 14+ messages in thread
From: Niklas Cassel @ 2026-01-21 8:22 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Tue, Jan 20, 2026 at 11:17:40PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> The dw_pcie_wait_for_link() function waits up to 1 second for the PCIe link
> to come up and returns -ETIMEDOUT for all failures without distinguishing
> cases where no device is present on the bus. But the callers may want to
> just skip the failure if the device is not found on the bus and handle
> failure for other reasons.
>
> So after timeout, if the LTSSM is in Detect.Quiet or Detect.Active state,
> return -ENODEV to indicate the callers that the device is not found on the
> bus and return -ETIMEDOUT otherwise.
>
> Also add kernel doc to document the parameter and return values.
>
> Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
> Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
Reviewed-by: Niklas Cassel <cassel@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active
2026-01-20 17:47 [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam via B4 Relay
2026-01-20 17:47 ` [PATCH v4 1/5] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found Manivannan Sadhasivam via B4 Relay
@ 2026-01-20 17:47 ` Manivannan Sadhasivam via B4 Relay
2026-01-21 8:23 ` Niklas Cassel
2026-01-20 17:47 ` [PATCH v4 3/5] PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c Manivannan Sadhasivam via B4 Relay
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-01-20 17:47 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, vincent.guittot, zhangsenchuan,
Shawn Lin, Niklas Cassel, Richard Zhu, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
There are cases where the PCIe device would be physically connected to the
bus, but the device firmware might not be active. So the LTSSM will
get stuck in POLL.{Active/Compliance} states.
This behavior is common with endpoint devices controlled by the PCI
Endpoint framework, where the device will wait for the user to start its
operation through configfs.
For those cases, print the relevant log and return -EIO to indicate that
the device is present, but not active. This will allow the callers to skip
the failure as the device might become active in the future.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-designware.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 55c1c60f7f8f..aca5bbeade03 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -696,8 +696,9 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
* dw_pcie_wait_for_link - Wait for the PCIe link to be up
* @pci: DWC instance
*
- * Returns: 0 if link is up, -ENODEV if device is not found, -ETIMEDOUT if the
- * link fails to come up for other reasons.
+ * Returns: 0 if link is up, -ENODEV if device is not found, -EIO if the device
+ * is found but not active and -ETIMEDOUT if the link fails to come up for other
+ * reasons.
*/
int dw_pcie_wait_for_link(struct dw_pcie *pci)
{
@@ -722,6 +723,16 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
ltssm == DW_PCIE_LTSSM_DETECT_ACT) {
dev_info(pci->dev, "Device not found\n");
return -ENODEV;
+
+ /*
+ * If the link is in POLL.{Active/Compliance} state, then the
+ * device is found to be connected to the bus, but it is not
+ * active i.e., the device firmware might not yet initialized.
+ */
+ } else if (ltssm == DW_PCIE_LTSSM_POLL_ACTIVE ||
+ ltssm == DW_PCIE_LTSSM_POLL_COMPLIANCE) {
+ dev_info(pci->dev, "Device found, but not active\n");
+ return -EIO;
}
dev_info(pci->dev, "Phy link never came up\n");
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active
2026-01-20 17:47 ` [PATCH v4 2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active Manivannan Sadhasivam via B4 Relay
@ 2026-01-21 8:23 ` Niklas Cassel
2026-01-21 9:13 ` Manivannan Sadhasivam
0 siblings, 1 reply; 14+ messages in thread
From: Niklas Cassel @ 2026-01-21 8:23 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Tue, Jan 20, 2026 at 11:17:41PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> There are cases where the PCIe device would be physically connected to the
> bus, but the device firmware might not be active. So the LTSSM will
> get stuck in POLL.{Active/Compliance} states.
>
> This behavior is common with endpoint devices controlled by the PCI
> Endpoint framework, where the device will wait for the user to start its
> operation through configfs.
>
> For those cases, print the relevant log and return -EIO to indicate that
> the device is present, but not active. This will allow the callers to skip
> the failure as the device might become active in the future.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/pci/controller/dwc/pcie-designware.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index 55c1c60f7f8f..aca5bbeade03 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -696,8 +696,9 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
> * dw_pcie_wait_for_link - Wait for the PCIe link to be up
> * @pci: DWC instance
> *
> - * Returns: 0 if link is up, -ENODEV if device is not found, -ETIMEDOUT if the
> - * link fails to come up for other reasons.
> + * Returns: 0 if link is up, -ENODEV if device is not found, -EIO if the device
> + * is found but not active and -ETIMEDOUT if the link fails to come up for other
> + * reasons.
> */
> int dw_pcie_wait_for_link(struct dw_pcie *pci)
> {
> @@ -722,6 +723,16 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
> ltssm == DW_PCIE_LTSSM_DETECT_ACT) {
> dev_info(pci->dev, "Device not found\n");
> return -ENODEV;
> +
> + /*
> + * If the link is in POLL.{Active/Compliance} state, then the
> + * device is found to be connected to the bus, but it is not
> + * active i.e., the device firmware might not yet initialized.
> + */
> + } else if (ltssm == DW_PCIE_LTSSM_POLL_ACTIVE ||
> + ltssm == DW_PCIE_LTSSM_POLL_COMPLIANCE) {
> + dev_info(pci->dev, "Device found, but not active\n");
> + return -EIO;
> }
>
> dev_info(pci->dev, "Phy link never came up\n");
This should probably be squashed with the previous patch.
Regardless:
Reviewed-by: Niklas Cassel <cassel@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active
2026-01-21 8:23 ` Niklas Cassel
@ 2026-01-21 9:13 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-01-21 9:13 UTC (permalink / raw)
To: Niklas Cassel
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Wed, Jan 21, 2026 at 09:23:22AM +0100, Niklas Cassel wrote:
> On Tue, Jan 20, 2026 at 11:17:41PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> >
> > There are cases where the PCIe device would be physically connected to the
> > bus, but the device firmware might not be active. So the LTSSM will
> > get stuck in POLL.{Active/Compliance} states.
> >
> > This behavior is common with endpoint devices controlled by the PCI
> > Endpoint framework, where the device will wait for the user to start its
> > operation through configfs.
> >
> > For those cases, print the relevant log and return -EIO to indicate that
> > the device is present, but not active. This will allow the callers to skip
> > the failure as the device might become active in the future.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > ---
> > drivers/pci/controller/dwc/pcie-designware.c | 15 +++++++++++++--
> > 1 file changed, 13 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index 55c1c60f7f8f..aca5bbeade03 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -696,8 +696,9 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
> > * dw_pcie_wait_for_link - Wait for the PCIe link to be up
> > * @pci: DWC instance
> > *
> > - * Returns: 0 if link is up, -ENODEV if device is not found, -ETIMEDOUT if the
> > - * link fails to come up for other reasons.
> > + * Returns: 0 if link is up, -ENODEV if device is not found, -EIO if the device
> > + * is found but not active and -ETIMEDOUT if the link fails to come up for other
> > + * reasons.
> > */
> > int dw_pcie_wait_for_link(struct dw_pcie *pci)
> > {
> > @@ -722,6 +723,16 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
> > ltssm == DW_PCIE_LTSSM_DETECT_ACT) {
> > dev_info(pci->dev, "Device not found\n");
> > return -ENODEV;
> > +
> > + /*
> > + * If the link is in POLL.{Active/Compliance} state, then the
> > + * device is found to be connected to the bus, but it is not
> > + * active i.e., the device firmware might not yet initialized.
> > + */
> > + } else if (ltssm == DW_PCIE_LTSSM_POLL_ACTIVE ||
> > + ltssm == DW_PCIE_LTSSM_POLL_COMPLIANCE) {
> > + dev_info(pci->dev, "Device found, but not active\n");
> > + return -EIO;
> > }
> >
> > dev_info(pci->dev, "Phy link never came up\n");
>
> This should probably be squashed with the previous patch.
>
No. I'd like to keep it as a separate patch because I think this deserves its
own justification.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 3/5] PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c
2026-01-20 17:47 [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam via B4 Relay
2026-01-20 17:47 ` [PATCH v4 1/5] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found Manivannan Sadhasivam via B4 Relay
2026-01-20 17:47 ` [PATCH v4 2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active Manivannan Sadhasivam via B4 Relay
@ 2026-01-20 17:47 ` Manivannan Sadhasivam via B4 Relay
2026-01-21 8:23 ` Niklas Cassel
2026-01-20 17:47 ` [PATCH v4 4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link() Manivannan Sadhasivam via B4 Relay
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-01-20 17:47 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, vincent.guittot, zhangsenchuan,
Shawn Lin, Niklas Cassel, Richard Zhu, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Rename ltssm_status_string() to dw_pcie_ltssm_status_string() and move it
to the common file pcie-designware.c so that this function could be used
outside of pcie-designware-debugfs.c file.
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
.../pci/controller/dwc/pcie-designware-debugfs.c | 54 +---------------------
drivers/pci/controller/dwc/pcie-designware.c | 52 +++++++++++++++++++++
drivers/pci/controller/dwc/pcie-designware.h | 2 +
3 files changed, 55 insertions(+), 53 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-debugfs.c b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
index df98fee69892..0d1340c9b364 100644
--- a/drivers/pci/controller/dwc/pcie-designware-debugfs.c
+++ b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
@@ -443,65 +443,13 @@ static ssize_t counter_value_read(struct file *file, char __user *buf,
return simple_read_from_buffer(buf, count, ppos, debugfs_buf, pos);
}
-static const char *ltssm_status_string(enum dw_pcie_ltssm ltssm)
-{
- const char *str;
-
- switch (ltssm) {
-#define DW_PCIE_LTSSM_NAME(n) case n: str = #n; break
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_QUIET);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_ACT);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_ACTIVE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_COMPLIANCE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_CONFIG);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_PRE_DETECT_QUIET);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_WAIT);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LINKWD_START);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LINKWD_ACEPT);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LANENUM_WAI);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LANENUM_ACEPT);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_COMPLETE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_IDLE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_LOCK);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_SPEED);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_RCVRCFG);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_IDLE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L0);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L0S);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L123_SEND_EIDLE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_IDLE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L2_IDLE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L2_WAKE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED_ENTRY);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED_IDLE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_ENTRY);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_ACTIVE);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_EXIT);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_EXIT_TIMEOUT);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_HOT_RESET_ENTRY);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_HOT_RESET);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ0);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ1);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ2);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ3);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_1);
- DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_2);
- default:
- str = "DW_PCIE_LTSSM_UNKNOWN";
- break;
- }
-
- return str + strlen("DW_PCIE_LTSSM_");
-}
-
static int ltssm_status_show(struct seq_file *s, void *v)
{
struct dw_pcie *pci = s->private;
enum dw_pcie_ltssm val;
val = dw_pcie_get_ltssm(pci);
- seq_printf(s, "%s (0x%02x)\n", ltssm_status_string(val), val);
+ seq_printf(s, "%s (0x%02x)\n", dw_pcie_ltssm_status_string(val), val);
return 0;
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index aca5bbeade03..f74eae79cca4 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -692,6 +692,58 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0);
}
+const char *dw_pcie_ltssm_status_string(enum dw_pcie_ltssm ltssm)
+{
+ const char *str;
+
+ switch (ltssm) {
+#define DW_PCIE_LTSSM_NAME(n) case n: str = #n; break
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_QUIET);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_ACT);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_ACTIVE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_COMPLIANCE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_CONFIG);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_PRE_DETECT_QUIET);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_WAIT);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LINKWD_START);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LINKWD_ACEPT);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LANENUM_WAI);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LANENUM_ACEPT);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_COMPLETE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_IDLE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_LOCK);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_SPEED);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_RCVRCFG);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_IDLE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L0);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L0S);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L123_SEND_EIDLE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_IDLE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L2_IDLE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L2_WAKE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED_ENTRY);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED_IDLE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_ENTRY);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_ACTIVE);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_EXIT);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_EXIT_TIMEOUT);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_HOT_RESET_ENTRY);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_HOT_RESET);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ0);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ1);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ2);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ3);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_1);
+ DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_2);
+ default:
+ str = "DW_PCIE_LTSSM_UNKNOWN";
+ break;
+ }
+
+ return str + strlen("DW_PCIE_LTSSM_");
+}
+
/**
* dw_pcie_wait_for_link - Wait for the PCIe link to be up
* @pci: DWC instance
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index f87c67a7a482..c1def4d9cf62 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -828,6 +828,8 @@ static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci)
return (enum dw_pcie_ltssm)FIELD_GET(PORT_LOGIC_LTSSM_STATE_MASK, val);
}
+const char *dw_pcie_ltssm_status_string(enum dw_pcie_ltssm ltssm);
+
#ifdef CONFIG_PCIE_DW_HOST
int dw_pcie_suspend_noirq(struct dw_pcie *pci);
int dw_pcie_resume_noirq(struct dw_pcie *pci);
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 3/5] PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c
2026-01-20 17:47 ` [PATCH v4 3/5] PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c Manivannan Sadhasivam via B4 Relay
@ 2026-01-21 8:23 ` Niklas Cassel
0 siblings, 0 replies; 14+ messages in thread
From: Niklas Cassel @ 2026-01-21 8:23 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Tue, Jan 20, 2026 at 11:17:42PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Rename ltssm_status_string() to dw_pcie_ltssm_status_string() and move it
> to the common file pcie-designware.c so that this function could be used
> outside of pcie-designware-debugfs.c file.
>
> Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
> Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link()
2026-01-20 17:47 [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam via B4 Relay
` (2 preceding siblings ...)
2026-01-20 17:47 ` [PATCH v4 3/5] PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c Manivannan Sadhasivam via B4 Relay
@ 2026-01-20 17:47 ` Manivannan Sadhasivam via B4 Relay
2026-01-21 8:23 ` Niklas Cassel
2026-01-20 17:47 ` [PATCH v4 5/5] PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT Manivannan Sadhasivam via B4 Relay
2026-01-21 9:21 ` [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam
5 siblings, 1 reply; 14+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-01-20 17:47 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, vincent.guittot, zhangsenchuan,
Shawn Lin, Niklas Cassel, Richard Zhu, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
If the link fails to come up even after detecting the device on the bus
i.e., if the LTSSM is not in Detect.Quiet and Detect.Active states, then
dw_pcie_wait_for_link() should log it as an error.
So promote dev_info() to dev_err(), reword the error log to make it clear
and also print the LTSSM state to aid debugging.
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-designware.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index f74eae79cca4..2fa9f6ee149e 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -787,7 +787,8 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
return -EIO;
}
- dev_info(pci->dev, "Phy link never came up\n");
+ dev_err(pci->dev, "Link failed to come up. LTSSM: %s\n",
+ dw_pcie_ltssm_status_string(ltssm));
return -ETIMEDOUT;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link()
2026-01-20 17:47 ` [PATCH v4 4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link() Manivannan Sadhasivam via B4 Relay
@ 2026-01-21 8:23 ` Niklas Cassel
2026-01-21 9:13 ` Manivannan Sadhasivam
0 siblings, 1 reply; 14+ messages in thread
From: Niklas Cassel @ 2026-01-21 8:23 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Tue, Jan 20, 2026 at 11:17:43PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> If the link fails to come up even after detecting the device on the bus
> i.e., if the LTSSM is not in Detect.Quiet and Detect.Active states, then
> dw_pcie_wait_for_link() should log it as an error.
Nit: maybe you should mention Poll.Active and Poll.Compliance here too?
>
> So promote dev_info() to dev_err(), reword the error log to make it clear
> and also print the LTSSM state to aid debugging.
>
> Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
> Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
Regardless:
Reviewed-by: Niklas Cassel <cassel@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link()
2026-01-21 8:23 ` Niklas Cassel
@ 2026-01-21 9:13 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-01-21 9:13 UTC (permalink / raw)
To: Niklas Cassel
Cc: manivannan.sadhasivam, Jingoo Han, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Wed, Jan 21, 2026 at 09:23:58AM +0100, Niklas Cassel wrote:
> On Tue, Jan 20, 2026 at 11:17:43PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> >
> > If the link fails to come up even after detecting the device on the bus
> > i.e., if the LTSSM is not in Detect.Quiet and Detect.Active states, then
> > dw_pcie_wait_for_link() should log it as an error.
>
> Nit: maybe you should mention Poll.Active and Poll.Compliance here too?
>
Sure, I missed it. Will ammend it while applying.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 5/5] PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT
2026-01-20 17:47 [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam via B4 Relay
` (3 preceding siblings ...)
2026-01-20 17:47 ` [PATCH v4 4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link() Manivannan Sadhasivam via B4 Relay
@ 2026-01-20 17:47 ` Manivannan Sadhasivam via B4 Relay
2026-01-21 8:24 ` Niklas Cassel
2026-01-21 9:21 ` [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam
5 siblings, 1 reply; 14+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-01-20 17:47 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, vincent.guittot, zhangsenchuan,
Shawn Lin, Niklas Cassel, Richard Zhu, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
The dw_pcie_wait_for_link() API now distinguishes link failures more
precisely:
-ENODEV: Device not found on the bus.
-EIO: Device found but inactive.
-ETIMEDOUT: Link failed to come up.
Out of these three errors, only -ETIMEDOUT represents a definitive link
failure since it signals that something is wrong with the link. For the
other two errors, there is a possibility that the link might come up later.
So fail dw_pcie_host_init() if -ETIMEDOUT is returned and skip the failure
otherwise.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index fad0cbedefbc..a72406ef7e26 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -675,8 +675,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
goto err_remove_edma;
}
- /* Ignore errors, the link may come up later */
- dw_pcie_wait_for_link(pci);
+ /*
+ * Only fail on timeout error. Other errors indicate the device may
+ * become available later, so continue without failing.
+ */
+ ret = dw_pcie_wait_for_link(pci);
+ if (ret == -ETIMEDOUT)
+ goto err_stop_link;
ret = pci_host_probe(bridge);
if (ret)
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 5/5] PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT
2026-01-20 17:47 ` [PATCH v4 5/5] PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT Manivannan Sadhasivam via B4 Relay
@ 2026-01-21 8:24 ` Niklas Cassel
0 siblings, 0 replies; 14+ messages in thread
From: Niklas Cassel @ 2026-01-21 8:24 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-kernel, vincent.guittot, zhangsenchuan, Shawn Lin,
Richard Zhu
On Tue, Jan 20, 2026 at 11:17:44PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> The dw_pcie_wait_for_link() API now distinguishes link failures more
> precisely:
>
> -ENODEV: Device not found on the bus.
> -EIO: Device found but inactive.
> -ETIMEDOUT: Link failed to come up.
>
> Out of these three errors, only -ETIMEDOUT represents a definitive link
> failure since it signals that something is wrong with the link. For the
> other two errors, there is a possibility that the link might come up later.
> So fail dw_pcie_host_init() if -ETIMEDOUT is returned and skip the failure
> otherwise.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
Reviewed-by: Niklas Cassel <cassel@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API
2026-01-20 17:47 [PATCH v4 0/5] PCI: dwc: Rework the error handling of dw_pcie_wait_for_link() API Manivannan Sadhasivam via B4 Relay
` (4 preceding siblings ...)
2026-01-20 17:47 ` [PATCH v4 5/5] PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT Manivannan Sadhasivam via B4 Relay
@ 2026-01-21 9:21 ` Manivannan Sadhasivam
5 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-01-21 9:21 UTC (permalink / raw)
To: Jingoo Han, Lorenzo Pieralisi, Krzysztof Wilczyński,
Rob Herring, Bjorn Helgaas, Manivannan Sadhasivam
Cc: linux-pci, linux-kernel, vincent.guittot, zhangsenchuan,
Shawn Lin, Niklas Cassel, Richard Zhu
On Tue, 20 Jan 2026 23:17:39 +0530, Manivannan Sadhasivam wrote:
> This series reworks the dw_pcie_wait_for_link() API to allow the callers to
> detect the absence of the device on the bus and skip the failure.
>
> Compared to v2, I've reworked the patch 2 to improve the API further and
> dropped the patch 1 that got applied (hence changed the subject). I've also
> modified the error code based on the feedback in v2 to return -ENODEV if device
> is not detected on the bus, -EIO if the device is found but not active and
> -ETIMEDOUT otherwise. This allows the callers to skip the failure as needed.
>
> [...]
Applied, thanks!
[1/5] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found
commit: 1bcf245c837bc66fdaddea222bab9eb5c978a9d7
[2/5] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active
commit: 01d16b8afb7afcc17f999f8b4a9b9cfe6c6fae71
[3/5] PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c
commit: 36dd677f7d76ddec96d50cf57f543ba7d612087c
[4/5] PCI: dwc: Rework the error print of dw_pcie_wait_for_link()
commit: d266f63b385a3bad5fd6f23797b6de57de998677
[5/5] PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT
commit: 86cbb7a81068434fdc1d5afb96d91ab971fb279e
Best regards,
--
Manivannan Sadhasivam <mani@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread