summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehoon Chung <jh80.chung@samsung.com>2015-04-23 13:40:56 +0900
committerSeung-Woo Kim <sw0312.kim@samsung.com>2016-12-14 13:44:39 +0900
commit239e0773cb3217ea01608479f791a1fc88b1640d (patch)
tree54dae9d37c6592d8c8c4a372f1a017f78421bdd4
parent674b3281a8133d1a99a4a6f3130e3733ba6c879f (diff)
local/pci: pci-exynos5433: add suspend/resume_noirq for pm_ops
Add suspend/resume_noirq for pm_ops. Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
-rw-r--r--drivers/pci/host/pci-exynos5433.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-exynos5433.c b/drivers/pci/host/pci-exynos5433.c
index 5f580b027ff8..762c6eb2d2f2 100644
--- a/drivers/pci/host/pci-exynos5433.c
+++ b/drivers/pci/host/pci-exynos5433.c
@@ -611,6 +611,73 @@ static int exynos_pcie_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int exynos_pcie_suspend_noirq(struct device *dev)
+{
+ struct exynos_pcie *ep = dev_get_drvdata(dev);
+
+ if (ep->wlanen_gpio && !gpio_get_value(ep->wlanen_gpio))
+ return 0;
+
+ return 0;
+}
+
+static int exynos_pcie_resume_noirq(struct device *dev)
+{
+ struct exynos_pcie *ep = dev_get_drvdata(dev);
+ struct pcie_port *pp = &ep->pp;
+ u32 val;
+
+ if (ep->wlanen_gpio && !gpio_get_value(ep->wlanen_gpio)) {
+ clk_prepare_enable(ep->clk);
+ clk_prepare_enable(ep->bus_clk);
+
+ exynos_pcie_enable_irq_pulse(&ep->pp);
+
+ /* PMU control at here */
+ if (ep->pmureg) {
+ if (regmap_update_bits(ep->pmureg, PCIE_PMU_PHY_OFFSET, BIT(0), 1))
+ dev_warn(pp->dev, "Failed to update regmap bit.\n");
+ }
+
+ val = exynos_pcie_readl(ep->block_base, PCIE_PHY_GLOBAL_RESET);
+ val &= ~PCIE_APP_REQ_EXIT_L1_MODE;
+ exynos_pcie_writel(ep->block_base, val, PCIE_PHY_GLOBAL_RESET);
+
+ val = exynos_pcie_readl(ep->block_base, PCIE_L1SUB_CM_CON);
+ val &= ~PCIE_REFCLK_GATING_EN;
+ exynos_pcie_writel(ep->block_base, val, PCIE_L1SUB_CM_CON);
+
+ exynos_pcie_assert_phy_reset(pp);
+
+ val = exynos_pcie_readl(ep->phy_base, PCIE_PHY_OFFSET(0x55));
+ val |= PCIE_PHY_ALL_TRSV_PWR_DOWN;
+ exynos_pcie_writel(ep->phy_base, val, PCIE_PHY_OFFSET(0x55));
+
+ val = exynos_pcie_readl(ep->phy_base, PCIE_PHY_OFFSET(0x21));
+ val |= PCIE_PHY_ALL_CMN_PWR_DOWN;
+ exynos_pcie_writel(ep->phy_base, val, PCIE_PHY_OFFSET(0x21));
+
+ clk_disable_unprepare(ep->bus_clk);
+ clk_disable_unprepare(ep->clk);
+
+ return 0;
+ }
+
+ exynos_pcie_host_init(pp);
+
+ return 0;
+}
+#else
+#define exynos_pcie_suspend_noirq NULL
+#define exynos_pcie_resume_noirq NULL
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops exynos_pcie_pm_ops = {
+ .suspend_noirq = exynos_pcie_suspend_noirq,
+ .resume_noirq = exynos_pcie_resume_noirq,
+};
+
static const struct of_device_id exynos_pcie_of_match[] = {
{ .compatible = "samsung,exynos5433-pcie", },
{},
@@ -622,6 +689,7 @@ static struct platform_driver exynos_pcie_driver = {
.driver = {
.name = "exynos-pcie",
.of_match_table = exynos_pcie_of_match,
+ .pm = &exynos_pcie_pm_ops,
},
};