-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARM: S5P64X0: Add Power Management support
Add suspend-to-ram support for SMDK6440/50 Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
- Loading branch information
Abhilash Kesavan
authored and
Kukjin Kim
committed
Oct 4, 2011
1 parent
e2e1362
commit 6b6844d
Showing
10 changed files
with
472 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* linux/arch/arm/mach-s5p64x0/include/mach/pm-core.h | ||
* | ||
* Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
* http://www.samsung.com | ||
* | ||
* S5P64X0 - PM core support for arch/arm/plat-samsung/pm.c | ||
* | ||
* Based on PM core support for S3C64XX by Ben Dooks | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <mach/regs-gpio.h> | ||
|
||
static inline void s3c_pm_debug_init_uart(void) | ||
{ | ||
u32 tmp = __raw_readl(S5P64X0_CLK_GATE_PCLK); | ||
|
||
/* | ||
* As a note, since the S5P64X0 UARTs generally have multiple | ||
* clock sources, we simply enable PCLK at the moment and hope | ||
* that the resume settings for the UART are suitable for the | ||
* use with PCLK. | ||
*/ | ||
tmp |= S5P64X0_CLK_GATE_PCLK_UART0; | ||
tmp |= S5P64X0_CLK_GATE_PCLK_UART1; | ||
tmp |= S5P64X0_CLK_GATE_PCLK_UART2; | ||
tmp |= S5P64X0_CLK_GATE_PCLK_UART3; | ||
|
||
__raw_writel(tmp, S5P64X0_CLK_GATE_PCLK); | ||
udelay(10); | ||
} | ||
|
||
static inline void s3c_pm_arch_prepare_irqs(void) | ||
{ | ||
/* VIC should have already been taken care of */ | ||
|
||
/* clear any pending EINT0 interrupts */ | ||
__raw_writel(__raw_readl(S5P64X0_EINT0PEND), S5P64X0_EINT0PEND); | ||
} | ||
|
||
static inline void s3c_pm_arch_stop_clocks(void) { } | ||
static inline void s3c_pm_arch_show_resume_irqs(void) { } | ||
|
||
/* | ||
* make these defines, we currently do not have any need to change | ||
* the IRQ wake controls depending on the CPU we are running on | ||
*/ | ||
#define s3c_irqwake_eintallow ((1 << 16) - 1) | ||
#define s3c_irqwake_intallow (~0) | ||
|
||
static inline void s3c_pm_arch_update_uart(void __iomem *regs, | ||
struct pm_uart_save *save) | ||
{ | ||
u32 ucon = __raw_readl(regs + S3C2410_UCON); | ||
u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK; | ||
u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK; | ||
u32 new_ucon; | ||
u32 delta; | ||
|
||
/* | ||
* S5P64X0 UART blocks only support level interrupts, so ensure that | ||
* when we restore unused UART blocks we force the level interrupt | ||
* settings. | ||
*/ | ||
save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL; | ||
|
||
/* | ||
* We have a constraint on changing the clock type of the UART | ||
* between UCLKx and PCLK, so ensure that when we restore UCON | ||
* that the CLK field is correctly modified if the bootloader | ||
* has changed anything. | ||
*/ | ||
if (ucon_clk != save_clk) { | ||
new_ucon = save->ucon; | ||
delta = ucon_clk ^ save_clk; | ||
|
||
/* | ||
* change from UCLKx => wrong PCLK, | ||
* either UCLK can be tested for by a bit-test | ||
* with UCLK0 | ||
*/ | ||
if (ucon_clk & S3C6400_UCON_UCLK0 && | ||
!(save_clk & S3C6400_UCON_UCLK0) && | ||
delta & S3C6400_UCON_PCLK2) { | ||
new_ucon &= ~S3C6400_UCON_UCLK0; | ||
} else if (delta == S3C6400_UCON_PCLK2) { | ||
/* | ||
* as a precaution, don't change from | ||
* PCLK2 => PCLK or vice-versa | ||
*/ | ||
new_ucon ^= S3C6400_UCON_PCLK2; | ||
} | ||
|
||
S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n", | ||
ucon, new_ucon, save->ucon); | ||
save->ucon = new_ucon; | ||
} | ||
} | ||
|
||
static inline void s3c_pm_restored_gpios(void) | ||
{ | ||
/* ensure sleep mode has been cleared from the system */ | ||
__raw_writel(0, S5P64X0_SLPEN); | ||
} | ||
|
||
static inline void samsung_pm_saved_gpios(void) | ||
{ | ||
/* | ||
* turn on the sleep mode and keep it there, as it seems that during | ||
* suspend the xCON registers get re-set and thus you can end up with | ||
* problems between going to sleep and resuming. | ||
*/ | ||
__raw_writel(S5P64X0_SLPEN_USE_xSLP, S5P64X0_SLPEN); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* linux/arch/arm/mach-s5p64x0/irq-pm.c | ||
* | ||
* Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
* http://www.samsung.com | ||
* | ||
* S5P64X0 - Interrupt handling Power Management | ||
* | ||
* Based on arch/arm/mach-s3c64xx/irq-pm.c by Ben Dooks | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/syscore_ops.h> | ||
#include <linux/serial_core.h> | ||
#include <linux/io.h> | ||
|
||
#include <plat/regs-serial.h> | ||
#include <plat/pm.h> | ||
|
||
#include <mach/regs-gpio.h> | ||
|
||
static struct sleep_save irq_save[] = { | ||
SAVE_ITEM(S5P64X0_EINT0CON0), | ||
SAVE_ITEM(S5P64X0_EINT0FLTCON0), | ||
SAVE_ITEM(S5P64X0_EINT0FLTCON1), | ||
SAVE_ITEM(S5P64X0_EINT0MASK), | ||
}; | ||
|
||
static struct irq_grp_save { | ||
u32 con; | ||
u32 fltcon; | ||
u32 mask; | ||
} eint_grp_save[4]; | ||
|
||
static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS]; | ||
|
||
static int s5p64x0_irq_pm_suspend(void) | ||
{ | ||
struct irq_grp_save *grp = eint_grp_save; | ||
int i; | ||
|
||
S3C_PMDBG("%s: suspending IRQs\n", __func__); | ||
|
||
s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); | ||
|
||
for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) | ||
irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM); | ||
|
||
for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { | ||
grp->con = __raw_readl(S5P64X0_EINT12CON + (i * 4)); | ||
grp->mask = __raw_readl(S5P64X0_EINT12MASK + (i * 4)); | ||
grp->fltcon = __raw_readl(S5P64X0_EINT12FLTCON + (i * 4)); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static void s5p64x0_irq_pm_resume(void) | ||
{ | ||
struct irq_grp_save *grp = eint_grp_save; | ||
int i; | ||
|
||
S3C_PMDBG("%s: resuming IRQs\n", __func__); | ||
|
||
s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); | ||
|
||
for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) | ||
__raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM); | ||
|
||
for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { | ||
__raw_writel(grp->con, S5P64X0_EINT12CON + (i * 4)); | ||
__raw_writel(grp->mask, S5P64X0_EINT12MASK + (i * 4)); | ||
__raw_writel(grp->fltcon, S5P64X0_EINT12FLTCON + (i * 4)); | ||
} | ||
|
||
S3C_PMDBG("%s: IRQ configuration restored\n", __func__); | ||
} | ||
|
||
static struct syscore_ops s5p64x0_irq_syscore_ops = { | ||
.suspend = s5p64x0_irq_pm_suspend, | ||
.resume = s5p64x0_irq_pm_resume, | ||
}; | ||
|
||
static int __init s5p64x0_syscore_init(void) | ||
{ | ||
register_syscore_ops(&s5p64x0_irq_syscore_ops); | ||
|
||
return 0; | ||
} | ||
core_initcall(s5p64x0_syscore_init); |
Oops, something went wrong.