Skip to content

Commit

Permalink
Make it possible to wake up from standby.
Browse files Browse the repository at this point in the history
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
  • Loading branch information
hramrach committed Mar 30, 2013
1 parent a4f193f commit 31a8001
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 71 deletions.
3 changes: 2 additions & 1 deletion arch/arm/plat-sunxi/pm/Makefile
@@ -1,6 +1,7 @@
subdir := standby

obj-y += pm.o standby.o
obj-y += pm.o standby.o \
standby-kernel.o standby/standby_delay.o

$(obj)/standby.o: $(obj)/standby/standby.bin

Expand Down
11 changes: 7 additions & 4 deletions arch/arm/plat-sunxi/pm/pm.c
Expand Up @@ -36,6 +36,7 @@
#include <asm/delay.h>
#include <asm/io.h>
#include <linux/power/aw_pm.h>
#include "standby/standby_wakeup.h"


extern char *standby_bin_start;
Expand All @@ -55,9 +56,15 @@ static int aw_pm_valid(suspend_state_t state)

static int aw_pm_enter(suspend_state_t state)
{
/* config system wakeup evetn type */
standby_info.standby_para.event = SUSPEND_WAKEUP_SRC_EXINT | SUSPEND_WAKEUP_SRC_ALARM |
SUSPEND_WAKEUP_SRC_KEY | SUSPEND_WAKEUP_SRC_IR | SUSPEND_WAKEUP_SRC_USB;

switch (state) {
case PM_SUSPEND_STANDBY:
standby_wakeup_init();
cpu_do_idle();
standby_wakeup_fini();
return 0;
case PM_SUSPEND_MEM: {
int (*standby)(struct aw_pm_info *arg) = (int (*)(struct aw_pm_info *arg))SRAM_FUNC_START;
Expand All @@ -66,10 +73,6 @@ static int aw_pm_enter(suspend_state_t state)
/* move standby code to sram */
memcpy((void *)SRAM_FUNC_START, (void *)&standby_bin_start, (int)&standby_bin_end - (int)&standby_bin_start);

/* config system wakeup evetn type */
standby_info.standby_para.event = SUSPEND_WAKEUP_SRC_EXINT | SUSPEND_WAKEUP_SRC_ALARM |
SUSPEND_WAKEUP_SRC_KEY | SUSPEND_WAKEUP_SRC_IR | SUSPEND_WAKEUP_SRC_USB;

/* goto sram and run */
ret = standby(&standby_info);
if (!ret)
Expand Down
12 changes: 12 additions & 0 deletions arch/arm/plat-sunxi/pm/standby-kernel.c
@@ -0,0 +1,12 @@
/* The standby code is compiled with different calling convention so include another copy for use in kernel. */

#include "standby/common.c"
#include "standby/standby_power.c"
#include "standby/standby_twi.c"
#include "standby/standby_int.c"
#include "standby/standby_clock.c"
#include "standby/standby_key.c"
#include "standby/standby_usb.c"
#include "standby/standby_ir.c"
#include "standby/standby_tmr.c"
#include "standby/standby_wakeup.c"
2 changes: 1 addition & 1 deletion arch/arm/plat-sunxi/pm/standby/Makefile
Expand Up @@ -4,7 +4,7 @@ targets := standby.elf
standby-y := common.o standby.o stack.o standby_clock.o \
dram.o dram_init.o \
standby_int.o standby_ir.o standby_key.o standby_power.o \
standby_tmr.o standby_twi.o standby_usb.o standby_delay.o
standby_tmr.o standby_twi.o standby_usb.o standby_delay.o standby_wakeup.o

targets += $(standby-y)
STANDBY_OBJS = $(addprefix $(obj)/,$(standby-y))
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/plat-sunxi/pm/standby/common.c
Expand Up @@ -23,6 +23,9 @@

#include "standby_i.h"

/* parameter for standby, it will be transfered from sys_pwm module */
struct aw_pm_info pm_info;


/*
*********************************************************************************************************
Expand Down
56 changes: 3 additions & 53 deletions arch/arm/plat-sunxi/pm/standby/standby.c
Expand Up @@ -22,6 +22,7 @@
*/

#include "standby_i.h"
#include "standby_wakeup.h"

extern unsigned int save_sp(void);
extern void restore_sp(unsigned int sp);
Expand All @@ -38,9 +39,6 @@ static __u32 dcdc2, dcdc3;
static struct sun4i_clk_div_t clk_div;
static struct sun4i_clk_div_t tmp_clk_div;

/* parameter for standby, it will be transfered from sys_pwm module */
struct aw_pm_info pm_info;

#define DRAM_BASE_ADDR 0xc0000000
#define DRAM_TRANING_SIZE (16)
static __u32 dram_traning_area_back[DRAM_TRANING_SIZE];
Expand Down Expand Up @@ -86,40 +84,7 @@ int __attribute__((section(".startup")))main(struct aw_pm_info *arg)
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/* init module before dram enter selfrefresh */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

/* initialise standby modules */
standby_clk_init();
standby_int_init();
standby_tmr_init();
standby_power_init();
/* init some system wake source */
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_EXINT){
standby_enable_int(INT_SOURCE_EXTNMI);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_KEY){
standby_key_init();
standby_enable_int(INT_SOURCE_LRADC);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_IR){
standby_ir_init();
standby_enable_int(INT_SOURCE_IR0);
standby_enable_int(INT_SOURCE_IR1);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_ALARM){
//standby_alarm_init();???
standby_enable_int(INT_SOURCE_ALARM);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_USB){
standby_usb_init();
standby_enable_int(INT_SOURCE_USB0);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_TIMEOFF){
/* set timer for power off */
if(pm_info.standby_para.time_off) {
standby_tmr_set(pm_info.standby_para.time_off);
standby_enable_int(INT_SOURCE_TIMER0);
}
}
standby_wakeup_init();

/* save stack pointer registger, switch stack to sram */
sp_backup = save_sp();
Expand All @@ -138,22 +103,7 @@ int __attribute__((section(".startup")))main(struct aw_pm_info *arg)
restore_sp(sp_backup);

/* exit standby module */
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_USB){
standby_usb_exit();
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_IR){
standby_ir_exit();
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_ALARM){
//standby_alarm_exit();
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_KEY){
standby_key_exit();
}
standby_power_exit();
standby_tmr_exit();
standby_int_exit();
standby_clk_exit();
standby_wakeup_fini();

/* restore dram traning area */
standby_memcpy((char *)DRAM_BASE_ADDR, (char *)dram_traning_area_back, sizeof(__u32)*DRAM_TRANING_SIZE);
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/plat-sunxi/pm/standby/standby_key.c
Expand Up @@ -26,7 +26,7 @@
#include "standby_i.h"

static __standby_key_reg_t *KeyReg;
static __u32 KeyCtrl, KeyIntc, KeyInts, KeyData0, KeyData1;
static __u32 KeyCtrl, KeyIntc;

/*
*********************************************************************************************************
Expand Down
4 changes: 1 addition & 3 deletions arch/arm/plat-sunxi/pm/standby/standby_power.c
Expand Up @@ -36,8 +36,7 @@
*/
__s32 standby_power_init(void)
{
__u8 val, mask, reg_val;
__s32 i;
__u8 reg_val;

standby_twi_init(AXP_IICBUS);

Expand Down Expand Up @@ -219,7 +218,6 @@ __u32 standby_get_voltage(enum power_vol_type_e type)
{
struct axp_info *info = 0;
__u8 val, mask;
int ret;

info = find_info(type);
if (info == 0) {
Expand Down
8 changes: 0 additions & 8 deletions arch/arm/plat-sunxi/pm/standby/standby_tmr.c
Expand Up @@ -39,8 +39,6 @@ static __u32 TmrIntCtl, Tmr0Ctl, Tmr0IntVal, Tmr0CntVal, Tmr1Ctl, Tmr1IntVal, Tm
*/
__s32 standby_tmr_init(void)
{
__s32 i;

/* set timer register base */
TmrReg = (__standby_tmr_reg_t *)SW_VA_TIMERC_IO_BASE;

Expand Down Expand Up @@ -80,8 +78,6 @@ __s32 standby_tmr_init(void)
*/
__s32 standby_tmr_exit(void)
{
__s32 i;

/* restore timer0 parameters */
TmrReg->Tmr0IntVal = Tmr0IntVal;
TmrReg->Tmr0CntVal = Tmr0CntVal;
Expand Down Expand Up @@ -188,8 +184,6 @@ void standby_tmr_disable_watchdog(void)
*/
__s32 standby_tmr_query(enum tmr_event_type_e type)
{
__s32 result;

switch(type)
{
case TMR_EVENT_POWEROFF:
Expand Down Expand Up @@ -227,8 +221,6 @@ __s32 standby_tmr_query(enum tmr_event_type_e type)
*/
void standby_tmr_mdlay(int ms)
{
int i;

if(ms < 30){
ms = 30;
}
Expand Down
1 change: 1 addition & 0 deletions arch/arm/plat-sunxi/pm/standby/standby_tmr.h
Expand Up @@ -101,6 +101,7 @@ enum tmr_event_type_e{
__s32 standby_tmr_init(void);
__s32 standby_tmr_exit(void);
__s32 standby_tmr_query(enum tmr_event_type_e type);
__s32 standby_tmr_set(__u32 second);
void standby_tmr_mdlay(int ms);
void standby_tmr_enable_watchdog(void);
void standby_tmr_disable_watchdog(void);
Expand Down
59 changes: 59 additions & 0 deletions arch/arm/plat-sunxi/pm/standby/standby_wakeup.c
@@ -0,0 +1,59 @@
#include "standby_i.h"
#include "standby_wakeup.h"

void standby_wakeup_init(void)
{
/* initialise standby modules */
standby_clk_init();
standby_int_init();
standby_tmr_init();
standby_power_init();
/* init some system wake source */
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_EXINT){
standby_enable_int(INT_SOURCE_EXTNMI);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_KEY){
standby_key_init();
standby_enable_int(INT_SOURCE_LRADC);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_IR){
standby_ir_init();
standby_enable_int(INT_SOURCE_IR0);
standby_enable_int(INT_SOURCE_IR1);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_ALARM){
//standby_alarm_init();???
standby_enable_int(INT_SOURCE_ALARM);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_USB){
standby_usb_init();
standby_enable_int(INT_SOURCE_USB0);
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_TIMEOFF){
/* set timer for power off */
if(pm_info.standby_para.time_off) {
standby_tmr_set(pm_info.standby_para.time_off);
standby_enable_int(INT_SOURCE_TIMER0);
}
}
}

void standby_wakeup_fini(void)
{
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_USB){
standby_usb_exit();
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_IR){
standby_ir_exit();
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_ALARM){
//standby_alarm_exit();
}
if(pm_info.standby_para.event & SUSPEND_WAKEUP_SRC_KEY){
standby_key_exit();
}
standby_power_exit();
standby_tmr_exit();
standby_int_exit();
standby_clk_exit();
}
3 changes: 3 additions & 0 deletions arch/arm/plat-sunxi/pm/standby/standby_wakeup.h
@@ -0,0 +1,3 @@

void standby_wakeup_init(void);
void standby_wakeup_fini(void);

0 comments on commit 31a8001

Please sign in to comment.