diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2011-07-12 16:16:14 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-07-15 16:49:30 -0700 |
commit | abe8c45b7e86f7d9ee2c508b6cae8acdbb624563 (patch) | |
tree | 566ebc06242e8df4cd4e988211377b1e8c1b3905 /arch | |
parent | 621614719837f9ff5664d9de523930ca3b216a7a (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu.c | 55 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-ventana.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/suspend.h | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/suspend.c | 22 |
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); |