Skip to content

Commit e697ea9

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 849068f commit e697ea9

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
@@ -2304,16 +2304,28 @@ static void tegra_pcie_dw_remove(struct platform_device *pdev)
23042304
gpiod_set_value(pcie->pex_refclk_sel_gpiod, 0);
23052305
}
23062306

2307-
static int tegra_pcie_dw_suspend_late(struct device *dev)
2307+
static int tegra_pcie_dw_suspend(struct device *dev)
23082308
{
23092309
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
2310-
u32 val;
23112310

23122311
if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
2313-
dev_err(dev, "Failed to Suspend as Tegra PCIe is in EP mode\n");
2314-
return -EPERM;
2312+
if (pcie->ep_state == EP_STATE_ENABLED) {
2313+
dev_err(dev, "Tegra PCIe is in EP mode, suspend not allowed\n");
2314+
return -EPERM;
2315+
}
2316+
2317+
disable_irq(pcie->pex_rst_irq);
2318+
return 0;
23152319
}
23162320

2321+
return 0;
2322+
}
2323+
2324+
static int tegra_pcie_dw_suspend_late(struct device *dev)
2325+
{
2326+
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
2327+
u32 val;
2328+
23172329
if (!pcie->link_state)
23182330
return 0;
23192331

@@ -2333,6 +2345,9 @@ static int tegra_pcie_dw_suspend_noirq(struct device *dev)
23332345
{
23342346
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
23352347

2348+
if (pcie->of_data->mode == DW_PCIE_EP_TYPE)
2349+
return 0;
2350+
23362351
if (!pcie->link_state)
23372352
return 0;
23382353

@@ -2347,6 +2362,9 @@ static int tegra_pcie_dw_resume_noirq(struct device *dev)
23472362
struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
23482363
int ret;
23492364

2365+
if (pcie->of_data->mode == DW_PCIE_EP_TYPE)
2366+
return 0;
2367+
23502368
if (!pcie->link_state)
23512369
return 0;
23522370

@@ -2379,8 +2397,8 @@ static int tegra_pcie_dw_resume_early(struct device *dev)
23792397
u32 val;
23802398

23812399
if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
2382-
dev_err(dev, "Suspend is not supported in EP mode");
2383-
return -ENOTSUPP;
2400+
enable_irq(pcie->pex_rst_irq);
2401+
return 0;
23842402
}
23852403

23862404
if (!pcie->link_state)
@@ -2485,6 +2503,7 @@ static const struct of_device_id tegra_pcie_dw_of_match[] = {
24852503
};
24862504

24872505
static const struct dev_pm_ops tegra_pcie_dw_pm_ops = {
2506+
.suspend = tegra_pcie_dw_suspend,
24882507
.suspend_late = tegra_pcie_dw_suspend_late,
24892508
.suspend_noirq = tegra_pcie_dw_suspend_noirq,
24902509
.resume_noirq = tegra_pcie_dw_resume_noirq,

0 commit comments

Comments
 (0)