static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b, const char *buf, size_t count) { int input = 0; int bypass = 0; int ret, cpu, reenable_timer; struct greenmax_info_s *greenmax_info; ret = sscanf(buf, "%d", &input); if (ret != 1) return -EINVAL; if (input >= POWERSAVE_BIAS_MAXLEVEL) { input = POWERSAVE_BIAS_MAXLEVEL; bypass = 1; } else if (input <= POWERSAVE_BIAS_MINLEVEL) { input = POWERSAVE_BIAS_MINLEVEL; bypass = 1; } if (input == powersave_bias) { /* no change */ return count; } reenable_timer = ((powersave_bias == POWERSAVE_BIAS_MAXLEVEL) || (powersave_bias == POWERSAVE_BIAS_MINLEVEL)); powersave_bias = input; if (!bypass) { if (reenable_timer) { /* reinstate dbs timer */ for_each_online_cpu(cpu) { if (lock_policy_rwsem_write(cpu) < 0) continue; greenmax_info_s = &per_cpu(greenmax_info, cpu); if (this_greenmax->cur_policy) { /* restart dbs timer */ dbs_timer_init(greenmax_info_s); } unlock_policy_rwsem_write(cpu); } } greenmax_powersave_bias_init(); } else {
static s32 cpufreq_governor_dbs(struct cpufreq_policy *policy, u32 event) { s32 cpu = (s32)policy->cpu; struct cpu_dbs_info_s *dbs_info = NULL; u32 retValue = 0; ST_PWC_SWITCH_STRU cpufreq_control_nv = {0} ; /*cpu 信息*/ dbs_info = &per_cpu(g_acpu_dbs_info, (u32)cpu); /*lint --e{744 } */ switch (event) { case CPUFREQ_GOV_START: cpufreq_debug("CPUFREQ_GOV_START\n"); mutex_lock(&dbs_mutex); dbs_enable++; /*cpu 信息初始化 函数??idle_time*/ dbs_info->prev_cpu_idle = get_cpu_idle_time(0, &dbs_info->prev_cpu_wall); dbs_info->cur_policy = policy; dbs_info->cpu = cpu; dbs_info->freq_table = cpufreq_frequency_get_table((u32)cpu); dbs_info->cpu_down_time = 0; dbs_info->cpu_up_time = 0; retValue = bsp_nvm_read(NV_ID_DRV_NV_PWC_SWITCH,(u8*)&cpufreq_control_nv,sizeof(ST_PWC_SWITCH_STRU)); if (NV_OK == retValue) { g_cpufreq_lock_status_flag = cpufreq_control_nv.dfs; } else { cpufreq_err("read nv failed %d\n", retValue); } if (1 == dbs_enable) { retValue = bsp_nvm_read(NV_ID_DRV_NV_DFS_SWITCH,(u8*)&g_stDfsSwitch,sizeof(ST_PWC_DFS_STRU)); if (NV_OK != retValue) { cpufreq_err("read nv failed use default value\n"); g_stDfsSwitch.AcpuDownLimit = 20; g_stDfsSwitch.AcpuDownNum = 3; g_stDfsSwitch.AcpuUpLimit = 80; g_stDfsSwitch.AcpuUpNum = 1; g_stDfsSwitch.DFSTimerLen = 400; } dbs_tuners_ins.up_threshold = g_stDfsSwitch.AcpuUpLimit; dbs_tuners_ins.down_threshold = g_stDfsSwitch.AcpuDownLimit; dbs_tuners_ins.down_threshold_times = g_stDfsSwitch.AcpuDownNum; dbs_tuners_ins.up_threshold_times = g_stDfsSwitch.AcpuUpNum; dbs_tuners_ins.sampling_rate = g_stDfsSwitch.DFSTimerLen * 10000; /*unit:us*/ /* * Start the timerschedule work, when this governor * is used for first time */ register_icc_for_cpufreq(); dbs_timer_init(dbs_info); } mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_STOP: dbs_timer_exit(dbs_info); mutex_lock(&dbs_mutex); dbs_enable--; mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_LIMITS: mutex_lock(&info_mutex); dbs_info->cpu_down_time = 0; dbs_info->cpu_up_time = 0; mutex_unlock(&info_mutex); if (policy->max < dbs_info->cur_policy->cur) __cpufreq_driver_target(dbs_info->cur_policy, policy->max, CPUFREQ_RELATION_H); else if (policy->min > dbs_info->cur_policy->cur) __cpufreq_driver_target(dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); break; } return 0; }