]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/cpufreq/tegra124-cpufreq.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux.git] / drivers / cpufreq / tegra124-cpufreq.c
index 5e748c8a5c9a99fc57da89a50005ddd9447fb302..7a1ea6fdcab62237d08842dd14b04483a3b07392 100644 (file)
@@ -1,19 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Tegra 124 cpufreq driver
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
 
 #include <linux/clk.h>
+#include <linux/cpufreq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -136,8 +129,66 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
        return ret;
 }
 
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
+{
+       struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+       int err;
+
+       /*
+        * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+        * use during suspend and resume. So, switch the CPU clock source
+        * to PLLP and disable DFLL.
+        */
+       err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+       if (err < 0) {
+               dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+               return err;
+       }
+
+       clk_disable_unprepare(priv->dfll_clk);
+
+       return 0;
+}
+
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+       struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+       int err;
+
+       /*
+        * Warmboot code powers up the CPU with PLLP clock source.
+        * Enable DFLL clock and switch CPU clock source back to DFLL.
+        */
+       err = clk_prepare_enable(priv->dfll_clk);
+       if (err < 0) {
+               dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+               goto disable_cpufreq;
+       }
+
+       err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+       if (err < 0) {
+               dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+               goto disable_dfll;
+       }
+
+       return 0;
+
+disable_dfll:
+       clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+       disable_cpufreq();
+
+       return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+                               tegra124_cpufreq_resume)
+};
+
 static struct platform_driver tegra124_cpufreq_platdrv = {
        .driver.name    = "cpufreq-tegra124",
+       .driver.pm      = &tegra124_cpufreq_pm_ops,
        .probe          = tegra124_cpufreq_probe,
 };