Example #1
0
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));
}
Example #3
0
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));
}