コード例 #1
0
static void input_booster_set_dvfs_tsp_lock(struct input_booster *booster, int on)
{
	int retval = 0;

	if (booster->dvfs_boost_mode == DVFS_STAGE_NONE) {
		pr_debug("%s: DVFS stage is none(%d)\n",
				__func__, booster->dvfs_boost_mode);
		return;
	}

	mutex_lock(&booster->dvfs_lock);

	if (on == 0) {
		if (booster->dvfs_lock_status) {
			switch (booster->dvfs_boost_mode) {
			case DVFS_STAGE_SINGLE:
			case DVFS_STAGE_DUAL:
			case DVFS_STAGE_TRIPLE:
			case DVFS_STAGE_PENTA:
				schedule_delayed_work(&booster->work_dvfs_off,
					msecs_to_jiffies(INPUT_BOOSTER_OFF_TIME_TSP));
				break;
			case DVFS_STAGE_NINTH:
				schedule_delayed_work(&booster->work_dvfs_off,
					msecs_to_jiffies(INPUT_BOOSTER_HIGH_OFF_TIME_TSP));
				break;
			}
		}
	} else if (on > 0) {
		cancel_delayed_work(&booster->work_dvfs_off);

		if ((!booster->dvfs_lock_status) || (booster->dvfs_old_stauts < on)) {
			cancel_delayed_work(&booster->work_dvfs_chg);

			switch (booster->dvfs_boost_mode) {
			case DVFS_STAGE_SINGLE:
			case DVFS_STAGE_DUAL:
#ifdef CONFIG_CPUFREQ_HARDLIMIT
				if (booster->dvfs_freq != check_cpufreq_hardlimit(touchboost_hi_freq)) {
					retval = set_freq_limit(DVFS_TOUCH_ID,
							check_cpufreq_hardlimit(touchboost_hi_freq));
#else
				if (booster->dvfs_freq != MIN_TOUCH_LIMIT) {
                    retval = set_freq_limit(DVFS_TOUCH_ID,
							MIN_TOUCH_LIMIT);
#endif
#if INPUT_BIMC_MINLOCK
					pr_info("%s: bimc clk set: %d\n",
							__func__, INPUT_BIMC_LIMIT);
					request_bimc_clk(INPUT_BIMC_LIMIT);
#endif
#ifdef CONFIG_CPUFREQ_HARDLIMIT
					booster->dvfs_freq = check_cpufreq_hardlimit(touchboost_hi_freq);
#else
					booster->dvfs_freq = MIN_TOUCH_LIMIT;
#endif
				}
				schedule_delayed_work(&booster->work_dvfs_chg,
					msecs_to_jiffies(INPUT_BOOSTER_CHG_TIME_TSP));
				break;
			case DVFS_STAGE_TRIPLE:
#ifdef CONFIG_CPUFREQ_HARDLIMIT
				if (booster->dvfs_freq != check_cpufreq_hardlimit(touchboost_lo_freq)) {
					retval = set_freq_limit(DVFS_TOUCH_ID,
							check_cpufreq_hardlimit(touchboost_lo_freq));
#else
				if (booster->dvfs_freq != MIN_TOUCH_LIMIT_SECOND) {
					retval = set_freq_limit(DVFS_TOUCH_ID,
							MIN_TOUCH_LIMIT_SECOND);
#endif
#if INPUT_BIMC_MINLOCK
					pr_info("%s: bimc clk set: %d\n",
							__func__, INPUT_BIMC_SECOND_LIMIT);
					request_bimc_clk(INPUT_BIMC_SECOND_LIMIT);
#endif
#ifdef CONFIG_CPUFREQ_HARDLIMIT
					booster->dvfs_freq = check_cpufreq_hardlimit(touchboost_lo_freq);
#else
                    booster->dvfs_freq = MIN_TOUCH_LIMIT_SECOND;
#endif
				}
				schedule_delayed_work(&booster->work_dvfs_chg,
					msecs_to_jiffies(INPUT_BOOSTER_CHG_TIME_TSP));
				break;
			case DVFS_STAGE_PENTA:
				if (booster->dvfs_freq != MIN_TOUCH_LOW_LIMIT) {
					retval = set_freq_limit(DVFS_TOUCH_ID,
							MIN_TOUCH_LOW_LIMIT);
#if INPUT_BIMC_MINLOCK
					pr_info("%s: bimc clk set: %d\n",
							__func__, INPUT_BIMC_LOW_LIMIT);
					request_bimc_clk(INPUT_BIMC_LOW_LIMIT);
#endif
					booster->dvfs_freq = MIN_TOUCH_LOW_LIMIT;
				}
				schedule_delayed_work(&booster->work_dvfs_chg,
					msecs_to_jiffies(INPUT_BOOSTER_CHG_TIME_TSP));
				break;
			case DVFS_STAGE_NINTH:
				if (booster->dvfs_freq != MIN_TOUCH_HIGH_LIMIT) {
					retval = set_freq_limit(DVFS_TOUCH_ID,
							MIN_TOUCH_HIGH_LIMIT);
#if INPUT_BIMC_MINLOCK
					pr_info("%s: bimc clk set: %d\n",
							__func__, INPUT_BIMC_HIGH_LIMIT);
					request_bimc_clk(INPUT_BIMC_HIGH_LIMIT);
#endif
					booster->dvfs_freq = MIN_TOUCH_HIGH_LIMIT;
				}
				schedule_delayed_work(&booster->work_dvfs_chg,
					msecs_to_jiffies(INPUT_BOOSTER_HIGH_CHG_TIME_TSP));
				break;

			}

			if (retval < 0)
				pr_err("%s: cpu first lock failed(%d)\n",
						__func__, retval);

			booster->dvfs_lock_status = true;
		}

	} else if (on < 0) {
コード例 #2
0
static int boost_mig_sync_thread(void *data)
{
	int dest_cpu = (int) data;
	int src_cpu, ret;
	struct cpu_sync *s = &per_cpu(sync_info, dest_cpu);
	struct cpufreq_policy dest_policy;
	struct cpufreq_policy src_policy;
	unsigned long flags;
	unsigned int req_freq;

	if (!cpuboost_enable) return 0;

	while (1) {
		wait_event(s->sync_wq, s->pending || kthread_should_stop());
#ifdef CONFIG_IRLED_GPIO
		if (unlikely(gir_boost_disable)) {
			pr_debug("[GPIO_IR][%s] continue~!(cpu:%d)\n", 
				__func__, raw_smp_processor_id());
			continue;
		}
#endif

		if (kthread_should_stop())
			break;

		spin_lock_irqsave(&s->lock, flags);
		s->pending = false;
		src_cpu = s->src_cpu;
		spin_unlock_irqrestore(&s->lock, flags);

		ret = cpufreq_get_policy(&src_policy, src_cpu);
		if (ret)
			continue;

		ret = cpufreq_get_policy(&dest_policy, dest_cpu);
		if (ret)
			continue;

		if (s->task_load < migration_load_threshold)
			continue;

		if (s->task_load < migration_load_threshold)
			continue;

		req_freq = load_based_syncs ?
			(dest_policy.max * s->task_load) / 100 : src_policy.cur;

		if (req_freq <= dest_policy.cpuinfo.min_freq) {
			pr_debug("No sync. Sync Freq:%u\n", req_freq);
			continue;
		}

		if (sync_threshold)
			req_freq = min(sync_threshold, req_freq);

		cancel_delayed_work_sync(&s->boost_rem);

#ifdef CONFIG_CPUFREQ_HARDLIMIT
        s->boost_min = check_cpufreq_hardlimit(req_freq);
#else
		s->boost_min = req_freq;
#endif

		/* Force policy re-evaluation to trigger adjust notifier. */
		get_online_cpus();
		if (cpu_online(src_cpu))
			/*
			 * Send an unchanged policy update to the source
			 * CPU. Even though the policy isn't changed from
			 * its existing boosted or non-boosted state
			 * notifying the source CPU will let the governor
			 * know a boost happened on another CPU and that it
			 * should re-evaluate the frequency at the next timer
			 * event without interference from a min sample time.
			 */
			cpufreq_update_policy(src_cpu);
		if (cpu_online(dest_cpu)) {
			cpufreq_update_policy(dest_cpu);
			queue_delayed_work_on(dest_cpu, cpu_boost_wq,
				&s->boost_rem, msecs_to_jiffies(boost_ms));
		} else {
			s->boost_min = 0;
		}
		put_online_cpus();
	}

	return 0;
}
コード例 #3
0
static void input_booster_change_dvfs_tsp_work(struct work_struct *work)
{
	int retval = 0;
	struct input_booster *booster =
		container_of(work,
				struct input_booster, work_dvfs_chg.work);

	mutex_lock(&booster->dvfs_lock);

	switch (booster->dvfs_boost_mode) {
	case DVFS_STAGE_SINGLE:
	case DVFS_STAGE_TRIPLE:
	case DVFS_STAGE_PENTA:
		retval = set_freq_limit(DVFS_TOUCH_ID, -1);
#if INPUT_BIMC_MINLOCK
		pr_info("%s: bimc clk set: 0\n", __func__);
		request_bimc_clk(0);
#endif
		booster->dvfs_freq = -1;
		break;
	case DVFS_STAGE_DUAL:
#ifdef CONFIG_CPUFREQ_HARDLIMIT
		retval = set_freq_limit(DVFS_TOUCH_ID,
				check_cpufreq_hardlimit(touchboost_lo_freq));
#else
		retval = set_freq_limit(DVFS_TOUCH_ID,
				MIN_TOUCH_LIMIT_SECOND);
#endif
#if INPUT_BIMC_MINLOCK
		pr_info("%s: bimc clk set: %d\n",
				__func__, INPUT_BIMC_SECOND_LIMIT);
		request_bimc_clk(INPUT_BIMC_SECOND_LIMIT);
#endif
#ifdef CONFIG_CPUFREQ_HARDLIMIT
		booster->dvfs_freq = check_cpufreq_hardlimit(touchboost_lo_freq);
#else
		booster->dvfs_freq = MIN_TOUCH_LIMIT_SECOND;
#endif
		break;
	case DVFS_STAGE_NINTH:
#ifdef CONFIG_CPUFREQ_HARDLIMIT
        retval = set_freq_limit(DVFS_TOUCH_ID,
                check_cpufreq_hardlimit(touchboost_hi_freq));
#else
		retval = set_freq_limit(DVFS_TOUCH_ID,
				MIN_TOUCH_LIMIT);
#endif
#if INPUT_BIMC_MINLOCK
		pr_info("%s: bimc clk set: %d\n",
				__func__, INPUT_BIMC_LIMIT);
		request_bimc_clk(INPUT_BIMC_LIMIT);
#endif
#ifdef CONFIG_CPUFREQ_HARDLIMIT
        booster->dvfs_freq = check_cpufreq_hardlimit(touchboost_hi_freq);
#else
		booster->dvfs_freq = MIN_TOUCH_LIMIT;
#endif
		break;
	}

	if (retval < 0)
		pr_err("%s: booster change failed(%d).\n",
				__func__, retval);
	mutex_unlock(&booster->dvfs_lock);
}