ARM: exynos4210: Add l2 retention mode cpuidle state
v6 cover ARM: exynos4210: Add l2 retention mode cpuidle state
Changes since V5:
*Rebased the patchset against kernel 3.3-rc4
*Added correct flag for exynos4210 evt1 based board *Removed CONFIG_OF from l2 cache configuration as suggested by
Olof Johansson <[email protected]>
Changes since V4:
*Rebased the patchset against for-next of samsung kernel tree. *Added Tushar suggestion of putting a check if L2 cache dt node not found. *Added Inder suggestion of removing the BUG_ON check in cpuidle driver.
Changes since V3:
*Implemented Russell feedback and moved sleep magic 4byte memory before s3c_cpu_resume to data section.
Changes since V2:
*Implemented the suggestion of MyungJoo Ham and used INFORM0/1 registers for resume for some board versions.
*Added back save/restore through CPU PM notifiers as suggested by Lorenzo Pieralisi. This is useful to restore vfp state. *some patch modularization (s5p/exynos) and proper commit logs.
Changes since V1:
*rebased the whole patch against 3.2-rc1 tree
*removed GIC save/restore in AFTR cpuidle state as it is external to cpu powerdomain
*Added L2 setup code through device tree
*Removed only l2 save/restore registers in sleep
This Patch series adds support for AFTR mode cpuidle state based on patch (http://www.spinics.net/lists/arm-kernel/msg132243.html) earlier submitted by Jaecheol Lee <[email protected]>.
This patch uses CPU PM notifiers , common l2 save/restore and new cpu_suspend/resume interfaces and is based on the tip of master branch of kernel.org tree(v3.3-rc4)
Amit Daniel Kachhap (5):
ARM: exynos: Add support AFTR mode on EXYNOS4210
ARM: s5p: add L2 early resume code
ARM: exynos: save L2 settings during bootup
ARM: exynos: remove useless code to save/restore L2
ARM: exynos: Enable l2 configuration through device tree
arch/arm/mach-exynos/common.c | 53 +++++++++--- arch/arm/mach-exynos/cpuidle.c | 147 ++++++++++++++++++++++++++++++- arch/arm/mach-exynos/include/mach/pmu.h | 2 + arch/arm/mach-exynos/pm.c | 15 --- arch/arm/plat-s5p/sleep.S | 44 ++++++++-- 5 files changed, 225 insertions(+), 36 deletions(-)
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
This patch adds support AFTR(ARM OFF TOP RUNNING) mode in cpuidle driver. L2 cache keeps their data in this mode. This patch ports the code to the latest interfaces to save/restore CPU state inclusive of CPU PM notifiers, l2 resume and cpu_suspend/resume.
--- arch/arm/mach-exynos/cpuidle.c | 147 ++++++++++++++++++++++++++++++- arch/arm/mach-exynos/include/mach/pmu.h | 2 + 2 files changed, 146 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/cpuidle.c +144 -3
@@ -11,15 +11,35 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/cpuidle.h> +#include <linux/cpu_pm.h> #include <linux/io.h> #include <linux/export.h> #include <linux/time.h> #include <asm/proc-fns.h> +#include <asm/smp_scu.h> +#include <asm/suspend.h> +#include <asm/unified.h> +#include <mach/regs-pmu.h> +#include <mach/pmu.h> + +#include <plat/cpu.h> + +#define REG_DIRECTGO_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ + S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ + (S5P_VA_SYSRAM + 0x24) : S5P_INFORM0)) +#define REG_DIRECTGO_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ + S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ + (S5P_VA_SYSRAM + 0x20) : S5P_INFORM1)) + +#define S5P_CHECK_AFTR 0xFCBA0D10static int exynos4_enter_idle (struct cpuidle_device *dev,struct cpuidle_driver *drv,int index); +static int exynos4_enter_lowpower (struct cpuidle_device *dev, +struct cpuidle_driver *drv, +int index);static struct cpuidle_state exynos4_cpuidle_set[] = { [0 ] = {
@@ -27,9 +47,17 @@ static struct cpuidle_state exynos4_cpuidle_set[] = { .exit_latency = 1, .target_residency = 100000, .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "IDLE", + .name = "C0", .desc = "ARM clock gating(WFI)", }, + [1] = { + .enter = exynos4_enter_lowpower, + .exit_latency = 300, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C1", + .desc = "ARM power down", + }, }; static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
@@ -39,9 +67,100 @@ static struct cpuidle_driver exynos4_idle_driver = { .owner = THIS_MODULE, }; +/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ +static void exynos4_set_wakeupmask (void ) +{ +__raw_writel (0x0000ff3e ,S5P_WAKEUP_MASK ); +} + +static unsigned int g_pwr_ctrl, g_diag_reg; + +static void save_cpu_arch_register (void ) +{ +/*read power control register*/ + asm("mrc p15, 0, %0, c15, c0, 0" :"=r" (g_pwr_ctrl) : :"cc" ); +/*read diagnostic register*/ + asm("mrc p15, 0, %0, c15, c0, 1" :"=r" (g_diag_reg) : :"cc" ); +return ; +} + +static void restore_cpu_arch_register (void ) +{ +/*write power control register*/ + asm("mcr p15, 0, %0, c15, c0, 0" : :"r" (g_pwr_ctrl) :"cc" ); +/*write diagnostic register*/ + asm("mcr p15, 0, %0, c15, c0, 1" : :"r" (g_diag_reg) :"cc" ); +return ; +} + +static int idle_finisher (unsigned long flags) +{ +cpu_do_idle (); +return 1 ; +} + +static int exynos4_enter_core0_aftr (struct cpuidle_device *dev, +struct cpuidle_driver *drv, +int index) +{ +struct timeval before, after; +int idle_time; +unsigned long tmp; + +local_irq_disable (); +do_gettimeofday (&before); + +exynos4_set_wakeupmask (); + +/* Set value of power down register for aftr mode */ +exynos4_sys_powerdown_conf (SYS_AFTR ); + +__raw_writel (virt_to_phys (s3c_cpu_resume),REG_DIRECTGO_ADDR ); +__raw_writel (S5P_CHECK_AFTR ,REG_DIRECTGO_FLAG ); + +save_cpu_arch_register (); + +/* Setting Central Sequence Register for power down mode */ + tmp =__raw_readl (S5P_CENTRAL_SEQ_CONFIGURATION ); + tmp &= ~S5P_CENTRAL_LOWPWR_CFG ; +__raw_writel (tmp,S5P_CENTRAL_SEQ_CONFIGURATION ); + +cpu_pm_enter (); +cpu_suspend (0 , idle_finisher); + +scu_enable (S5P_VA_SCU ); +cpu_pm_exit (); + +restore_cpu_arch_register (); + +/* +* If PMU failed while entering sleep mode, WFI will be +* ignored by PMU and then exiting cpu_do_idle(). +* S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically +* in this situation. +*/ + tmp =__raw_readl (S5P_CENTRAL_SEQ_CONFIGURATION ); +if (!(tmp &S5P_CENTRAL_LOWPWR_CFG )) { + tmp |=S5P_CENTRAL_LOWPWR_CFG ; +__raw_writel (tmp,S5P_CENTRAL_SEQ_CONFIGURATION ); + } + +/* Clear wakeup state register */ +__raw_writel (0x0 ,S5P_WAKEUP_STAT ); + +do_gettimeofday (&after); + +local_irq_enable (); + idle_time = (after.tv_sec - before.tv_sec) *USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + dev->last_residency = idle_time; +return index; +} +static int exynos4_enter_idle (struct cpuidle_device *dev,struct cpuidle_driver *drv, -int index) +int index) {struct timeval before, after;int idle_time;
@@ -60,6 +179,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,return index; } +static int exynos4_enter_lowpower (struct cpuidle_device *dev, +struct cpuidle_driver *drv, +int index) +{ +int new_index = index; + +/* This mode only can be entered when other core's are offline */ +if (num_online_cpus () >1 ) + new_index = drv->safe_state_index; + +if (new_index ==0 ) +return exynos4_enter_idle (dev, drv, new_index); +else +return exynos4_enter_core0_aftr (dev, drv, new_index); +} +static int __init exynos4_init_cpuidle (void ) {int i, max_cpuidle_state, cpu_id;
@@ -74,19 +209,25 @@ static int __init exynos4_init_cpuidle(void)memcpy (&drv->states[i], &exynos4_cpuidle_set[i],sizeof (struct cpuidle_state )); } + drv->safe_state_index =0 ;cpuidle_register_driver (&exynos4_idle_driver);for_each_cpu (cpu_id, cpu_online_mask) { device = &per_cpu (exynos4_cpuidle_device, cpu_id); device->cpu = cpu_id; - device->state_count = drv->state_count; +if (cpu_id ==0 ) + device->state_count = (sizeof (exynos4_cpuidle_set) / +sizeof (struct cpuidle_state )); +else + device->state_count =1 ;/* Support IDLE only */ if (cpuidle_register_device (device)) {printk (KERN_ERR "CPUidle register device failed\n," );return -EIO ; } } +return 0 ; }device_initcall (exynos4_init_cpuidle);
arch/arm/mach-exynos/include/mach/pmu.h +2 -0
@@ -22,11 +22,13 @@ enum sys_powerdown { NUM_SYS_POWERDOWN, }; +extern unsigned long l2x0_regs_phys;struct exynos4_pmu_conf {void __iomem *reg;unsigned int val[NUM_SYS_POWERDOWN ]; };extern void exynos4_sys_powerdown_conf (enum sys_powerdown mode); +extern void s3c_cpu_resume (void );#endif /* __ASM_ARCH_PMU_H */
Signature · 1 line
1.7.1
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
Hi Amit,
Quoted 15 lines · Amit Daniel Kachhap
This patch adds support AFTR(ARM OFF TOP RUNNING) mode in cpuidle driver. L2 cache keeps their data in this mode. This patch ports the code to the latest interfaces to save/restore CPU state inclusive of CPU PM notifiers, l2 resume and cpu_suspend/resume.
Signed-off-by Jaecheol Lee <[email protected]>Signed-off-by Lorenzo Pieralisi <[email protected]>Signed-off-by Amit Daniel Kachhap <[email protected]>--- arch/arm/mach-exynos/cpuidle.c | 147 ++++++++++++++++++++++++++++++- arch/arm/mach-exynos/include/mach/pmu.h | 2 + 2 files changed, 146 insertions(+), 3 deletions(-)arch/arm/mach-exynos/cpuidle.c +0
-0
[ snip ]
Quoted 4 lines
arch/arm/mach-exynos/cpuidle.c +4
-0+static int exynos4_enter_core0_aftr (struct cpuidle_device *dev, +struct cpuidle_driver *drv, +int index) +{
[ snip ]
arch/arm/mach-exynos/cpuidle.c static struct cpuidle_driver exynos4_idle_driver = { · line 131
Quoted 1 line
arch/arm/mach-exynos/cpuidle.c +1
-0+scu_enable (S5P_VA_SCU );
#ifdef CONFIG_SMP scu_enable(S5P_VA_SCU);
#endif
Without this, if SMP is not enabled, I am getting following build error.
arch/arm/mach-exynos/built-in.o: In function `exynos4_enter_core0_aftr':arch/arm/mach-exynos/cpuidle.c:131: undefined reference to `scu_enable'
Signature · 1 line
Tushar Behera
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
Quoted 35 lines · Tushar Behera
Hi Amit,
Quoted 11 lines · Amit Daniel Kachhap
This patch adds support AFTR(ARM OFF TOP RUNNING) mode in cpuidle driver. L2 cache keeps their data in this mode. This patch ports the code to the latest interfaces to save/restore CPU state inclusive of CPU PM notifiers, l2 resume and cpu_suspend/resume.
Signed-off-by Jaecheol Lee <[email protected]>Signed-off-by Lorenzo Pieralisi <[email protected]>Signed-off-by Amit Daniel Kachhap <[email protected]>--- arch/arm/mach-exynos/cpuidle.c | 147++++++++++++++++++++++++++++++-
arch/arm/mach-
Quoted 4 lines
arch/arm/mach-exynos/include/mach/pmu.h | 2 + 2 files changed, 146 insertions(+), 3 deletions(-)arch/arm/mach- renamed from arch/arm/mach-exynos/cpuidle.c +0
-0
exynos/cpuidle.c[ snip ]
Quoted 4 lines
arch/arm/mach- renamed from arch/arm/mach-exynos/cpuidle.c +4
-0+static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{[ snip ]
arch/arm/mach-
Quoted 1 line
arch/arm/mach- renamed from arch/arm/mach-exynos/cpuidle.c +1
-0+ scu_enable(S5P_VA_SCU);#ifdef CONFIG_SMP scu_enable(S5P_VA_SCU);
Quoted 7 lines
#endif
Without this, if SMP is not enabled, I am getting following build error.
arch/arm/mach-exynos/built-in.o: In function `exynos4_enter_core0_aftr':arch/arm/mach-exynos/cpuidle.c:131: undefined reference to `scu_enable'
Thanks for your pointing out.
Let me fix it as per your comment when I apply this patch.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
In reply to Amit Daniel KachhapQuoted 9 lines
?static struct
cpuidle_stateexynos4_cpuidle_set[] = { ? ? ? ?[0] = {(quoted diff) +1
-1@@ -27,9 +47,17 @@ static struct cpuidle_state exynos4_cpuidle_set[] = { ? ? ? ? ? ? ? ?.exit_latency ? ? ? ? ? = 1, ? ? ? ? ? ? ? ?.target_residency ? ? ? = 100000, ? ? ? ? ? ? ? ?.flags ? ? ? ? ? ? ? ? ?= CPUIDLE_FLAG_TIME_VALID, - ? ? ? ? ? ? ? .name ? ? ? ? ? ? ? ? ? = "IDLE", + ? ? ? ? ? ? ? .name ? ? ? ? ? ? ? ? ? = "C0", ? ? ? ? ? ? ? ?.desc ? ? ? ? ? ? ? ? ? = "ARM clock gating(WFI)",
Review static struct cpuidle_state exynos4_cpuidle_set[] = { · line 61
Quoted 10 lines
(quoted diff) +8
-0? ? ? ?}, + ? ? ? [1] = { + ? ? ? ? ? ? ? .enter ? ? ? ? ? ? ? ? ?= exynos4_enter_lowpower, + ? ? ? ? ? ? ? .exit_latency ? ? ? ? ? = 300, + ? ? ? ? ? ? ? .target_residency ? ? ? = 100000, + ? ? ? ? ? ? ? .flags ? ? ? ? ? ? ? ? ?= CPUIDLE_FLAG_TIME_VALID, + ? ? ? ? ? ? ? .name ? ? ? ? ? ? ? ? ? = "C1", + ? ? ? ? ? ? ? .desc ? ? ? ? ? ? ? ? ? = "ARM power down", + ? ? ? }, ?};
It looks like you could make this __initdata because your are copying this state data over to the cpuidle_driver object during initialization.
Quoted 180 lines
(quoted diff) +115
-2?static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);@@ -39,9 +67,100 @@ static struct cpuidle_driver exynos4_idle_driver = { ? ? ? ?.owner ? ? ? ? ?= THIS_MODULE, ?}; +/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ +static void exynos4_set_wakeupmask(void) +{ + ? ? ? __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK); +} + +static unsigned int g_pwr_ctrl, g_diag_reg; + +static void save_cpu_arch_register(void) +{ + ? ? ? /*read power control register*/ + ? ? ? asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc"); + ? ? ? /*read diagnostic register*/ + ? ? ? asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc"); + ? ? ? return; +} + +static void restore_cpu_arch_register(void) +{ + ? ? ? /*write power control register*/ + ? ? ? asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc"); + ? ? ? /*write diagnostic register*/ + ? ? ? asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc"); + ? ? ? return; +} + +static int idle_finisher(unsigned long flags) +{ + ? ? ? cpu_do_idle(); + ? ? ? return 1; +} + +static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct cpuidle_driver *drv, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) +{ + ? ? ? struct timeval before, after; + ? ? ? int idle_time; + ? ? ? unsigned long tmp; + + ? ? ? local_irq_disable(); + ? ? ? do_gettimeofday(&before); + + ? ? ? exynos4_set_wakeupmask(); + + ? ? ? /* Set value of power down register for aftr mode */ + ? ? ? exynos4_sys_powerdown_conf(SYS_AFTR); + + ? ? ? __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); + ? ? ? __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); + + ? ? ? save_cpu_arch_register(); + + ? ? ? /* Setting Central Sequence Register for power down mode */ + ? ? ? tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + ? ? ? tmp &= ~S5P_CENTRAL_LOWPWR_CFG; + ? ? ? __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + + ? ? ? cpu_pm_enter(); + ? ? ? cpu_suspend(0, idle_finisher); + + ? ? ? scu_enable(S5P_VA_SCU); + ? ? ? cpu_pm_exit(); + + ? ? ? restore_cpu_arch_register(); + + ? ? ? /* + ? ? ? ?* If PMU failed while entering sleep mode, WFI will be + ? ? ? ?* ignored by PMU and then exiting cpu_do_idle(). + ? ? ? ?* S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically + ? ? ? ?* in this situation. + ? ? ? ?*/ + ? ? ? tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + ? ? ? if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { + ? ? ? ? ? ? ? tmp |= S5P_CENTRAL_LOWPWR_CFG; + ? ? ? ? ? ? ? __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + ? ? ? } + + ? ? ? /* Clear wakeup state register */ + ? ? ? __raw_writel(0x0, S5P_WAKEUP_STAT); + + ? ? ? do_gettimeofday(&after); + + ? ? ? local_irq_enable(); + ? ? ? idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + ? ? ? ? ? ? ? ? ? (after.tv_usec - before.tv_usec); + + ? ? ? dev->last_residency = idle_time; + ? ? ? return index; +} + ?static int exynos4_enter_idle(struct cpuidle_device *dev, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct cpuidle_driver *drv, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) ?{ ? ? ? ?struct timeval before, after; ? ? ? ?int idle_time;@@ -60,6 +179,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, ? ? ? ?return index; ?} +static int exynos4_enter_lowpower(struct cpuidle_device *dev, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct cpuidle_driver *drv, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) +{ + ? ? ? int new_index = index; + + ? ? ? /* This mode only can be entered when other core's are offline */ + ? ? ? if (num_online_cpus() > 1) + ? ? ? ? ? ? ? new_index = drv->safe_state_index; + + ? ? ? if (new_index == 0) + ? ? ? ? ? ? ? return exynos4_enter_idle(dev, drv, new_index); + ? ? ? else + ? ? ? ? ? ? ? return exynos4_enter_core0_aftr(dev, drv, new_index); +} + ?static int __init exynos4_init_cpuidle(void) ?{ ? ? ? ?int i, max_cpuidle_state, cpu_id;@@ -74,19 +209,25 @@ static int __init exynos4_init_cpuidle(void) ? ? ? ? ? ? ? ?memcpy(&drv->states[i], &exynos4_cpuidle_set[i], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct cpuidle_state)); ? ? ? ?} + ? ? ? drv->safe_state_index = 0; ? ? ? ?cpuidle_register_driver(&exynos4_idle_driver); ? ? ? ?for_each_cpu(cpu_id, cpu_online_mask) { ? ? ? ? ? ? ? ?device = &per_cpu(exynos4_cpuidle_device, cpu_id); ? ? ? ? ? ? ? ?device->cpu = cpu_id; - ? ? ? ? ? ? ? device->state_count = drv->state_count; + ? ? ? ? ? ? ? if (cpu_id == 0) + ? ? ? ? ? ? ? ? ? ? ? device->state_count = (sizeof(exynos4_cpuidle_set) / + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct cpuidle_state)); + ? ? ? ? ? ? ? else + ? ? ? ? ? ? ? ? ? ? ? device->state_count = 1; ? ? ? ?/* Support IDLE only */ ? ? ? ? ? ? ? ?if (cpuidle_register_device(device)) { ? ? ? ? ? ? ? ? ? ? ? ?printk(KERN_ERR "CPUidle register device failed\n,"); ? ? ? ? ? ? ? ? ? ? ? ?return -EIO; ? ? ? ? ? ? ? ?} ? ? ? ?} + ? ? ? ?return 0; ?} ?device_initcall(exynos4_init_cpuidle);arch/arm/mach-exynos/include/mach/pmu.h +2
-0@@ -22,11 +22,13 @@ enum sys_powerdown { ? ? ? ?NUM_SYS_POWERDOWN, ?}; +extern unsigned long l2x0_regs_phys; ?struct exynos4_pmu_conf { ? ? ? ?void __iomem *reg; ? ? ? ?unsigned int val[NUM_SYS_POWERDOWN]; ?}; ?extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); +extern void s3c_cpu_resume (void );?#endif /*
__ASM_ARCH_PMU_H*/
--
1.7.1_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
Quoted 15 lines · Rob Lee
Quoted 15 lines
?static struct
cpuidle_stateexynos4_cpuidle_set[] = { ? ? ? ?[0] = {(quoted diff) +6
-1@@ -27,9 +47,17 @@ static struct cpuidle_state exynos4_cpuidle_set[] = { ? ? ? ? ? ? ? ?.exit_latency ? ? ? ? ? = 1, ? ? ? ? ? ? ? ?.target_residency ? ? ? = 100000, ? ? ? ? ? ? ? ?.flags ? ? ? ? ? ? ? ? ?= CPUIDLE_FLAG_TIME_VALID, - ? ? ? ? ? ? ? .name ? ? ? ? ? ? ? ? ? = "IDLE", + ? ? ? ? ? ? ? .name ? ? ? ? ? ? ? ? ? = "C0", ? ? ? ? ? ? ? ?.desc ? ? ? ? ? ? ? ? ? = "ARM clock gating(WFI)", ? ? ? ?}, + ? ? ? [1] = { + ? ? ? ? ? ? ? .enter ? ? ? ? ? ? ? ? ?= exynos4_enter_lowpower, + ? ? ? ? ? ? ? .exit_latency ? ? ? ? ? = 300, + ? ? ? ? ? ? ? .target_residency ? ? ? = 100000, + ? ? ? ? ? ? ? .flags ? ? ? ? ? ? ? ? ?= CPUIDLE_FLAG_TIME_VALID,
Quoted 8 lines
Review static struct cpuidle_state exynos4_cpuidle_set[] = { · line 61
Quoted 4 lines
(quoted diff) +3
-0+ ? ? ? ? ? ? ? .name ? ? ? ? ? ? ? ? ? = "C1", + ? ? ? ? ? ? ? .desc ? ? ? ? ? ? ? ? ? = "ARM power down", + ? ? ? }, ?};It looks like you could make this
__initdatabecause your are copying this state data over to thecpuidle_driverobject during initialization.
Hi Rob,
This is a good suggestion. I tested it and this works fine.
Hi Mr kim,
Can this change be accommodated in the current patch series as below or should i send a new patchset?
arch/arm/mach-exynos/cpuidle.c +1 -1
@@ -41,7 +41,7 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev,struct cpuidle_driver *drv, int index); -static struct cpuidle_state exynos4_cpuidle_set[] = { +static struct cpuidle_state exynos4_cpuidle_set[]__initdata = { [0 ] = { .enter = exynos4_enter_idle, .exit_latency =1 ,
Thanks,
Amit Daniel
Quoted 181 lines
Quoted 181 lines
(quoted diff) +115
-2?static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);@@ -39,9 +67,100 @@ static struct cpuidle_driver exynos4_idle_driver = { ? ? ? ?.owner ? ? ? ? ?= THIS_MODULE, ?}; +/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ +static void exynos4_set_wakeupmask(void) +{ + ? ? ? __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK); +} + +static unsigned int g_pwr_ctrl, g_diag_reg; + +static void save_cpu_arch_register(void) +{ + ? ? ? /*read power control register*/ + ? ? ? asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc"); + ? ? ? /*read diagnostic register*/ + ? ? ? asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc"); + ? ? ? return; +} + +static void restore_cpu_arch_register(void) +{ + ? ? ? /*write power control register*/ + ? ? ? asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc"); + ? ? ? /*write diagnostic register*/ + ? ? ? asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc"); + ? ? ? return; +} + +static int idle_finisher(unsigned long flags) +{ + ? ? ? cpu_do_idle(); + ? ? ? return 1; +} + +static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct cpuidle_driver *drv, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) +{ + ? ? ? struct timeval before, after; + ? ? ? int idle_time; + ? ? ? unsigned long tmp; + + ? ? ? local_irq_disable(); + ? ? ? do_gettimeofday(&before); + + ? ? ? exynos4_set_wakeupmask(); + + ? ? ? /* Set value of power down register for aftr mode */ + ? ? ? exynos4_sys_powerdown_conf(SYS_AFTR); + + ? ? ? __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); + ? ? ? __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); + + ? ? ? save_cpu_arch_register(); + + ? ? ? /* Setting Central Sequence Register for power down mode */ + ? ? ? tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + ? ? ? tmp &= ~S5P_CENTRAL_LOWPWR_CFG; + ? ? ? __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + + ? ? ? cpu_pm_enter(); + ? ? ? cpu_suspend(0, idle_finisher); + + ? ? ? scu_enable(S5P_VA_SCU); + ? ? ? cpu_pm_exit(); + + ? ? ? restore_cpu_arch_register(); + + ? ? ? /* + ? ? ? ?* If PMU failed while entering sleep mode, WFI will be + ? ? ? ?* ignored by PMU and then exiting cpu_do_idle(). + ? ? ? ?* S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically + ? ? ? ?* in this situation. + ? ? ? ?*/ + ? ? ? tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + ? ? ? if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { + ? ? ? ? ? ? ? tmp |= S5P_CENTRAL_LOWPWR_CFG; + ? ? ? ? ? ? ? __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + ? ? ? } + + ? ? ? /* Clear wakeup state register */ + ? ? ? __raw_writel(0x0, S5P_WAKEUP_STAT); + + ? ? ? do_gettimeofday(&after); + + ? ? ? local_irq_enable(); + ? ? ? idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + ? ? ? ? ? ? ? ? ? (after.tv_usec - before.tv_usec); + + ? ? ? dev->last_residency = idle_time; + ? ? ? return index; +} + ?static int exynos4_enter_idle(struct cpuidle_device *dev, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct cpuidle_driver *drv, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) ?{ ? ? ? ?struct timeval before, after; ? ? ? ?int idle_time;@@ -60,6 +179,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, ? ? ? ?return index; ?} +static int exynos4_enter_lowpower(struct cpuidle_device *dev, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct cpuidle_driver *drv, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int index) +{ + ? ? ? int new_index = index; + + ? ? ? /* This mode only can be entered when other core's are offline */ + ? ? ? if (num_online_cpus() > 1) + ? ? ? ? ? ? ? new_index = drv->safe_state_index; + + ? ? ? if (new_index == 0) + ? ? ? ? ? ? ? return exynos4_enter_idle(dev, drv, new_index); + ? ? ? else + ? ? ? ? ? ? ? return exynos4_enter_core0_aftr(dev, drv, new_index); +} + ?static int __init exynos4_init_cpuidle(void) ?{ ? ? ? ?int i, max_cpuidle_state, cpu_id;@@ -74,19 +209,25 @@ static int __init exynos4_init_cpuidle(void) ? ? ? ? ? ? ? ?memcpy(&drv->states[i], &exynos4_cpuidle_set[i], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct cpuidle_state)); ? ? ? ?} + ? ? ? drv->safe_state_index = 0; ? ? ? ?cpuidle_register_driver(&exynos4_idle_driver); ? ? ? ?for_each_cpu(cpu_id, cpu_online_mask) { ? ? ? ? ? ? ? ?device = &per_cpu(exynos4_cpuidle_device, cpu_id); ? ? ? ? ? ? ? ?device->cpu = cpu_id; - ? ? ? ? ? ? ? device->state_count = drv->state_count; + ? ? ? ? ? ? ? if (cpu_id == 0) + ? ? ? ? ? ? ? ? ? ? ? device->state_count = (sizeof(exynos4_cpuidle_set) / + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct cpuidle_state)); + ? ? ? ? ? ? ? else + ? ? ? ? ? ? ? ? ? ? ? device->state_count = 1; ? ? ? ?/* Support IDLE only */ ? ? ? ? ? ? ? ?if (cpuidle_register_device(device)) { ? ? ? ? ? ? ? ? ? ? ? ?printk(KERN_ERR "CPUidle register device failed\n,"); ? ? ? ? ? ? ? ? ? ? ? ?return -EIO; ? ? ? ? ? ? ? ?} ? ? ? ?} + ? ? ? ?return 0; ?} ?device_initcall(exynos4_init_cpuidle);arch/arm/mach-exynos/include/mach/pmu.h +2
-0@@ -22,11 +22,13 @@ enum sys_powerdown { ? ? ? ?NUM_SYS_POWERDOWN, ?}; +extern unsigned long l2x0_regs_phys; ?struct exynos4_pmu_conf { ? ? ? ?void __iomem *reg; ? ? ? ?unsigned int val[NUM_SYS_POWERDOWN]; ?}; ?extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); +extern void s3c_cpu_resume (void );?#endif /*
__ASM_ARCH_PMU_H*/
--
1.7.1_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
Hello Kukjim and Amit,
Can you tell me the status of this patch? I based my core cpuidle consolidation patchset on these changes. My patchset seems to be acceptable now and I would like to do a git pull-request for linux-next, but I see these Exynos cpuidle changes have not yet made it to linux-next.
Thanks,
Rob
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
Quoted 8 lines · Rob Lee
Hello Kukjim and Amit,
Can you tell me the status of this patch? I based my core cpuidle consolidation patchset on these changes. My patchset seems to be acceptable now and I would like to do a git pull-request for linux-next, but I see these Exynos cpuidle changes have not yet made it to linux-next.
Hi Rob,
Probably, I missed merging its topic branch and I will do right now. I think you can see it in a couple of hours.
Then, if any problems, please let me know.
Thanks for your reminder.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
PATCH v6 1/5 ARM: exynos: Add support AFTR mode on EXYNOS4210
In reply to Amit KachhapQuoted 1 line · Amit Kachhap
On 23 February 2012 11:54, Rob Lee<[email protected]> wrote:
[...]
Quoted 5 lines
Hi Mr kim,
Can this change be accommodated in the current patch series as below or should i send a new patchset?
I did, Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
Quoted 13 lines
arch/arm/mach-exynos/cpuidle.c +1
-1@@ -41,7 +41,7 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev,struct cpuidle_driver *drv, int index); -static struct cpuidle_state exynos4_cpuidle_set[] = { +static struct cpuidle_state exynos4_cpuidle_set[]__initdata = { [0 ] = { .enter = exynos4_enter_idle, .exit_latency =1 ,
PATCH v6 2/5 ARM: s5p: add L2 early resume code
In reply to Amit Daniel KachhapThis patch adds code to resume L2 before MMU is enabled in suspend and cpuidle resume paths. s3c_cpu_resume is moved to the data section with appropriate comments.
--- arch/arm/plat-s5p/sleep.S | 44 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 38 insertions(+), 6 deletions(-)
arch/arm/plat-s5p/sleep.S +38 -6
@@ -23,9 +23,18 @@ */ #include <linux/linkage.h> -#include <asm/assembler.h> +#include <asm/asm-offsets.h> +#include <asm/hardware/cache-l2x0.h> - .text +/* + * The following code is located into the .data section. This is to + * allow l2x0_regs_phys to be accessed with a relative load while we + * can't rely on any MMU translation. We could have put l2x0_regs_phys + * in the .text section as well, but some setups might insist on it to + * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) + */ + .data + .align /* * sleep magic, to allow the bootloader to check for an valid
@@ -39,11 +48,34 @@ * s3c_cpu_resume * * resume code entry for bootloader to call - * - * we must put this code here in the data segment as we have no - * other way of restoring the stack pointer after sleep, and we - * must not write to the code segment (code is read-only) */ ENTRY(s3c_cpu_resume) +#ifdef CONFIG_CACHE_L2X0 + adr r0, l2x0_regs_phys + ldr r0, [r0] + ldr r1, [r0, #L2X0_R_PHY_BASE] + ldr r2, [r1, #L2X0_CTRL] + tst r2, #0x1 + bne resume_l2on + ldr r2, [r0, #L2X0_R_AUX_CTRL] + str r2, [r1, #L2X0_AUX_CTRL] + ldr r2, [r0, #L2X0_R_TAG_LATENCY] + str r2, [r1, #L2X0_TAG_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_DATA_LATENCY] + str r2, [r1, #L2X0_DATA_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] + str r2, [r1, #L2X0_PREFETCH_CTRL] + ldr r2, [r0, #L2X0_R_PWR_CTRL] + str r2, [r1, #L2X0_POWER_CTRL] + mov r2, #1 + str r2, [r1, #L2X0_CTRL] +resume_l2on: +#endif b cpu_resume +ENDPROC(s3c_cpu_resume) +#ifdef CONFIG_CACHE_L2X0 + .globl l2x0_regs_phys +l2x0_regs_phys: + .long 0 +#endif
Signature · 1 line
1.7.1
PATCH v6 3/5 ARM: exynos: save L2 settings during bootup
In reply to Amit Daniel KachhapThis patch adds code to save L2 register configuration at boot, and later used to resume L2 before MMU is enabled in suspend and cpuidle resume paths.
--- arch/arm/mach-exynos/common.c | 42 ++++++++++++++++++++++++++++++---------- 1 files changed, 31 insertions(+), 11 deletions(-)
arch/arm/mach-exynos/common.c +31 -11
@@ -26,10 +26,12 @@#include <asm/hardware/gic.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <asm/cacheflush.h> #include <mach/regs-irq.h> #include <mach/regs-pmu.h> #include <mach/regs-gpio.h> +#include <mach/pmu.h> #include <plat/cpu.h> #include <plat/clock.h>
@@ -441,20 +443,38 @@ core_initcall(exynos4_core_init);#ifdef CONFIG_CACHE_L2X0 static int __init exynos4_l2x0_cache_init (void ) { -/* TAG, Data Latency Control: 2cycle */ -__raw_writel (0x110 ,S5P_VA_L2CC +L2X0_TAG_LATENCY_CTRL ); +if (!(__raw_readl (S5P_VA_L2CC +L2X0_CTRL ) &0x1 )) { + l2x0_saved_regs.phy_base =EXYNOS4_PA_L2CC ; +/* TAG, Data Latency Control: 2 cycles */ + l2x0_saved_regs.tag_latency =0x110 ; -if (soc_is_exynos4210 ()) -__raw_writel (0x110 ,S5P_VA_L2CC +L2X0_DATA_LATENCY_CTRL ); -else if (soc_is_exynos4212 () ||soc_is_exynos4412 ()) -__raw_writel (0x120 ,S5P_VA_L2CC +L2X0_DATA_LATENCY_CTRL ); +if (soc_is_exynos4212 () ||soc_is_exynos4412 ()) + l2x0_saved_regs.data_latency =0x120 ; +else + l2x0_saved_regs.data_latency =0x110 ; + + l2x0_saved_regs.prefetch_ctrl =0x30000007 ; + l2x0_saved_regs.pwr_ctrl = + (L2X0_DYNAMIC_CLK_GATING_EN |L2X0_STNDBY_MODE_EN ); + + l2x0_regs_phys =virt_to_phys (&l2x0_saved_regs); -/* L2X0 Prefetch Control */ -__raw_writel (0x30000007 ,S5P_VA_L2CC +L2X0_PREFETCH_CTRL ); +__raw_writel (l2x0_saved_regs.tag_latency, +S5P_VA_L2CC +L2X0_TAG_LATENCY_CTRL ); +__raw_writel (l2x0_saved_regs.data_latency, +S5P_VA_L2CC +L2X0_DATA_LATENCY_CTRL ); -/* L2X0 Power Control */ -__raw_writel (L2X0_DYNAMIC_CLK_GATING_EN |L2X0_STNDBY_MODE_EN , -S5P_VA_L2CC +L2X0_POWER_CTRL ); +/* L2X0 Prefetch Control */ +__raw_writel (l2x0_saved_regs.prefetch_ctrl, +S5P_VA_L2CC +L2X0_PREFETCH_CTRL ); + +/* L2X0 Power Control */ +__raw_writel (l2x0_saved_regs.pwr_ctrl, +S5P_VA_L2CC +L2X0_POWER_CTRL ); + +clean_dcache_area (&l2x0_regs_phys,sizeof (unsigned long )); +clean_dcache_area (&l2x0_saved_regs,sizeof (struct l2x0_regs )); + }l2x0_init (S5P_VA_L2CC ,0x7C470001 ,0xC200ffff );
Signature · 1 line
1.7.1
PATCH v6 4/5 ARM: exynos: remove useless code to save/restore L2
In reply to Amit Daniel KachhapFollowing the merge of CPU PM notifiers and L2 resume code, this patch removes useless code to save and restore L2 registers.
This is now automatically covered by suspend calls which integrated CPU PM notifiers and new sleep code that allows to resume L2 before MMU is turned on.
--- arch/arm/mach-exynos/pm.c | 15 --------------- 1 files changed, 0 insertions(+), 15 deletions(-)
arch/arm/mach-exynos/pm.c +0 -15
@@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_SROM_BC3), }; -static struct sleep_save exynos4_l2cc_save[] = { -SAVE_ITEM (S5P_VA_L2CC +L2X0_TAG_LATENCY_CTRL ), -SAVE_ITEM (S5P_VA_L2CC +L2X0_DATA_LATENCY_CTRL ), -SAVE_ITEM (S5P_VA_L2CC +L2X0_PREFETCH_CTRL ), -SAVE_ITEM (S5P_VA_L2CC +L2X0_POWER_CTRL ), -SAVE_ITEM (S5P_VA_L2CC +L2X0_AUX_CTRL ), -};/* For Cortex-A9 Diagnostic and Power control register */ static unsigned int save_arm_register[2 ];
@@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void)u32 tmp;s3c_pm_do_save (exynos4_core_save,ARRAY_SIZE (exynos4_core_save)); -s3c_pm_do_save (exynos4_l2cc_save,ARRAY_SIZE (exynos4_l2cc_save));s3c_pm_do_save (exynos4_epll_save,ARRAY_SIZE (exynos4_epll_save));s3c_pm_do_save (exynos4_vpll_save,ARRAY_SIZE (exynos4_vpll_save));
@@ -388,13 +380,6 @@ static void exynos4_pm_resume(void)scu_enable (S5P_VA_SCU );#endif -#ifdef CONFIG_CACHE_L2X0 -s3c_pm_do_restore_core (exynos4_l2cc_save,ARRAY_SIZE (exynos4_l2cc_save)); -outer_inv_all (); -/* enable L2X0*/ -writel_relaxed (1 ,S5P_VA_L2CC +L2X0_CTRL ); -#endif - early_wakeup:return ; }
Signature · 1 line
1.7.1
PATCH v6 5/5 ARM: exynos: Enable l2 configuration through device tree
In reply to Amit Daniel KachhapThis patch enables calling generic l2 setup functions if device tree is used.
--- arch/arm/mach-exynos/common.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-)
arch/arm/mach-exynos/common.c +11 -2
@@ -47,6 +47,8 @@#include <plat/regs-serial.h> #include "common.h" +#define L2_AUX_VAL 0x7C470001 +#define L2_AUX_MASK 0xC200ffffstatic const char name_exynos4210[] ="EXYNOS4210" ;static const char name_exynos4212[] ="EXYNOS4212" ;
@@ -443,6 +445,14 @@ core_initcall(exynos4_core_init);#ifdef CONFIG_CACHE_L2X0 static int __init exynos4_l2x0_cache_init (void ) { +int ret; + ret =l2x0_of_init (L2_AUX_VAL ,L2_AUX_MASK ); +if (!ret) { + l2x0_regs_phys =virt_to_phys (&l2x0_saved_regs); +clean_dcache_area (&l2x0_regs_phys,sizeof (unsigned long )); +return 0 ; + } +if (!(__raw_readl (S5P_VA_L2CC +L2X0_CTRL ) &0x1 )) { l2x0_saved_regs.phy_base =EXYNOS4_PA_L2CC ;/* TAG, Data Latency Control: 2 cycles */
@@ -476,8 +486,7 @@ static int __init exynos4_l2x0_cache_init(void)clean_dcache_area (&l2x0_saved_regs,sizeof (struct l2x0_regs )); } -l2x0_init (S5P_VA_L2CC ,0x7C470001 ,0xC200ffff ); - +l2x0_init (S5P_VA_L2CC ,L2_AUX_VAL ,L2_AUX_MASK );return 0 ; }
Signature · 1 line
1.7.1
v6 cover ARM: exynos4210: Add l2 retention mode cpuidle state
In reply to Amit Daniel KachhapQuoted 45 lines · Amit Daniel Kachhap
Changes since V5:
*Rebased the patchset against kernel 3.3-rc4
*Added correct flag for exynos4210 evt1 based board *RemovedCONFIG_OFfrom l2 cache configuration as suggested by
Olof Johansson <[email protected]>Changes since V4:
*Rebased the patchset against for-next of samsung kernel tree. *Added Tushar suggestion of putting a check if L2 cache dt node not found. *Added Inder suggestion of removing theBUG_ONcheck in cpuidle driver.Changes since V3:
*Implemented Russell feedback and moved sleep magic 4byte memory befores3c_cpu_resumeto data section.Changes since V2:
*Implemented the suggestion of MyungJoo Ham and used INFORM0/1 registers for resume for some board versions.
*Added back save/restore through CPU PM notifiers as suggested by Lorenzo Pieralisi. This is useful to restore vfp state. *some patch modularization (s5p/exynos) and proper commit logs.Changes since V1:
*rebased the whole patch against 3.2-rc1 tree
*removed GIC save/restore in AFTR cpuidle state as it is external to cpu powerdomain
*Added L2 setup code through device tree
*Removed only l2 save/restore registers in sleepThis Patch series adds support for AFTR mode cpuidle state based on patch (http://www.spinics.net/lists/arm-kernel/msg132243.html) earlier submitted by Jaecheol Lee <[email protected]>.
This patch uses CPU PM notifiers , common l2 save/restore and new cpu_suspend/resume interfaces and is based on the tip of master branch of kernel.org tree(v3.3-rc4)
Amit Daniel Kachhap (5):
ARM: exynos: Add support AFTR mode on EXYNOS4210
ARM: s5p: add L2 early resume code
ARM: exynos: save L2 settings during bootup
ARM: exynos: remove useless code to save/restore L2
ARM: exynos: Enable l2 configuration through device tree
Quoted 7 lines
arch/arm/mach-exynos/common.c | 53 +++++++++--- arch/arm/mach-exynos/cpuidle.c | 147 ++++++++++++++++++++++++++++++- arch/arm/mach-exynos/include/mach/pmu.h | 2 + arch/arm/mach-exynos/pm.c | 15 --- arch/arm/plat-s5p/sleep.S | 44 ++++++++-- 5 files changed, 225 insertions(+), 36 deletions(-)
Cc'ed Jaecheol Lee and Rob Lee.
OK, looks ok to me and I got the report this works fine on SMDKV310 from Jaecheol Lee.
I will apply this whole series for v3.4, but I'm not sure how conflicts will happen with common cpuidle. Let me check it.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.