コード例 #1
0
ファイル: clk_auto_volt.c プロジェクト: gtlinyun/bq-DC-v2
static void scal_volt_func(struct work_struct *work)
{
    int ret = 0;

    ret = regulator_set_voltage(regulator, volt, volt);
    if (ret) {
        PM_ERR("regulator_set_voltage failed!\n");
        PM_ERR("stop!\n");
        return;
    }
    else
        PM_DBG("regulator_set_voltage: %d(uV)\n",volt);

    if (volt_direction == VOLT_DOWN) {
        volt = volt - volt_step;
        if(volt <  stop_volt) {
            PM_DBG("stop!\n");
            return;
        }
    }
    else if (volt_direction == VOLT_UP) {
        volt = volt + volt_step;
        if (volt > stop_volt) {
            PM_DBG("stop!\n");
            return;
        }
    }

    queue_delayed_work(scal_volt_wq, &scal_volt_work, msecs_to_jiffies(timer_tick*1000));
}
コード例 #2
0
ファイル: pm.c プロジェクト: diguokaituozhe/XR871
void parse_dpm_list(struct list_head *head, unsigned int idx)
{
	struct list_head *list;
	struct soc_device *dev;

	PM_DBG("(%p)", head);
	list_for_each(list, head) {
		dev = to_device(list, idx);
		PM_DBG("-->%s(%p)", dev->name, dev);
	}
コード例 #3
0
ファイル: clk_rate.c プロジェクト: Astralix/kernel
ssize_t clk_rate_store(struct kobject *kobj, struct kobj_attribute *attr,
		const char *buf, size_t n)
{
	struct dvfs_node *clk_dvfs_node = NULL;
	char cmd[20], clk_name[20], msg[50];
	int rate;
	printk("%s: %s\n", __func__, buf);
	sscanf(buf, "%s %s %d", cmd, clk_name, &rate);

	clk_dvfs_node = clk_get_dvfs_node(clk_name);
	if (!clk_dvfs_node) {
		PM_ERR("%s: clk(%s) get dvfs node error\n", __func__, clk_name);
		return n;
	}

	if (0 == strncmp(cmd, "set", strlen("set"))) {
		PM_DBG("Get command set %s %dHz\n", clk_name, rate);
		if (file_read(FILE_GOV_MODE, msg) != 0) {
			PM_ERR("read current governor error\n");
			return n;
		} else {
			PM_DBG("current governor = %s\n", msg);
		}

		strcpy(msg, "userspace");
		if (file_write(FILE_GOV_MODE, msg) != 0) {
			PM_ERR("set current governor error\n");
			return n;
		}

		dvfs_clk_enable_limit(clk_dvfs_node, rate, rate);
		dvfs_clk_set_rate(clk_dvfs_node, rate);

	} else if (0 == strncmp(cmd, "reset", strlen("reset"))) {	
		PM_DBG("Get command reset %s\n", clk_name);
		if (file_read(FILE_GOV_MODE, msg) != 0) {
			PM_ERR("read current governor error\n");
			return n;
		} else {
			PM_DBG("current governor = %s\n", msg);
		}

		strcpy(msg, "interactive");
		if (file_write(FILE_GOV_MODE, msg) != 0) {
			PM_ERR("set current governor error\n");
			return n;
		}

		dvfs_clk_disable_limit(clk_dvfs_node);
	}
	
	return n;
}
コード例 #4
0
int aw_pm_begin(suspend_state_t state)
{
    struct cpufreq_policy *policy;

    PM_DBG("%d state begin:%d\n", state,debug_mask);

    //set freq max
#ifdef CONFIG_CPU_FREQ_USR_EVNT_NOTIFY
    //cpufreq_user_event_notify();
#endif
    
    backup_max_freq = 0;
    backup_min_freq = 0;
    policy = cpufreq_cpu_get(0);
    if (!policy)
    {
        PM_DBG("line:%d cpufreq_cpu_get failed!\n", __LINE__);
        goto out;
    }

    backup_max_freq = policy->max;
    backup_min_freq = policy->min;
    policy->user_policy.max= suspend_freq;
    policy->user_policy.min = suspend_freq;
    cpufreq_cpu_put(policy);
    cpufreq_update_policy(0);

    /*must init perfcounter, because delay_us and delay_ms is depandant perf counter*/
#ifndef GET_CYCLE_CNT
    backup_perfcounter();
    init_perfcounters (1, 0);
#endif

    if(unlikely(debug_mask&PM_STANDBY_PRINT_REG)){
        printk("before dev suspend , line:%d\n", __LINE__);
        show_reg(SW_VA_CCM_IO_BASE, (CCU_REG_LENGTH)*4, "ccu");
        show_reg(SW_VA_PORTC_IO_BASE, GPIO_REG_LENGTH*4, "gpio");
        show_reg(SW_VA_TIMERC_IO_BASE, TMR_REG_LENGTH*4, "timer");
        show_reg(SW_VA_TWI0_IO_BASE, TWI0_REG_LENGTH*4, "twi0");
        show_reg(SW_VA_SRAM_IO_BASE, SRAM_REG_LENGTH*4, "sram");
        if (userdef_reg_addr != 0 && userdef_reg_size != 0)
        {
            show_reg(userdef_reg_addr, userdef_reg_size*4, "user defined");
        }
    }
    return 0;

out:
    return -1;
}
コード例 #5
0
ファイル: cpu_usage.c プロジェクト: netros/rklinux4.4
static void arm_mode_timer_handler(unsigned long data)
{
	int i;
	PM_DBG("enter %s\n", __func__);
	if (cpu_usage_run == 0) {
		PM_DBG("STOP\n");
		return ;
	}

	arm_mode_timer.expires  = jiffies + msecs_to_jiffies(ARM_MODE_TIMER_MSEC);
	add_timer(&arm_mode_timer);
	for(i = 0; i < cpu_usage_percent; i++) {
		mdelay(1);
	}
}
コード例 #6
0
ファイル: cpu_usage.c プロジェクト: netros/rklinux4.4
ssize_t cpu_usage_store(struct kobject *kobj, struct kobj_attribute *attr,
		const char *buf, size_t n)
{
	struct workqueue_struct	*workqueue;
	struct work_struct *work;
	char cmd[20];
	int usage = 0;
	int cpu;

	sscanf(buf, "%s %d", cmd, &usage);

	if((!strncmp(cmd, "start", strlen("start")))) {
		PM_DBG("get cmd start\n");
		cpu_usage_run = 1;
		
		cpu_usage_percent = (ARM_MODE_TIMER_MSEC * usage) / 100;


		for_each_online_cpu(cpu){
			work = &per_cpu(work_cpu_usage, cpu);
			workqueue = per_cpu(workqueue_cpu_usage, cpu);
			if (!work || !workqueue){
				PM_ERR("work or workqueue NULL\n");
				return n;
			}	
			queue_work_on(cpu, workqueue, work);
		}
#if 0
		del_timer(&arm_mode_timer);
		arm_mode_timer.expires	= jiffies + msecs_to_jiffies(ARM_MODE_TIMER_MSEC);
		add_timer(&arm_mode_timer);
#endif
	
	} else if (!strncmp(cmd, "stop", strlen("stop"))) {
コード例 #7
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
int aw_pm_begin(suspend_state_t state)
{
    PM_DBG("%d state begin:%d\n", state,debug_mask);

    //set freq max
#ifdef CONFIG_CPU_FREQ_USR_EVNT_NOTIFY
    //cpufreq_user_event_notify();
#endif
    
    /*must init perfcounter, because delay_us and delay_ms is depandant perf counter*/
#ifndef GET_CYCLE_CNT
    backup_perfcounter();
    init_perfcounters (1, 0);
#endif

    if(unlikely(debug_mask&PM_STANDBY_PRINT_REG)){
        printk("before dev suspend , line:%d\n", __LINE__);
        show_reg(SW_VA_CCM_IO_BASE, (CCU_REG_LENGTH)*4, "ccu");
        show_reg(SW_VA_PORTC_IO_BASE, GPIO_REG_LENGTH*4, "gpio");
        show_reg(SW_VA_TIMERC_IO_BASE, TMR_REG_LENGTH*4, "timer");
        show_reg(SW_VA_TWI0_IO_BASE, TWI0_REG_LENGTH*4, "twi0");
        show_reg(SW_VA_SRAM_IO_BASE, SRAM_REG_LENGTH*4, "sram");
        if (userdef_reg_addr != 0 && userdef_reg_size != 0)
        {
            show_reg(userdef_reg_addr, userdef_reg_size*4, "user defined");
        }
    }
    return 0;

}
コード例 #8
0
ファイル: clk_rate.c プロジェクト: Astralix/kernel
static int file_write(char *file_path, char *buf)
{
	struct file *file = NULL;
	mm_segment_t old_fs;
	loff_t offset = 0;

	PM_DBG("write %s %s size = %d\n", file_path, buf, strlen(buf));
	file = filp_open(file_path, O_RDWR, 0);

	if (IS_ERR(file)) {
		PM_ERR("%s error open file  %s\n", __func__, file_path);
		return -1;
	}

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	file->f_op->write(file, (char *)buf, strlen(buf), &offset);

	set_fs(old_fs);
	filp_close(file, NULL);  

	file = NULL;

	return 0;

}
コード例 #9
0
ファイル: clk_rate.c プロジェクト: Astralix/kernel
static int file_read(char *file_path, char *buf)
{
	struct file *file = NULL;
	mm_segment_t old_fs;
	loff_t offset = 0;

	PM_DBG("read %s\n", file_path);
	file = filp_open(file_path, O_RDONLY, 0);

	if (IS_ERR(file)) {
		PM_ERR("%s error open file  %s\n", __func__, file_path);
		return -1;
	}

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	file->f_op->read(file, (char *)buf, 32, &offset);
	sscanf(buf, "%s", buf);

	set_fs(old_fs);
	filp_close(file, NULL);  

	file = NULL;

	return 0;

}
コード例 #10
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_init
*
*Description: initial pm sub-system for platform;
*
*Arguments  : none;
*
*Return     : result;
*
*Notes      :
*
*********************************************************************************************************
*/
static int __init aw_pm_init(void)
{
    script_item_u item;
    script_item_u   *list = NULL;
    int cpu0_en = 0;
    int dram_selfresh_en = 0;
    int wakeup_src_cnt = 0;
    
    PM_DBG("aw_pm_init!\n");

    if (fetch_dram_para(&standby_info.dram_para) != 0)
    {
        memset(&standby_info.dram_para, 0, sizeof(standby_info.dram_para));
        pr_err("%s: fetch_dram_para err. \n", __func__);
    }
    memcpy(&mem_para_info.dram_para, &standby_info.dram_para, sizeof(standby_info.dram_para));
    
    //get standby_mode.
    if(SCIRPT_ITEM_VALUE_TYPE_INT != script_get_item("pm_para", "standby_mode", &item)){
        pr_err("%s: script_parser_fetch err. \n", __func__);
        standby_mode = 0;
        //standby_mode = 1;
        pr_err("notice: standby_mode = %d.\n", standby_mode);
    }else{
        standby_mode = item.val;
        pr_info("standby_mode = %d. \n", standby_mode);
        if(1 != standby_mode){
            pr_err("%s: not support super standby. \n",  __func__);
        }
    }

    //get wakeup_src_para cpu_en
    if(SCIRPT_ITEM_VALUE_TYPE_INT != script_get_item("wakeup_src_para", "cpu_en", &item)){
        cpu0_en = 0;
    }else{
        cpu0_en = item.val;
    }
    pr_info("cpu0_en = %d.\n", cpu0_en);

    //get dram_selfresh en
    if(SCIRPT_ITEM_VALUE_TYPE_INT != script_get_item("wakeup_src_para", "dram_selfresh_en", &item)){
        dram_selfresh_en = 1;
    }else{
        dram_selfresh_en = item.val;
    }
    pr_info("dram_selfresh_en = %d.\n", dram_selfresh_en);

    if(0 == dram_selfresh_en && 0 == cpu0_en){
        pr_err("Notice: if u don't want the dram enter selfresh mode,\n \
                make sure the cpu0 is not allowed to be powered off.\n");
        goto script_para_err;
    }else{
コード例 #11
0
ssize_t clk_rate_store(struct kobject *kobj, struct kobj_attribute *attr,
		const char *buf, size_t n)
{
	struct dvfs_node *clk_dvfs_node = NULL;
	struct clk *clk;
	char cmd[20], clk_name[20];
	unsigned long rate=0;
	int ret=0;
		
	sscanf(buf, "%s %s %lu", cmd, clk_name, &rate);
	
	PM_DBG("%s: cmd(%s), clk_name(%s), rate(%lu)\n", __func__, cmd, clk_name, rate);

	if (!strncmp(cmd, "set", strlen("set"))) {
		clk_dvfs_node = clk_get_dvfs_node(clk_name);
		if (!clk_dvfs_node) {
			PM_ERR("%s: clk(%s) get dvfs node error\n", __func__, clk_name);
			return n;
		}
		
		if (!strncmp(clk_name, "clk_core", strlen("clk_core"))) {
			if (file_write(FILE_GOV_MODE, "userspace") != 0) {
				PM_ERR("%s: set current governor error\n", __func__);
				return n;
			}
		}

		ret = dvfs_clk_enable_limit(clk_dvfs_node, rate, rate);
	} else {
		clk = clk_get(NULL, clk_name);
		if (IS_ERR_OR_NULL(clk)) {
			PM_ERR("%s: get clk(%s) err(%ld)\n", 
				__func__, clk_name, PTR_ERR(clk));
			return n;
		}
		
		if (!strncmp(cmd, "rawset", strlen("rawset"))) {
			ret = clk_set_rate(clk, rate);
		} else if (!strncmp(cmd, "open", strlen("open"))) {
			ret = clk_prepare_enable(clk);
		} else if (!strncmp(cmd, "close", strlen("close"))) {	
			clk_disable_unprepare(clk);
		}
	}

	if (ret) {
		PM_ERR("%s: set rate err(%d)", __func__, ret);
	}
	return n;
}
コード例 #12
0
/*
*********************************************************************************************************
*                           aw_pm_end
*
*Description: Notify the platform that system is in work mode now.
*
*Arguments  : none
*
*Return     : none
*
*Notes      : This function is called by the PM core right after resuming devices, to indicate to
*             the platform that the system has returned to the working state or
*             the transition to the sleep state has been aborted. This function is opposited to
*             aw_pm_begin function.
*********************************************************************************************************
*/
void aw_pm_end(void)
{
    struct cpufreq_policy *policy;

#ifndef GET_CYCLE_CNT
    #ifndef IO_MEASURE
            restore_perfcounter();
    #endif
#endif
    pm_disable_watchdog(dogMode);
    if (backup_max_freq != 0 && backup_min_freq != 0)
    {
        policy = cpufreq_cpu_get(0);
        if (!policy)
        {
            printk("cpufreq_cpu_get err! check it! aw_pm_end:%d\n", __LINE__);
            return;
        }
        
        policy->user_policy.max = backup_max_freq;
        policy->user_policy.min = backup_min_freq;
        cpufreq_cpu_put(policy);
        cpufreq_update_policy(0);
    }
    
    if(unlikely(debug_mask&PM_STANDBY_PRINT_REG)){
        printk("after dev suspend, line:%d\n", __LINE__);
        show_reg(SW_VA_CCM_IO_BASE, (CCU_REG_LENGTH)*4, "ccu");
        show_reg(SW_VA_PORTC_IO_BASE, GPIO_REG_LENGTH*4, "gpio");
        show_reg(SW_VA_TIMERC_IO_BASE, TMR_REG_LENGTH*4, "timer");
        show_reg(SW_VA_TWI0_IO_BASE, TWI0_REG_LENGTH*4, "twi0");
        show_reg(SW_VA_SRAM_IO_BASE, SRAM_REG_LENGTH*4, "sram");
        if (userdef_reg_addr != 0 && userdef_reg_size != 0)
        {
            show_reg(userdef_reg_addr, userdef_reg_size*4, "user defined");
        }
    }

    PM_DBG("aw_pm_end!\n");
}
コード例 #13
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_end
*
*Description: Notify the platform that system is in work mode now.
*
*Arguments  : none
*
*Return     : none
*
*Notes      : This function is called by the PM core right after resuming devices, to indicate to
*             the platform that the system has returned to the working state or
*             the transition to the sleep state has been aborted. This function is opposited to
*             aw_pm_begin function.
*********************************************************************************************************
*/
void aw_pm_end(void)
{
#ifndef GET_CYCLE_CNT
    #ifndef IO_MEASURE
            restore_perfcounter();
    #endif
#endif
    pm_disable_watchdog(0);
    
    if(unlikely(debug_mask&PM_STANDBY_PRINT_REG)){
        printk("after dev suspend, line:%d\n", __LINE__);
        show_reg(SW_VA_CCM_IO_BASE, (CCU_REG_LENGTH)*4, "ccu");
        show_reg(SW_VA_PORTC_IO_BASE, GPIO_REG_LENGTH*4, "gpio");
        show_reg(SW_VA_TIMERC_IO_BASE, TMR_REG_LENGTH*4, "timer");
        show_reg(SW_VA_TWI0_IO_BASE, TWI0_REG_LENGTH*4, "twi0");
        show_reg(SW_VA_SRAM_IO_BASE, SRAM_REG_LENGTH*4, "sram");
        if (userdef_reg_addr != 0 && userdef_reg_size != 0)
        {
            show_reg(userdef_reg_addr, userdef_reg_size*4, "user defined");
        }
    }

    PM_DBG("aw_pm_end!\n");
}
コード例 #14
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_wake
*
*Description: platform wakeup;
*
*Arguments  : none;
*
*Return     : none;
*
*Notes      : This function called when the system has just left a sleep state, right after
*             the nonboot CPUs have been enabled and before device drivers' early resume
*             callbacks are executed. This function is opposited to the aw_pm_prepare_late;
*********************************************************************************************************
*/
static void aw_pm_wake(void)
{
    PM_DBG("platform wakeup, wakesource is:0x%x\n", standby_info.standby_para.event);
}
コード例 #15
0
ファイル: clk_auto_volt.c プロジェクト: gtlinyun/bq-DC-v2
ssize_t clk_auto_volt_store(struct kobject *kobj, struct kobj_attribute *attr,
                            const char *buf, size_t n)
{
    char cmd[10];
    char volt_flag[10];
    char regulator_name[20];

    sscanf(buf, "%s %s %s %u %u %u %u", cmd, volt_flag, regulator_name, &begin_volt, &stop_volt, &volt_step, &timer_tick);

    if (0 == strncmp(cmd, "start", strlen("start"))) {
        if (0 == strncmp(volt_flag, "up", strlen("up"))) {
            if (begin_volt >= stop_volt) {
                PM_ERR("wrong! begin_volt >= stop_volt!\n");
                return -EINVAL;
            }
            volt_direction = VOLT_UP;

        } else if (0 == strncmp(volt_flag, "down", strlen("down"))) {
            if (begin_volt <= stop_volt) {
                PM_ERR("wrong! begin_volt <= stop_volt!\n");
                return -EINVAL;
            }
            volt_direction = VOLT_DOWN;

        } else {
            PM_ERR("argument %s is invalid!\n",volt_flag);
            return -EINVAL;
        }

        regulator = dvfs_get_regulator(regulator_name);
        if (IS_ERR_OR_NULL(regulator)) {
            PM_ERR("%s get dvfs_regulator %s error\n", __func__, regulator_name);
            return -ENOMEM;
        }

        if (wq_is_run == 1) {
            cancel_delayed_work(&scal_volt_work);
            flush_workqueue(scal_volt_wq);
            //destroy_workqueue(scal_volt_wq);
            wq_is_run = 0;
        }

        PM_DBG("begin!\n");

        volt = begin_volt;

        scal_volt_wq = create_workqueue("scal volt wq");
        INIT_DELAYED_WORK(&scal_volt_work, scal_volt_func);
        queue_delayed_work(scal_volt_wq, &scal_volt_work, msecs_to_jiffies(timer_tick*1000));

        wq_is_run = 1;

    } else if (0 == strncmp(cmd, "stop", strlen("stop"))) {
        if (wq_is_run == 1) {
            cancel_delayed_work(&scal_volt_work);
            flush_workqueue(scal_volt_wq);
            //destroy_workqueue(scal_volt_wq);
            wq_is_run = 0;
        }

    } else {
        PM_ERR("argument %s is invalid!\n", cmd);
        return -EINVAL;
    }

    return  n;
}
コード例 #16
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
static int aw_pm_valid(suspend_state_t state)
{
#ifdef CHECK_IC_VERSION
    enum sw_ic_ver version = MAGIC_VER_NULL;
#endif

    PM_DBG("valid\n");
    console_suspend_enabled = 0;

    if(!((state > PM_SUSPEND_ON) && (state < PM_SUSPEND_MAX))){
        PM_DBG("state (%d) invalid!\n", state);
        return 0;
    }

#ifdef CHECK_IC_VERSION
    if(1 == standby_mode){
        version = sw_get_ic_ver();
        if(!(MAGIC_VER_A13B == version || MAGIC_VER_A12B == version || MAGIC_VER_A10SB == version)){
            pr_info("ic version: %d not support super standby. \n", version);
            standby_mode = 0;
        }
    }
#endif

    //if 1 == standby_mode, actually, mean mem corresponding with super standby
    if(PM_SUSPEND_STANDBY == state){
        if(1 == standby_mode){
            standby_type = NORMAL_STANDBY;
        }else{
            standby_type = SUPER_STANDBY;
        }
        printk("standby_mode:%d, standby_type:%d, line:%d\n",standby_mode, standby_type, __LINE__);
    }else if(PM_SUSPEND_MEM == state || PM_SUSPEND_BOOTFAST == state){
        if(1 == standby_mode){
            standby_type = SUPER_STANDBY;
        }else{
            standby_type = NORMAL_STANDBY;
        }
        printk("standby_mode:%d, standby_type:%d, line:%d\n",standby_mode, standby_type, __LINE__);
    }
    
    //allocat space for backup dram data
    if(SUPER_STANDBY == standby_type){
        if((DRAM_BACKUP_SIZE) < ((int)&resume0_bin_end - (int)&resume0_bin_start) ){
            //judge the reserved space for resume0 is enough or not.
            pr_info("Notice: reserved space(%d) for resume is not enough(%d). \n", DRAM_BACKUP_SIZE,((int)&resume0_bin_end - (int)&resume0_bin_start));
            return 0;
        }
        
        memcpy((void *)DRAM_BACKUP_BASE_ADDR, (void *)&resume0_bin_start, (int)&resume0_bin_end - (int)&resume0_bin_start);
        dmac_flush_range((void *)DRAM_BACKUP_BASE_ADDR, (void *)(DRAM_BACKUP_BASE_ADDR + DRAM_BACKUP_SIZE -1) );
    }
        
#ifdef GET_CYCLE_CNT
        // init counters:
        init_perfcounters (1, 0);
#endif

    return 1;

}
コード例 #17
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_recover
*
*Description: Recover platform from a suspend failure;
*
*Arguments  : none
*
*Return     : none
*
*Notes      : This function alled by the PM core if the suspending of devices fails.
*             This callback is optional and should only be implemented by platforms
*             which require special recovery actions in that situation.
*********************************************************************************************************
*/
void aw_pm_recover(void)
{
    PM_DBG("aw_pm_recover\n");
}
コード例 #18
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_finish
*
*Description: Finish wake-up of the platform;
*
*Arguments  : none
*
*Return     : none
*
*Notes      : This function is called right prior to calling device drivers' regular suspend
*              callbacks. This function is opposited to the aw_pm_prepare function.
*********************************************************************************************************
*/
void aw_pm_finish(void)
{
    PM_DBG("platform wakeup finish\n");
}
コード例 #19
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_enter
*
*Description: Enter the system sleep state;
*
*Arguments  : state     system sleep state;
*
*Return     : return 0 is process successed;
*
*Notes      : this function is the core function for platform sleep.
*********************************************************************************************************
*/
static int aw_pm_enter(suspend_state_t state)
{
//  asm volatile ("stmfd sp!, {r1-r12, lr}" );
    normal_standby_func standby;
    
    PM_DBG("enter state %d\n", state);

    if(unlikely(debug_mask&PM_STANDBY_PRINT_REG)){
        printk("after cpu suspend , line:%d\n", __LINE__);
        show_reg(SW_VA_CCM_IO_BASE, (CCU_REG_LENGTH)*4, "ccu");
        show_reg(SW_VA_PORTC_IO_BASE, GPIO_REG_LENGTH*4, "gpio");
        show_reg(SW_VA_TIMERC_IO_BASE, TMR_REG_LENGTH*4, "timer");
        show_reg(SW_VA_TWI0_IO_BASE, TWI0_REG_LENGTH*4, "twi0");
        show_reg(SW_VA_SRAM_IO_BASE, SRAM_REG_LENGTH*4, "sram");
        if (userdef_reg_addr != 0 && userdef_reg_size != 0)
        {
            show_reg(userdef_reg_addr, userdef_reg_size*4, "user defined");
        }
    }

    standby_info.standby_para.axp_enable = standby_axp_enable;
    
    if(NORMAL_STANDBY== standby_type){
        standby = (int (*)(struct aw_pm_info *arg))SRAM_FUNC_START;
        //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 */
        if(PM_SUSPEND_MEM == state || PM_SUSPEND_STANDBY == state){
            standby_info.standby_para.axp_src = AXP_MEM_WAKEUP;
        }else if(PM_SUSPEND_BOOTFAST == state){
            standby_info.standby_para.axp_src = AXP_BOOTFAST_WAKEUP;
        }
        standby_info.standby_para.event_enable = (SUSPEND_WAKEUP_SRC_EXINT | SUSPEND_WAKEUP_SRC_ALARM);

        if (standby_timeout != 0)
        {
            standby_info.standby_para.event_enable |= (SUSPEND_WAKEUP_SRC_TIMEOFF);
            standby_info.standby_para.time_off = standby_timeout;
        }
        /* goto sram and run */
        printk("standby_mode:%d, standby_type:%d, line:%d\n",standby_mode, standby_type, __LINE__);
        standby(&standby_info);
        printk("standby_mode:%d, standby_type:%d, line:%d\n",standby_mode, standby_type, __LINE__);
    }else if(SUPER_STANDBY == standby_type){
        printk("standby_mode:%d, standby_type:%d, line:%d\n",standby_mode, standby_type, __LINE__);
            print_call_info();
            aw_super_standby(state);    
    }
    pm_enable_watchdog();
    print_call_info();

    if(unlikely(debug_mask&PM_STANDBY_PRINT_REG)){
        printk("after cpu suspend , line:%d\n", __LINE__);
        show_reg(SW_VA_CCM_IO_BASE, (CCU_REG_LENGTH)*4, "ccu");
        show_reg(SW_VA_PORTC_IO_BASE, GPIO_REG_LENGTH*4, "gpio");
        show_reg(SW_VA_TIMERC_IO_BASE, TMR_REG_LENGTH*4, "timer");
        show_reg(SW_VA_TWI0_IO_BASE, TWI0_REG_LENGTH*4, "twi0");
        show_reg(SW_VA_SRAM_IO_BASE, SRAM_REG_LENGTH*4, "sram");
        if (userdef_reg_addr != 0 && userdef_reg_size != 0)
        {
            show_reg(userdef_reg_addr, userdef_reg_size*4, "user defined");
        }
    }
//  asm volatile ("ldmfd sp!, {r1-r12, lr}" );
    return 0;
}
コード例 #20
0
ファイル: pm.c プロジェクト: dwlinux/Armcore_a20_V30_lichee
/*
*********************************************************************************************************
*                           aw_pm_prepare_late
*
*Description: Finish preparing the platform for entering the system sleep state.
*
*Arguments  : none;
*
*Return     : return 0 for process successed, and negative code for error;
*
*Notes      : this is a call-back function, registered into PM core.
*             prepare_late is called before disabling nonboot CPUs and after
*              device drivers' late suspend callbacks have been executed;
*********************************************************************************************************
*/
int aw_pm_prepare_late(void)
{
    PM_DBG("prepare_late\n");

    return 0;
}