summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-07-12 16:16:14 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-07-15 16:49:30 -0700
commitabe8c45b7e86f7d9ee2c508b6cae8acdbb624563 (patch)
tree566ebc06242e8df4cd4e988211377b1e8c1b3905
parent621614719837f9ff5664d9de523930ca3b216a7a (diff)
arm: tegra: suspend: Add board specific suspend/resume calls
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 Change-Id: Ia9ff3b8a8d2faa1071a8ff634960e6a6c8a43d40 Reviewed-on: http://git-master/r/34494 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c55
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c3
-rw-r--r--arch/arm/mach-tegra/board-ventana.c3
-rw-r--r--arch/arm/mach-tegra/include/mach/suspend.h16
-rw-r--r--arch/arm/mach-tegra/suspend.c22
5 files changed, 69 insertions, 30 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 490cc6981085..85222bfe8d9c 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -50,6 +50,7 @@
#include <asm/mach/arch.h>
#include <mach/usb_phy.h>
#include <sound/wm8903.h>
+#include <mach/suspend.h>
#include "board.h"
#include "clock.h"
@@ -446,8 +447,35 @@ static struct tegra_uart_platform_data cardhu_uart_pdata;
static void __init uart_debug_init(void)
{
struct board_info board_info;
- int i;
+
+ tegra_get_board_info(&board_info);
+ if (board_info.sku & SKU_SLT_ULPI_SUPPORT) {
+ if ((board_info.board_id == BOARD_E1186) ||
+ (board_info.board_id == BOARD_E1187) ||
+ (board_info.board_id == BOARD_PM269)) {
+ /* UARTB is the debug port. */
+ pr_info("Selecting UARTB as the debug console\n");
+ cardhu_uart_devices[1] = &debug_uartb_device;
+ debug_uart_clk = clk_get_sys("serial8250.0", "uartb");
+ debug_uart_port_base = ((struct plat_serial8250_port *)(
+ debug_uartb_device.dev.platform_data))->mapbase;
+ return;
+ }
+ pr_err("%s(): Unhandled SKU information for Board 0x%04x\n",
+ __func__, board_info.board_id);
+ }
+ /* UARTA is the debug port. */
+ pr_info("Selecting UARTA as the debug console\n");
+ cardhu_uart_devices[0] = &debug_uarta_device;
+ debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
+ debug_uart_port_base = ((struct plat_serial8250_port *)(
+ debug_uarta_device.dev.platform_data))->mapbase;
+}
+
+static void __init cardhu_uart_init(void)
+{
struct clk *c;
+ int i;
for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
c = tegra_get_clock_by_name(uart_parent_clk[i].name);
@@ -467,31 +495,6 @@ static void __init uart_debug_init(void)
tegra_uartd_device.dev.platform_data = &cardhu_uart_pdata;
tegra_uarte_device.dev.platform_data = &cardhu_uart_pdata;
- tegra_get_board_info(&board_info);
- if (board_info.sku & SKU_SLT_ULPI_SUPPORT) {
- if ((board_info.board_id == BOARD_E1186) ||
- (board_info.board_id == BOARD_E1187) ||
- (board_info.board_id == BOARD_E1256) ||
- (board_info.board_id == BOARD_PM269)) {
- /* UARTB is the debug port. */
- pr_info("Selecting UARTB as the debug console\n");
- cardhu_uart_devices[1] = &debug_uartb_device;
- debug_uart_clk =
- clk_get_sys("serial8250.0", "uartb");
- return;
- }
- pr_err("%s(): Unhandled SKU information for Board 0x%04x\n",
- __func__, board_info.board_id);
- }
- /* UARTA is the debug port. */
- pr_info("Selecting UARTA as the debug console\n");
- cardhu_uart_devices[0] = &debug_uarta_device;
- debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
-}
-
-static void __init cardhu_uart_init(void)
-{
- struct clk *c;
/* Register low speed only if it is selected */
if (!is_tegra_debug_uartport_hs()) {
uart_debug_init();
diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c
index 33277c313594..245bc3bc58d1 100644
--- a/arch/arm/mach-tegra/board-enterprise.c
+++ b/arch/arm/mach-tegra/board-enterprise.c
@@ -49,6 +49,7 @@
#include <asm/mach/arch.h>
#include <mach/usb_phy.h>
#include <sound/max98088.h>
+#include <mach/suspend.h>
#include "board.h"
#include "clock.h"
@@ -476,6 +477,8 @@ static void __init uart_debug_init(void)
/* UARTD is the debug port. */
pr_info("Selecting UARTD as the debug console\n");
enterprise_uart_devices[3] = &debug_uartd_device;
+ debug_uart_port_base = ((struct plat_serial8250_port *)(
+ debug_uartd_device.dev.platform_data))->mapbase;
debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
/* Clock enable for the debug channel */
diff --git a/arch/arm/mach-tegra/board-ventana.c b/arch/arm/mach-tegra/board-ventana.c
index 8abc4e1d6946..9a701fce3439 100644
--- a/arch/arm/mach-tegra/board-ventana.c
+++ b/arch/arm/mach-tegra/board-ventana.c
@@ -53,6 +53,7 @@
#include <asm/mach/arch.h>
#include <mach/usb_phy.h>
#include <mach/tegra_das.h>
+#include <mach/suspend.h>
#include "board.h"
#include "clock.h"
@@ -526,6 +527,8 @@ static void __init uart_debug_init(void)
/* UARTD is the debug port. */
pr_info("Selecting UARTD as the debug console\n");
ventana_uart_devices[2] = &debug_uartd_device;
+ debug_uart_port_base = ((struct plat_serial8250_port *)(
+ debug_uartd_device.dev.platform_data))->mapbase;
debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
/* Clock enable for the debug channel */
diff --git a/arch/arm/mach-tegra/include/mach/suspend.h b/arch/arm/mach-tegra/include/mach/suspend.h
index d4d115dc9177..b4dc2fd1fa56 100644
--- a/arch/arm/mach-tegra/include/mach/suspend.h
+++ b/arch/arm/mach-tegra/include/mach/suspend.h
@@ -31,6 +31,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 separate_req; /* Core & CPU power request are separate */
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);
@@ -94,4 +107,7 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat);
*/
extern void (*tegra_deep_sleep)(int);
+/* The debug channel uart base physical address */
+extern unsigned long debug_uart_port_base;
+
#endif /* _MACH_TEGRA_SUSPEND_H_ */
diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c
index b2f5e1e12c67..4a9f93479908 100644
--- a/arch/arm/mach-tegra/suspend.c
+++ b/arch/arm/mach-tegra/suspend.c
@@ -633,6 +633,11 @@ void tegra_suspend_dram(bool do_lp0)
reg = readl(pmc + PMC_CTRL);
mode |= ((reg >> TEGRA_POWER_PMC_SHIFT) & TEGRA_POWER_PMC_MASK);
+ if (pdata && pdata->board_suspend) {
+ int lp_state = (do_lp0) ? 0 : 1;
+ pdata->board_suspend(lp_state, TEGRA_SUSPEND_BEFORE_CPU);
+ }
+
if (!do_lp0) {
cpu = cpu_number();
@@ -755,16 +760,18 @@ static void tegra_suspend_wake(void)
}
static u8 uart_state[5];
+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);
@@ -792,10 +799,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 = uart_state[0];
@@ -956,6 +963,8 @@ static int tegra_suspend_enter(suspend_state_t state)
local_fiq_disable();
pr_info("Entering suspend state LP%d\n", lp_state);
+ if (pdata && pdata->board_suspend)
+ pdata->board_suspend(lp_state, TEGRA_SUSPEND_BEFORE_PERIPHERAL);
if (do_lp0) {
tegra_lp0_cpu_mode(true);
tegra_irq_suspend();
@@ -1000,6 +1009,9 @@ static int tegra_suspend_enter(suspend_state_t state)
/* Clear DPD sample */
writel(0x0, pmc + PMC_DPD_SAMPLE);
+ if (pdata && pdata->board_resume)
+ pdata->board_resume(lp_state, TEGRA_RESUME_AFTER_CPU);
+
if (do_lp0) {
writel(mc_data[0], mc + MC_SECURITY_START);
writel(mc_data[1], mc + MC_SECURITY_SIZE);
@@ -1018,6 +1030,8 @@ static int tegra_suspend_enter(suspend_state_t state)
tegra_irq_resume();
tegra_lp0_cpu_mode(false);
}
+ if (pdata && pdata->board_resume)
+ pdata->board_resume(lp_state, TEGRA_RESUME_AFTER_PERIPHERAL);
secs = rtc_after - rtc_before;
ms = do_div(secs, 1000);