Skip to content

Commit 61693e4

Browse files
Vidya Sagargregkh
authored andcommitted
PCI: tegra194: Allow system suspend when the Endpoint link is not up
[ Upstream commit c76f8ea ] Host software 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. Fixes: de2bbf2 ("PCI: tegra194: Don't allow suspend when Tegra PCIe is in EP mode") Signed-off-by: Vidya Sagar <vidyas@nvidia.com> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Jon Hunter <jonathanh@nvidia.com> Reviewed-by: Jon Hunter <jonathanh@nvidia.com> Reviewed-by: Vidya Sagar <vidyas@nvidia.com> Link: https://patch.msgid.link/20260324190755.1094879-10-mmaddireddy@nvidia.com Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent b55ba84 commit 61693e4

1 file changed

Lines changed: 25 additions & 6 deletions

File tree

drivers/pci/controller/dwc/pcie-tegra194.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2270,16 +2270,28 @@ static void tegra_pcie_dw_remove(struct platform_device *pdev)
22702270
gpiod_set_value(pcie->pex_refclk_sel_gpiod, 0);
22712271
}
22722272

2273-
static int tegra_pcie_dw_suspend_late(struct device *dev)
2273+
static int tegra_pcie_dw_suspend(struct device *dev)
22742274
{
22752275
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
2276-
u32 val;
22772276

22782277
if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
2279-
dev_err(dev, "Failed to Suspend as Tegra PCIe is in EP mode\n");
2280-
return -EPERM;
2278+
if (pcie->ep_state == EP_STATE_ENABLED) {
2279+
dev_err(dev, "Tegra PCIe is in EP mode, suspend not allowed\n");
2280+
return -EPERM;
2281+
}
2282+
2283+
disable_irq(pcie->pex_rst_irq);
2284+
return 0;
22812285
}
22822286

2287+
return 0;
2288+
}
2289+
2290+
static int tegra_pcie_dw_suspend_late(struct device *dev)
2291+
{
2292+
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
2293+
u32 val;
2294+
22832295
if (!pcie->link_state)
22842296
return 0;
22852297

@@ -2299,6 +2311,9 @@ static int tegra_pcie_dw_suspend_noirq(struct device *dev)
22992311
{
23002312
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
23012313

2314+
if (pcie->of_data->mode == DW_PCIE_EP_TYPE)
2315+
return 0;
2316+
23022317
if (!pcie->link_state)
23032318
return 0;
23042319

@@ -2313,6 +2328,9 @@ static int tegra_pcie_dw_resume_noirq(struct device *dev)
23132328
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
23142329
int ret;
23152330

2331+
if (pcie->of_data->mode == DW_PCIE_EP_TYPE)
2332+
return 0;
2333+
23162334
if (!pcie->link_state)
23172335
return 0;
23182336

@@ -2345,8 +2363,8 @@ static int tegra_pcie_dw_resume_early(struct device *dev)
23452363
u32 val;
23462364

23472365
if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
2348-
dev_err(dev, "Suspend is not supported in EP mode");
2349-
return -ENOTSUPP;
2366+
enable_irq(pcie->pex_rst_irq);
2367+
return 0;
23502368
}
23512369

23522370
if (!pcie->link_state)
@@ -2451,6 +2469,7 @@ static const struct of_device_id tegra_pcie_dw_of_match[] = {
24512469
};
24522470

24532471
static const struct dev_pm_ops tegra_pcie_dw_pm_ops = {
2472+
.suspend = tegra_pcie_dw_suspend,
24542473
.suspend_late = tegra_pcie_dw_suspend_late,
24552474
.suspend_noirq = tegra_pcie_dw_suspend_noirq,
24562475
.resume_noirq = tegra_pcie_dw_resume_noirq,

0 commit comments

Comments
 (0)