summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/pm-t3.c3
-rw-r--r--arch/arm/mach-tegra/pm.c66
-rw-r--r--arch/arm/mach-tegra/pm.h8
-rw-r--r--arch/arm64/mach-tegra/pm.c14
-rw-r--r--drivers/platform/tegra/Makefile1
-rw-r--r--drivers/platform/tegra/pm.c92
-rw-r--r--include/linux/tegra-pm.h19
-rw-r--r--include/linux/tegra-pmc.h10
8 files changed, 116 insertions, 97 deletions
diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c
index 371f48448ac6..167f796271c9 100644
--- a/arch/arm/mach-tegra/pm-t3.c
+++ b/arch/arm/mach-tegra/pm-t3.c
@@ -3,7 +3,7 @@
*
* Tegra3 SOC-specific power and cluster management
*
- * Copyright (c) 2009-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2009-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,6 +33,7 @@
#include <linux/tegra-powergate.h>
#include <linux/tegra-soc.h>
#include <linux/tegra-cpuidle.h>
+#include <linux/tegra-pm.h>
#include <mach/irqs.h>
#include <mach/io_dpd.h>
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 16e9b2cf55a9..4d4415f54a61 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -134,8 +134,6 @@ static u64 suspend_time;
static u64 suspend_entry_time;
#endif
-static RAW_NOTIFIER_HEAD(tegra_pm_chain_head);
-
#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
static void update_pmc_registers(unsigned long rate);
#endif
@@ -281,27 +279,6 @@ void tegra_cluster_switch_time(unsigned int flags, int id)
}
#endif
-int tegra_register_pm_notifier(struct notifier_block *nb)
-{
- return raw_notifier_chain_register(&tegra_pm_chain_head, nb);
-}
-EXPORT_SYMBOL(tegra_register_pm_notifier);
-
-int tegra_unregister_pm_notifier(struct notifier_block *nb)
-{
- return raw_notifier_chain_unregister(&tegra_pm_chain_head, nb);
-}
-EXPORT_SYMBOL(tegra_unregister_pm_notifier);
-
-#ifdef CONFIG_TEGRA_LP0_IN_IDLE
-static int tegra_pm_notifier_call_chain(unsigned int val)
-{
- int ret = raw_notifier_call_chain(&tegra_pm_chain_head, val, NULL);
-
- return notifier_to_errno(ret);
-}
-#endif
-
#ifdef CONFIG_PM_SLEEP
static const char *tegra_suspend_name[TEGRA_MAX_SUSPEND_MODE] = {
[TEGRA_SUSPEND_NONE] = "none",
@@ -1331,49 +1308,6 @@ static void tegra_disable_lp1bb_interrupt(void)
}
#endif
-#ifdef CONFIG_TEGRA_LP0_IN_IDLE
-int tegra_enter_lp0(unsigned long sleep_time)
-{
- int err = 0;
-
- /* This state is managed by power domains, hence no voice call expected if
- * we are entering this state */
-
- tegra_pm_notifier_call_chain(TEGRA_PM_SUSPEND);
-
- tegra_rtc_set_trigger(sleep_time);
-
- tegra_actmon_save();
-
- tegra_dma_save();
-
- tegra_smmu_save();
-
- err = syscore_save();
- if (err) {
- tegra_smmu_restore();
- tegra_dma_restore();
- tegra_rtc_set_trigger(0);
- return err;
- }
-
- tegra_suspend_dram(TEGRA_SUSPEND_LP0, 0);
-
- syscore_restore();
-
- tegra_smmu_restore();
-
- tegra_dma_restore();
-
- tegra_actmon_restore();
-
- tegra_rtc_set_trigger(0);
-
- tegra_pm_notifier_call_chain(TEGRA_PM_RESUME);
-
- return 0;
-}
-#endif
int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
{
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index cda2282e1ae4..d2eb583985ae 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -30,6 +30,7 @@
#include <linux/errno.h>
#include <linux/clkdev.h>
#include <linux/tegra-pmc.h>
+#include <linux/tegra-pm.h>
#include "iomap.h"
@@ -112,13 +113,6 @@ bool tegra_set_cpu_in_pd(int cpu);
void tegra_mc_clk_prepare(void);
void tegra_mc_clk_finish(void);
-int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags);
-#ifdef CONFIG_TEGRA_LP0_IN_IDLE
-int tegra_enter_lp0(unsigned long sleep_time);
-#else
-static inline int tegra_enter_lp0(unsigned long sleep_time)
-{ return 0; }
-#endif
#ifdef CONFIG_TEGRA_LP1_LOW_COREVOLTAGE
int tegra_is_lp1_suspend_mode(void);
#endif
diff --git a/arch/arm64/mach-tegra/pm.c b/arch/arm64/mach-tegra/pm.c
index 58b56ab792a0..f5bf54445a61 100644
--- a/arch/arm64/mach-tegra/pm.c
+++ b/arch/arm64/mach-tegra/pm.c
@@ -127,8 +127,6 @@ static u64 suspend_time;
static u64 suspend_entry_time;
#endif
-static RAW_NOTIFIER_HEAD(tegra_pm_chain_head);
-
struct suspend_context tegra_sctx;
#define TEGRA_POWER_PWRREQ_POLARITY (1 << 8) /* core power request polarity */
@@ -216,18 +214,6 @@ bool tegra_suspend_in_progress(void)
return suspend_in_progress;
}
-int tegra_register_pm_notifier(struct notifier_block *nb)
-{
- return raw_notifier_chain_register(&tegra_pm_chain_head, nb);
-}
-EXPORT_SYMBOL(tegra_register_pm_notifier);
-
-int tegra_unregister_pm_notifier(struct notifier_block *nb)
-{
- return raw_notifier_chain_unregister(&tegra_pm_chain_head, nb);
-}
-EXPORT_SYMBOL(tegra_unregister_pm_notifier);
-
bool tegra_dvfs_is_dfll_bypass(void)
{
#ifdef CONFIG_REGULATOR_TEGRA_DFLL_BYPASS
diff --git a/drivers/platform/tegra/Makefile b/drivers/platform/tegra/Makefile
index 918e2af246b6..50d5e494b02f 100644
--- a/drivers/platform/tegra/Makefile
+++ b/drivers/platform/tegra/Makefile
@@ -15,6 +15,7 @@ endif
obj-y += mc/
obj-$(CONFIG_PM_SLEEP) += pm-irq.o
obj-y += pmc.o
+obj-y += pm.o
obj-$(CONFIG_TEGRA_MC_DOMAINS) += pm_domains.o
diff --git a/drivers/platform/tegra/pm.c b/drivers/platform/tegra/pm.c
new file mode 100644
index 000000000000..654ff2460349
--- /dev/null
+++ b/drivers/platform/tegra/pm.c
@@ -0,0 +1,92 @@
+/*
+ * drivers/platform/tegra/pm.c
+ *
+ * CPU complex suspend & resume functions for Tegra SoCs
+ *
+ * Copyright (c) 2009-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/notifier.h>
+#include <linux/tegra_pm_domains.h>
+
+static RAW_NOTIFIER_HEAD(tegra_pm_chain_head);
+
+int tegra_register_pm_notifier(struct notifier_block *nb)
+{
+ return raw_notifier_chain_register(&tegra_pm_chain_head, nb);
+}
+EXPORT_SYMBOL(tegra_register_pm_notifier);
+
+int tegra_unregister_pm_notifier(struct notifier_block *nb)
+{
+ return raw_notifier_chain_unregister(&tegra_pm_chain_head, nb);
+}
+EXPORT_SYMBOL(tegra_unregister_pm_notifier);
+
+#ifdef CONFIG_TEGRA_LP0_IN_IDLE
+static int tegra_pm_notifier_call_chain(unsigned int val)
+{
+ int ret = raw_notifier_call_chain(&tegra_pm_chain_head, val, NULL);
+
+ return notifier_to_errno(ret);
+}
+
+int tegra_enter_lp0(unsigned long sleep_time)
+{
+ int err = 0;
+
+ /*
+ * This state is managed by power domains,
+ * hence no voice call expected if
+ * we are entering this state
+ */
+
+ tegra_pm_notifier_call_chain(TEGRA_PM_SUSPEND);
+
+ tegra_rtc_set_trigger(sleep_time);
+
+ tegra_actmon_save();
+
+ tegra_dma_save();
+
+ tegra_smmu_save();
+
+ err = syscore_save();
+ if (err) {
+ tegra_smmu_restore();
+ tegra_dma_restore();
+ tegra_rtc_set_trigger(0);
+ return err;
+ }
+
+ tegra_suspend_dram(TEGRA_SUSPEND_LP0, 0);
+
+ syscore_restore();
+
+ tegra_smmu_restore();
+
+ tegra_dma_restore();
+
+ tegra_actmon_restore();
+
+ tegra_rtc_set_trigger(0);
+
+ tegra_pm_notifier_call_chain(TEGRA_PM_RESUME);
+
+ return 0;
+}
+#endif
diff --git a/include/linux/tegra-pm.h b/include/linux/tegra-pm.h
index 37ccc88cbbf6..38d5ba6e5e8d 100644
--- a/include/linux/tegra-pm.h
+++ b/include/linux/tegra-pm.h
@@ -1,7 +1,7 @@
/*
* include/linux/tegra-pm.h
*
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,7 +23,24 @@
#define TEGRA_PM_SUSPEND 0x0001
#define TEGRA_PM_RESUME 0x0002
+enum tegra_suspend_mode {
+ TEGRA_SUSPEND_NONE = 0,
+ TEGRA_SUSPEND_LP2, /* CPU voltage off */
+ TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
+ TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
+ TEGRA_MAX_SUSPEND_MODE,
+};
+
+int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags);
+
int tegra_register_pm_notifier(struct notifier_block *nb);
int tegra_unregister_pm_notifier(struct notifier_block *nb);
+#ifdef CONFIG_TEGRA_LP0_IN_IDLE
+int tegra_enter_lp0(unsigned long sleep_time);
+#else
+static inline int tegra_enter_lp0(unsigned long sleep_time)
+{ return 0; }
+#endif
+
#endif /* _LINUX_TEGRA_PM_H_ */
diff --git a/include/linux/tegra-pmc.h b/include/linux/tegra-pmc.h
index 002f8849905d..1bcb11a81449 100644
--- a/include/linux/tegra-pmc.h
+++ b/include/linux/tegra-pmc.h
@@ -21,6 +21,8 @@
#ifndef __LINUX_TEGRA_PMC_H__
#define __LINUX_TEGRA_PMC_H__
+#include <linux/tegra-pm.h>
+
extern void tegra_pmc_set_dpd_sample(void);
extern void tegra_pmc_clear_dpd_sample(void);
extern void tegra_pmc_remove_dpd_req(void);
@@ -28,14 +30,6 @@ extern void __iomem *tegra_pmc_base;
extern bool tegra_is_dpd_mode;
-enum tegra_suspend_mode {
- TEGRA_SUSPEND_NONE = 0,
- TEGRA_SUSPEND_LP2, /* CPU voltage off */
- TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
- TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
- TEGRA_MAX_SUSPEND_MODE,
-};
-
struct pmc_pm_data {
u32 cpu_good_time; /* CPU power good time in uS */
u32 cpu_off_time; /* CPU power off time in uS */