static unsigned long scaling_state_check(struct devfreq *df, ktime_t time) { struct podgov_info_rec *podgov = df->data; unsigned long dt; /* adjustment: set scale parameters (idle_min, idle_max) +/- 25% * based on ratio of scale up to scale down hints */ if (podgov->p_adjust) scaling_adjust(podgov, time); else { podgov->idle_min = podgov->p_idle_min; podgov->idle_max = podgov->p_idle_max; } dt = (unsigned long) ktime_us_delta(time, podgov->last_scale); if (dt < podgov->p_estimation_window) return 0; podgov->last_scale = time; /* if too busy, scale up */ if (podgov->idle_estimate < podgov->idle_min) { podgov->is_scaled = 0; podgov->fast_up_count++; trace_podgov_busy(1000 - podgov->idle_estimate); trace_podgov_scaling_state_check(df->previous_freq, df->max_freq); return df->max_freq; } trace_podgov_idle(podgov->idle_estimate); if (podgov->idle_estimate > podgov->idle_max) { if (!podgov->is_scaled) podgov->is_scaled = 1; podgov->slow_down_count++; /* if idle time is high, clock down */ podgov->scale = 100 - (podgov->idle_estimate - podgov->idle_min) / 10; schedule_work(&podgov->work); } return 0; }
static void scaling_state_check(ktime_t time) { unsigned long dt; /* adjustment: set scale parameters (fast_response, period) +/- 25% * based on ratio of scale up to scale down hints */ if (scale3d.p_adjust) scaling_adjust(time); else { scale3d.fast_response = scale3d.p_fast_response; scale3d.period = scale3d.p_period; scale3d.idle_min = scale3d.p_idle_min; scale3d.idle_max = scale3d.p_idle_max; } /* check for load peaks */ dt = (unsigned long) ktime_us_delta(time, scale3d.fast_frame); if (dt > scale3d.fast_response) { unsigned long idleness = (scale3d.idle_short_term_total * 100) / dt; scale3d.fast_responses++; scale3d.fast_frame = time; /* if too busy, scale up */ if (idleness < scale3d.idle_min) { scale3d.is_scaled = 0; scale3d.fast_up_count++; if (scale3d.p_verbosity >= 5) pr_info("scale3d: %ld%% busy\n", 100 - idleness); reset_3d_clocks(); reset_scaling_counters(time); return; } scale3d.idle_short_term_total = 0; scale3d.last_short_term_idle = time; } dt = (unsigned long) ktime_us_delta(time, scale3d.idle_frame); if (dt > scale3d.period) { unsigned long idleness = (scale3d.idle_total * 100) / dt; if (scale3d.p_verbosity >= 5) pr_info("scale3d: idle %lu, ~%lu%%\n", scale3d.idle_total, idleness); if (idleness > scale3d.idle_max) { if (!scale3d.is_scaled) { scale3d.is_scaled = 1; scale3d.last_down = time; } scale3d.slow_down_count++; /* if idle time is high, clock down */ scale3d.scale = 100 - (idleness - scale3d.idle_min); schedule_work(&scale3d.work); } reset_scaling_counters(time); } }