static void __cpuinit sleepy_plug_work_fn(struct work_struct *work) { enum mp_decisions decision = DO_NOTHING; if (sleepy_plug_active == 1) { // detect artificial loads or constant loads // using msm rqstats decision = mp_decision(); #ifdef DEBUG_SLEEPY_PLUG pr_info("decision: %d\n",decision); #endif if (!suspended) { if (decision == CPU_UP) { cpu_up(1); sampling_time = BUSY_SAMPLING_MS; } else if(decision == CPU_DOWN){ cpu_down(1); sampling_time = DEF_SAMPLING_MS; } else if(decision == DO_NOTHING) sampling_time = DEF_SAMPLING_MS; } #ifdef DEBUG_SLEEPY_PLUG else pr_info("sleepy_plug is suspened!\n"); #endif } queue_delayed_work_on(0, sleepy_plug_wq, &sleepy_plug_work, msecs_to_jiffies(sampling_time)); }
static void __cpuinit intelli_plug_work_fn(struct work_struct *work) { unsigned int nr_run_stat; unsigned int cpu_count = 0; unsigned int nr_cpus = 0; int decision = 0; int i; if (intelli_plug_active == 1) { nr_run_stat = calculate_thread_stats(); #ifdef DEBUG_INTELLI_PLUG pr_info("nr_run_stat: %u\n", nr_run_stat); #endif cpu_count = nr_run_stat; // detect artificial loads or constant loads // using msm rqstats nr_cpus = num_online_cpus(); if (!eco_mode_active && (nr_cpus >= 1 && nr_cpus < 4)) { decision = mp_decision(); if (decision) { switch (nr_cpus) { case 2: cpu_count = 3; #ifdef DEBUG_INTELLI_PLUG pr_info("nr_run(2) => %u\n", nr_run_stat); #endif break; case 3: cpu_count = 4; #ifdef DEBUG_INTELLI_PLUG pr_info("nr_run(3) => %u\n", nr_run_stat); #endif break; } } } /* it's busy.. lets help it a bit */ if (cpu_count > 2) { if (busy_persist_count == 0) { sampling_time = BUSY_SAMPLING_MS; busy_persist_count = BUSY_PERSISTENCE; } } else { if (busy_persist_count > 0) busy_persist_count--; else sampling_time = DEF_SAMPLING_MS; } if (!suspended) { switch (cpu_count) { case 1: if (persist_count > 0) persist_count--; if (persist_count == 0) { //take down everyone for (i = 3; i > 0; i--) cpu_down(i); } #ifdef DEBUG_INTELLI_PLUG pr_info("case 1: %u\n", persist_count); #endif break; case 2: persist_count = DUAL_CORE_PERSISTENCE; if (!decision) persist_count = DUAL_CORE_PERSISTENCE / CPU_DOWN_FACTOR; if (nr_cpus < 2) { for (i = 1; i < cpu_count; i++) cpu_up(i); } else { for (i = 3; i > 1; i--) cpu_down(i); } #ifdef DEBUG_INTELLI_PLUG pr_info("case 2: %u\n", persist_count); #endif break; case 3: persist_count = TRI_CORE_PERSISTENCE; if (!decision) persist_count = TRI_CORE_PERSISTENCE / CPU_DOWN_FACTOR; if (nr_cpus < 3) { for (i = 1; i < cpu_count; i++) cpu_up(i); } else { for (i = 3; i > 2; i--) cpu_down(i); } #ifdef DEBUG_INTELLI_PLUG pr_info("case 3: %u\n", persist_count); #endif break; case 4: persist_count = QUAD_CORE_PERSISTENCE; if (!decision) persist_count = QUAD_CORE_PERSISTENCE / CPU_DOWN_FACTOR; if (nr_cpus < 4) for (i = 1; i < cpu_count; i++) cpu_up(i); #ifdef DEBUG_INTELLI_PLUG pr_info("case 4: %u\n", persist_count); #endif break; default: pr_err("Run Stat Error: Bad value %u\n", nr_run_stat); break; } } #ifdef DEBUG_INTELLI_PLUG else pr_info("intelli_plug is suspened!\n"); #endif } schedule_delayed_work_on(0, &intelli_plug_work, msecs_to_jiffies(sampling_time)); }
void gcpu_plug(unsigned int cpu_freq) { unsigned long up_delay, top_freq, bottom_freq; static bool first_call = true; static cputime64_t total_time = 0; static cputime64_t last_time; cputime64_t current_time; cputime64_t this_time = 0; mutex_lock(&tegra3_plug_lock); if (is_plugging) { mutex_unlock(&tegra3_plug_lock); return; } mutex_unlock(&tegra3_plug_lock); current_time = ktime_to_ms(ktime_get()); if (first_call) { first_call = false; } else { this_time = current_time - last_time; } total_time += this_time; up_delay = up2gn_delay; top_freq = idle_bottom_freq; bottom_freq = idle_bottom_freq; mp_state = mp_decision(); switch (hp_state) { case TEGRA_HP_DISABLED: total_time = 0; break; case TEGRA_HP_IDLE: if (cpu_freq > top_freq) { hp_state = TEGRA_HP_UP; } else if (cpu_freq <= bottom_freq) { hp_state = TEGRA_HP_DOWN; } total_time = 0; break; case TEGRA_HP_DOWN: if (cpu_freq > top_freq) { hp_state = TEGRA_HP_UP; total_time = 0; } break; case TEGRA_HP_UP: if (cpu_freq <= bottom_freq) { hp_state = TEGRA_HP_DOWN; total_time = 0; } break; } if (hp_state == TEGRA_HP_UP) { switch (tegra_cpu_speed_balance()) { /* cpu speed is up and balanced - one more on-line */ case TEGRA_CPU_SPEED_BALANCED: if ((total_time >= up_time) && (mp_state == TEGRA_HP_UP)) { mutex_lock(&tegra3_plug_lock); is_plugging = true; last_state = TEGRA_HP_UP; mutex_unlock(&tegra3_plug_lock); queue_work(cpuplug_wq, &cpuplug_work); total_time = 0; } break; /* cpu speed is up, but skewed - remove one core */ case TEGRA_CPU_SPEED_SKEWED: if ((total_time >= down_time) && (mp_state == TEGRA_HP_DOWN)) { mutex_lock(&tegra3_plug_lock); is_plugging = true; last_state = TEGRA_HP_DOWN; mutex_unlock(&tegra3_plug_lock); queue_work(cpuplug_wq, &cpuplug_work); total_time = 0; } break; /* cpu speed is up, but under-utilized - do nothing */ case TEGRA_CPU_SPEED_BIASED: if (total_time >= up_time) total_time = 0; default: break; } } else if (hp_state == TEGRA_HP_DOWN) { if ((total_time >= down_time) && (mp_state == TEGRA_HP_DOWN)) { mutex_lock(&tegra3_plug_lock); is_plugging = true; last_state = TEGRA_HP_DOWN; mutex_unlock(&tegra3_plug_lock); queue_work(cpuplug_wq, &cpuplug_work); total_time = 0; } } last_time = ktime_to_ms(ktime_get()); }
static void __ref intelli_plug_work_fn(struct work_struct *work) { unsigned int nr_run_stat; unsigned int cpu_count = 0; unsigned int nr_cpus = 0; int decision = 0; int i; nr_run_stat = calculate_thread_stats(); if (debug_intelli_plug) pr_info("nr_run_stat: %u\n", nr_run_stat); cpu_count = nr_run_stat; /* detect artificial loads or constant loads * using msm rqstats */ nr_cpus = num_online_cpus(); if (!eco_mode_active && !strict_mode_active && (nr_cpus >= 1 && nr_cpus < 4)) { decision = mp_decision(); if (decision) { switch (nr_cpus) { case 2: cpu_count = 3; if (debug_intelli_plug) pr_info("nr_run(2) => %u\n", nr_run_stat); break; case 3: cpu_count = 4; if (debug_intelli_plug) pr_info("nr_run(3) => %u\n", nr_run_stat); break; } } } /* it's busy.. lets help it a bit */ if (cpu_count > 2) { if (busy_persist_count == 0) { sampling_time = busy_sampling_ms; busy_persist_count = busy_persistence; } } else { if (busy_persist_count > 0) busy_persist_count--; else sampling_time = def_sampling_ms; } if (!hotplug_suspended) { switch (cpu_count) { case 1: if (persist_count > 0) persist_count--; if (persist_count == 0) { /* take down everyone */ for (i = 3; i > 0; i--) cpu_down(i); } if (debug_intelli_plug) pr_info("case 1: %u\n", persist_count); break; case 2: persist_count = dual_core_persistence; if (!decision) persist_count = dual_core_persistence / cpu_down_factor; if (nr_cpus < 2) { for (i = 1; i < cpu_count; i++) cpu_up(i); } else { for (i = 3; i > 1; i--) cpu_down(i); } if (debug_intelli_plug) pr_info("case 2: %u\n", persist_count); break; case 3: persist_count = tri_core_persistence; if (!decision) persist_count = tri_core_persistence / cpu_down_factor; if (nr_cpus < 3) { for (i = 1; i < cpu_count; i++) cpu_up(i); } else { for (i = 3; i > 2; i--) cpu_down(i); } if (debug_intelli_plug) pr_info("case 3: %u\n", persist_count); break; case 4: persist_count = quad_core_persistence; if (!decision) persist_count = quad_core_persistence / cpu_down_factor; if (nr_cpus < 4) for (i = 1; i < cpu_count; i++) cpu_up(i); if (debug_intelli_plug) pr_info("case 4: %u\n", persist_count); break; default: pr_err("Run Stat Error: Bad value %u\n", nr_run_stat); break; } } else if (debug_intelli_plug) pr_info("intelli_plug is suspened!\n"); queue_delayed_work_on(0, intelliplug_wq, &intelli_plug_work, msecs_to_jiffies(sampling_time)); }