unknown changes from android-tegra-nv-3.4
[linux-3.10.git] / arch / arm / mach-tegra / pm-t3.c
index a738957..595e405 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra3 SOC-specific power and cluster management
  *
- * Copyright (c) 2009-2011, NVIDIA Corporation.
+ * Copyright (c) 2009-2012, NVIDIA Corporation.
  *
  * 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
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
-#include <linux/cpu_pm.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/clockchips.h>
+#include <linux/cpu_pm.h>
 
 #include <mach/gpio.h>
 #include <mach/irqs.h>
@@ -37,7 +38,6 @@
 
 #include "clock.h"
 #include "cpuidle.h"
-#include "flowctrl.h"
 #include "iomap.h"
 #include "pm.h"
 #include "sleep.h"
@@ -199,13 +199,13 @@ void tegra_cluster_switch_prolog(unsigned int flags)
        /* Read the flow controler CSR register and clear the CPU switch
           and immediate flags. If an actual CPU switch is to be performed,
           re-write the CSR register with the desired values. */
-       reg = flowctrl_read_cpu_csr(0);
-       reg &= ~(FLOW_CTRL_CSR_IMMEDIATE_WAKE |
-                FLOW_CTRL_CSR_SWITCH_CLUSTER);
+       reg = readl(FLOW_CTRL_CPU_CSR(0));
+       reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE |
+                FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER);
 
        /* Program flow controller for immediate wake if requested */
        if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
-               reg |= FLOW_CTRL_CSR_IMMEDIATE_WAKE;
+               reg |= FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE;
 
        /* Do nothing if no switch actions requested */
        if (!target_cluster)
@@ -221,12 +221,12 @@ void tegra_cluster_switch_prolog(unsigned int flags)
                        }
 
                        /* Set up the flow controller to switch CPUs. */
-                       reg |= FLOW_CTRL_CSR_SWITCH_CLUSTER;
+                       reg |= FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER;
                }
        }
 
 done:
-       flowctrl_write_cpu_csr(0, reg);
+       writel(reg, FLOW_CTRL_CPU_CSR(0));
 }
 
 
@@ -293,10 +293,10 @@ void tegra_cluster_switch_epilog(unsigned int flags)
        /* Make sure the switch and immediate flags are cleared in
           the flow controller to prevent undesirable side-effects
           for future users of the flow controller. */
-       reg = flowctrl_read_cpu_csr(0);
-       reg &= ~(FLOW_CTRL_CSR_IMMEDIATE_WAKE |
-                FLOW_CTRL_CSR_SWITCH_CLUSTER);
-       flowctrl_write_cpu_csr(0, reg);
+       reg = readl(FLOW_CTRL_CPU_CSR(0));
+       reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE |
+                FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER);
+       writel(reg, FLOW_CTRL_CPU_CSR(0));
 
        /* Perform post-switch LP=>G clean-up */
        if (!is_lp_cluster()) {
@@ -381,9 +381,17 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
                if (us)
                        tegra_lp2_set_trigger(0);
        } else {
+               int cpu = 0;
+
                tegra_set_cpu_in_lp2(0);
                cpu_pm_enter();
+               if (!timekeeping_suspended)
+                       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+                                          &cpu);
                tegra_idle_lp2_last(0, flags);
+               if (!timekeeping_suspended)
+                       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+                                          &cpu);
                cpu_pm_exit();
                tegra_clear_cpu_in_lp2(0);
        }
@@ -421,6 +429,7 @@ void tegra_lp0_cpu_mode(bool enter)
                flags = enter ? TEGRA_POWER_CLUSTER_LP : TEGRA_POWER_CLUSTER_G;
                flags |= TEGRA_POWER_CLUSTER_IMMEDIATE;
                tegra_cluster_control(0, flags);
+               pr_info("Tegra: switched to %s cluster\n", enter ? "LP" : "G");
        }
 }
 #endif