static int hp_state_set(const char *arg, const struct kernel_param *kp)
{
    int ret = 0;
    int old_state;

    if (!tegra3_cpu_lock)
        return ret;

    mutex_lock(tegra3_cpu_lock);

    old_state = hp_state;
    ret = param_set_bool(arg, kp);	/* set idle or disabled only */

    if (ret == 0) {
        if ((hp_state == TEGRA_HP_DISABLED) &&
                (old_state != TEGRA_HP_DISABLED))
            pr_info("Tegra auto-hotplug disabled\n");
        else if (hp_state != TEGRA_HP_DISABLED) {
            if (old_state == TEGRA_HP_DISABLED) {
                pr_info("Tegra auto-hotplug enabled\n");
                hp_init_stats();
            }
            /* catch-up with governor target speed */
            tegra_cpu_set_speed_cap(NULL);
        }
    } else
        pr_warn("%s: unable to set tegra hotplug state %s\n",
                __func__, arg);

    mutex_unlock(tegra3_cpu_lock);
    return ret;
}
int tegra_auto_hotplug_init(struct mutex *cpu_lock)
{
	/*
	 * Not bound to the issuer CPU (=> high-priority), has rescue worker
	 * task, single-threaded, freezable.
	 */
	int i = 0;
	hotplug_wq = alloc_workqueue(
		"cpu-tegra3", WQ_UNBOUND | WQ_RESCUER | WQ_FREEZABLE, 1);
	if (!hotplug_wq)
		return -ENOMEM;
	INIT_DELAYED_WORK(&hotplug_work, tegra_auto_hotplug_work_func);

	cpuplug_wq = alloc_workqueue(
		"cpu-tegra3-plug", WQ_UNBOUND | WQ_RESCUER | WQ_FREEZABLE, 1);
	if (!cpuplug_wq)
		return -ENOMEM;
	INIT_WORK(&cpuplug_work, tegra_auto_cpuplug_work_func);

	cpu_clk = clk_get_sys(NULL, "cpu");
	cpu_g_clk = clk_get_sys(NULL, "cpu_g");
	cpu_lp_clk = clk_get_sys(NULL, "cpu_lp");
	if (IS_ERR(cpu_clk) || IS_ERR(cpu_g_clk) || IS_ERR(cpu_lp_clk))
		return -ENOENT;

	idle_top_freq = clk_get_max_rate(cpu_lp_clk) / 1000;
	idle_bottom_freq = clk_get_min_rate(cpu_g_clk) / 1000;

	up2g0_delay = msecs_to_jiffies(UP2G0_DELAY_MS);
	up2gn_delay = msecs_to_jiffies(UP2Gn_DELAY_MS);
	down_delay = msecs_to_jiffies(DOWN_DELAY_MS);

	is_plugging = false;

	tegra3_cpu_lock = cpu_lock;
	hp_state = INITIAL_STATE;
	mp_state = TEGRA_HP_IDLE;
	hp_init_stats();
	pr_info(CPU_HOTPLUG_TAG"Tegra auto-hotplug initialized: %s\n",
		(hp_state == TEGRA_HP_DISABLED) ? "disabled" : "enabled");
	for (i = 0; i <= CONFIG_NR_CPUS; i++) {
		cpu_hp_active_time_stats[i].this_active_Time = 0;
		cpu_hp_active_time_stats[i].total_active_Time = 0;
	}
	pm_debug_cpu_hotplug = printCPUTotalActiveTime;

	if (pm_qos_add_notifier(PM_QOS_MIN_ONLINE_CPUS, &min_cpus_notifier))
		pr_err("%s: Failed to register min cpus PM QoS notifier\n",
			__func__);

	return 0;
}
Пример #3
0
int tegra_auto_hotplug_init(struct mutex *cpu_lock)
{
	/*
	 * Not bound to the issuer CPU (=> high-priority), has rescue worker
	 * task, single-threaded, freezable.
	 */
	hotplug_wq = alloc_workqueue(
		"cpu-tegra3", WQ_UNBOUND | WQ_RESCUER | WQ_FREEZABLE, 1);
	if (!hotplug_wq)
		return -ENOMEM;
	INIT_DELAYED_WORK(&hotplug_work, tegra_auto_hotplug_work_func);

	cpu_clk = clk_get_sys(NULL, "cpu");
	cpu_g_clk = clk_get_sys(NULL, "cpu_g");
	cpu_lp_clk = clk_get_sys(NULL, "cpu_lp");
	if (IS_ERR(cpu_clk) || IS_ERR(cpu_g_clk) || IS_ERR(cpu_lp_clk))
		return -ENOENT;

	idle_top_freq = clk_get_max_rate(cpu_lp_clk) / 1000;
	idle_bottom_freq = clk_get_min_rate(cpu_g_clk) / 1000;

	up2g0_delay = msecs_to_jiffies(UP2G0_DELAY_MS);
	up2gn_delay = msecs_to_jiffies(UP2Gn_DELAY_MS);
	down_delay = msecs_to_jiffies(DOWN_DELAY_MS);

	tegra3_cpu_lock = cpu_lock;
	hp_state = INITIAL_STATE;
	hp_init_stats();
	pr_info("Tegra auto-hotplug initialized: %s\n",
		(hp_state == TEGRA_HP_DISABLED) ? "disabled" : "enabled");

	if (pm_qos_add_notifier(PM_QOS_MIN_ONLINE_CPUS, &min_cpus_notifier))
		pr_err("%s: Failed to register min cpus PM QoS notifier\n",
			__func__);

	rt_cfg_kobj = kobject_create_and_add("rt_config", kernel_kobj);
	if (!rt_cfg_kobj) {
		pr_err("cpu_tegra3: failed to create sysfs rt_cfg_kobj object");
		return 0;
	}
	if (sysfs_create_files(rt_cfg_kobj, rt_cfg_attributes)) {
		pr_err("tegra3_dvfs: failed to create sysfs rt_cfg_kobj interface");
		return 0;
	}
	return 0;
}
Пример #4
0
static int hp_state_set(const char *arg, const struct kernel_param *kp)
{
	int ret = 0;
	int old_state;

	if (!tegra3_cpu_lock)
		return ret;

	mutex_lock(tegra3_cpu_lock);

	old_state = hp_state;
	ret = param_set_bool(arg, kp);	/* set idle or disabled only */

	if (ret == 0) {
		if ((hp_state == TEGRA_HP_DISABLED) &&
		    (old_state != TEGRA_HP_DISABLED)) {
			mutex_unlock(tegra3_cpu_lock);
			cancel_delayed_work_sync(&hotplug_work);
			cancel_work_sync(&cpuplug_work);
			mutex_lock(tegra3_cpu_lock);
			if (is_plugging) {
				pr_info(CPU_HOTPLUG_TAG" is_plugging is true, set to false\n");
				is_plugging = false;
			}
			pr_info(CPU_HOTPLUG_TAG" Tegra auto hotplug disabled\n");
		} else if (hp_state != TEGRA_HP_DISABLED) {
			if (old_state == TEGRA_HP_DISABLED) {
				pr_info(CPU_HOTPLUG_TAG" Tegra auto-hotplug enabled\n");
				hp_init_stats();
			}
			active_start_time = ktime_get();
			/* catch-up with governor target speed */
			tegra_cpu_set_speed_cap(NULL);
		}
	} else
		pr_warn(CPU_HOTPLUG_TAG" %s: unable to set tegra hotplug state %s\n",
				__func__, arg);

	mutex_unlock(tegra3_cpu_lock);
	return ret;
}