arm: tegra: suspend: Add board specific suspend/resume calls
Laxman Dewangan [Tue, 12 Jul 2011 10:46:14 +0000 (15:46 +0530)]
Adding board specific suspend and resume call apis through platform
data.
Added call of these function at appropriate stage of suspend/resume.

Added mechanism to select the uart debug channel base address through
variable so that board file can directly change this.

bug 820536
bug 832273

Original-Change-Id: Ia9ff3b8a8d2faa1071a8ff634960e6a6c8a43d40
Reviewed-on: http://git-master/r/34494
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: R5c4d212ab07463ecbdf263412d4c7a5962dac5a3

arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h

index 2ff62d3..6d36a2b 100644 (file)
@@ -695,7 +695,17 @@ static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {
 
 static int tegra_suspend_enter(suspend_state_t state)
 {
-       return tegra_suspend_dram(current_suspend_mode);
+       int ret;
+
+       if (pdata && pdata->board_suspend)
+               pdata->board_suspend(current_suspend_mode, TEGRA_SUSPEND_BEFORE_PERIPHERAL);
+
+       ret = tegra_suspend_dram(current_suspend_mode);
+
+       if (pdata && pdata->board_resume)
+               pdata->board_resume(current_suspend_mode, TEGRA_RESUME_AFTER_PERIPHERAL);
+
+       return ret;
 }
 
 static void tegra_suspend_check_pwr_stats(void)
@@ -741,6 +751,9 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode)
 
        tegra_pm_set(mode);
 
+       if (pdata && pdata->board_suspend)
+               pdata->board_suspend(mode, TEGRA_SUSPEND_BEFORE_CPU);
+
        local_fiq_disable();
 
        cpu_pm_enter();
@@ -773,6 +786,9 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode)
        cpu_cluster_pm_exit();
        cpu_pm_exit();
 
+       if (pdata && pdata->board_resume)
+               pdata->board_resume(mode, TEGRA_RESUME_AFTER_CPU);
+
        local_fiq_enable();
 
        tegra_common_resume();
@@ -974,15 +990,18 @@ fail:
        current_suspend_mode = plat->suspend_mode;
 }
 
+unsigned long debug_uart_port_base = 0;
+EXPORT_SYMBOL(debug_uart_port_base);
+
 static int tegra_debug_uart_suspend(void)
 {
        void __iomem *uart;
        u32 lcr;
 
-       if (TEGRA_DEBUG_UART_BASE == 0)
+       if (!debug_uart_port_base)
                return 0;
 
-       uart = IO_ADDRESS(TEGRA_DEBUG_UART_BASE);
+       uart = IO_ADDRESS(debug_uart_port_base);
 
        lcr = readb(uart + UART_LCR * 4);
 
@@ -1010,10 +1029,10 @@ static void tegra_debug_uart_resume(void)
        void __iomem *uart;
        u32 lcr;
 
-       if (TEGRA_DEBUG_UART_BASE == 0)
+       if (!debug_uart_port_base)
                return;
 
-       uart = IO_ADDRESS(TEGRA_DEBUG_UART_BASE);
+       uart = IO_ADDRESS(debug_uart_port_base);
 
        lcr = tegra_sctx.uart[0];
 
index 0c6c55d..8da1cff 100644 (file)
@@ -36,6 +36,16 @@ enum tegra_suspend_mode {
        TEGRA_MAX_SUSPEND_MODE,
 };
 
+enum suspend_stage {
+       TEGRA_SUSPEND_BEFORE_PERIPHERAL,
+       TEGRA_SUSPEND_BEFORE_CPU,
+};
+
+enum resume_stage {
+       TEGRA_RESUME_AFTER_PERIPHERAL,
+       TEGRA_RESUME_AFTER_CPU,
+};
+
 struct tegra_suspend_platform_data {
        unsigned long cpu_timer;   /* CPU power good time in us,  LP2/LP1 */
        unsigned long cpu_off_timer;    /* CPU power off time us, LP2/LP1 */
@@ -45,6 +55,9 @@ struct tegra_suspend_platform_data {
        bool sysclkreq_high;       /* System clock request is active-high */
        enum tegra_suspend_mode suspend_mode;
        unsigned long cpu_lp2_min_residency; /* Min LP2 state residency in us */
+       void (*board_suspend)(int lp_state, enum suspend_stage stg);
+       /* lp_state = 0 for LP0 state, 1 for LP1 state, 2 for LP2 state */
+       void (*board_resume)(int lp_state, enum resume_stage stg);
 };
 
 unsigned long tegra_cpu_power_good_time(void);
@@ -195,4 +208,7 @@ extern bool tegra_all_cpus_booted __read_mostly;
 #define tegra_all_cpus_booted (true)
 #endif
 
+/* The debug channel uart base physical address */
+extern unsigned long  debug_uart_port_base;
+
 #endif /* _MACH_TEGRA_PM_H_ */