summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/cpufreq.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/cpufreq.c b/arch/arm/mach-tegra/cpufreq.c
index dd5c45b8a77d..149ad936b00c 100644
--- a/arch/arm/mach-tegra/cpufreq.c
+++ b/arch/arm/mach-tegra/cpufreq.c
@@ -33,6 +33,7 @@
#include <linux/kthread.h>
#include <linux/workqueue.h>
#include <linux/smp_lock.h>
+#include <linux/suspend.h>
#include <asm/system.h>
#include <asm/smp_twd.h>
@@ -50,12 +51,20 @@ static struct clk *clk_cpu = NULL;
static DEFINE_MUTEX(init_mutex);
+#ifdef CONFIG_HOTPLUG_CPU
+static int disable_hotplug = 0;
+#endif
+
static void tegra_cpufreq_hotplug(NvRmPmRequest req)
{
int rc = 0;
#ifdef CONFIG_HOTPLUG_CPU
unsigned int cpu;
+ smp_rmb();
+ if (disable_hotplug)
+ return;
+
if (req & NvRmPmRequest_CpuOnFlag) {
struct cpumask m;
@@ -78,6 +87,28 @@ static void tegra_cpufreq_hotplug(NvRmPmRequest req)
}
+#ifdef CONFIG_HOTPLUG_CPU
+static int tegra_cpufreq_pm_notifier(struct notifier_block *nfb,
+ unsigned long event, void *data)
+{
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ disable_hotplug = 1;
+ smp_wmb();
+ break;
+ case PM_POST_SUSPEND:
+ disable_hotplug = 0;
+ smp_wmb();
+ break;
+ default:
+ pr_err("%s: unknown event %lu\n", __func__, event);
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
+}
+#endif
+
static int tegra_cpufreq_dfsd(void *arg)
{
unsigned long rate, last_rate;
@@ -250,6 +281,9 @@ static struct cpufreq_driver s_tegra_cpufreq_driver = {
static int __init tegra_cpufreq_init(void)
{
+#ifdef CONFIG_HOTPLUG_CPU
+ pm_notifier(tegra_cpufreq_pm_notifier, 0);
+#endif
return cpufreq_register_driver(&s_tegra_cpufreq_driver);
}