[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260126074519.3426742-13-mmaddireddy@nvidia.com>
Date: Mon, 26 Jan 2026 13:15:09 +0530
From: Manikanta Maddireddy <mmaddireddy@...dia.com>
To: <bhelgaas@...gle.com>, <lpieralisi@...nel.org>, <kwilczynski@...nel.org>,
<mani@...nel.org>, <robh@...nel.org>, <krzk+dt@...nel.org>,
<conor+dt@...nel.org>, <thierry.reding@...il.com>, <jonathanh@...dia.com>,
<jingoohan1@...il.com>, <vidyas@...dia.com>, <cassel@...nel.org>,
<18255117159@....com>
CC: <linux-pci@...r.kernel.org>, <devicetree@...r.kernel.org>,
<linux-tegra@...r.kernel.org>, <linux-kernel@...r.kernel.org>, "Manikanta
Maddireddy" <mmaddireddy@...dia.com>
Subject: [PATCH V4 12/22] PCI: tegra194: Allow system suspend when the Endpoint link is not up
From: Vidya Sagar <vidyas@...dia.com>
Only a Root port initiates the L2 sequence. PCIe link is kept in L2 state
during suspend. If Endpoint mode is enabled and the link is up, the
software cannot proceed with suspend. However, when the PCIe Endpoint
driver is probed, but the PCIe link is not up, Tegra can go into suspend
state. So, allow system to suspend in this case.
Signed-off-by: Vidya Sagar <vidyas@...dia.com>
Signed-off-by: Manikanta Maddireddy <mmaddireddy@...dia.com>
---
V4:
* None
V3:
* This is a new patch in this series
drivers/pci/controller/dwc/pcie-tegra194.c | 31 +++++++++++++++++-----
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 5fa4d2adf64e..04e6c34f47f0 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -2341,16 +2341,28 @@ static void tegra_pcie_dw_remove(struct platform_device *pdev)
gpiod_set_value(pcie->pex_refclk_sel_gpiod, 0);
}
-static int tegra_pcie_dw_suspend_late(struct device *dev)
+static int tegra_pcie_dw_suspend(struct device *dev)
{
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
- u32 val;
if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
- dev_err(dev, "Failed to Suspend as Tegra PCIe is in EP mode\n");
- return -EPERM;
+ if (pcie->ep_state == EP_STATE_ENABLED) {
+ dev_err(dev, "Tegra PCIe is in EP mode, suspend not allowed\n");
+ return -EPERM;
+ }
+
+ disable_irq(pcie->pex_rst_irq);
+ return 0;
}
+ return 0;
+}
+
+static int tegra_pcie_dw_suspend_late(struct device *dev)
+{
+ struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
+ u32 val;
+
if (!pcie->link_state)
return 0;
@@ -2370,6 +2382,9 @@ static int tegra_pcie_dw_suspend_noirq(struct device *dev)
{
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
+ if (pcie->of_data->mode == DW_PCIE_EP_TYPE)
+ return 0;
+
if (!pcie->link_state)
return 0;
@@ -2385,6 +2400,9 @@ static int tegra_pcie_dw_resume_noirq(struct device *dev)
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
int ret;
+ if (pcie->of_data->mode == DW_PCIE_EP_TYPE)
+ return 0;
+
if (!pcie->link_state)
return 0;
@@ -2417,8 +2435,8 @@ static int tegra_pcie_dw_resume_early(struct device *dev)
u32 val;
if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
- dev_err(dev, "Suspend is not supported in EP mode");
- return -ENOTSUPP;
+ enable_irq(pcie->pex_rst_irq);
+ return 0;
}
if (!pcie->link_state)
@@ -2524,6 +2542,7 @@ static const struct of_device_id tegra_pcie_dw_of_match[] = {
};
static const struct dev_pm_ops tegra_pcie_dw_pm_ops = {
+ .suspend = tegra_pcie_dw_suspend,
.suspend_late = tegra_pcie_dw_suspend_late,
.suspend_noirq = tegra_pcie_dw_suspend_noirq,
.resume_noirq = tegra_pcie_dw_resume_noirq,
--
2.34.1
Powered by blists - more mailing lists