18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  drivers/cpufreq/cpufreq_conservative.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C)  2001 Russell King
68c2ecf20Sopenharmony_ci *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
78c2ecf20Sopenharmony_ci *                      Jun Nakajima <jun.nakajima@intel.com>
88c2ecf20Sopenharmony_ci *            (C)  2009 Alexander Clouter <alex@digriz.org.uk>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/slab.h>
128c2ecf20Sopenharmony_ci#include "cpufreq_governor.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistruct cs_policy_dbs_info {
158c2ecf20Sopenharmony_ci	struct policy_dbs_info policy_dbs;
168c2ecf20Sopenharmony_ci	unsigned int down_skip;
178c2ecf20Sopenharmony_ci	unsigned int requested_freq;
188c2ecf20Sopenharmony_ci};
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	return container_of(policy_dbs, struct cs_policy_dbs_info, policy_dbs);
238c2ecf20Sopenharmony_ci}
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct cs_dbs_tuners {
268c2ecf20Sopenharmony_ci	unsigned int down_threshold;
278c2ecf20Sopenharmony_ci	unsigned int freq_step;
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/* Conservative governor macros */
318c2ecf20Sopenharmony_ci#define DEF_FREQUENCY_UP_THRESHOLD		(80)
328c2ecf20Sopenharmony_ci#define DEF_FREQUENCY_DOWN_THRESHOLD		(20)
338c2ecf20Sopenharmony_ci#define DEF_FREQUENCY_STEP			(5)
348c2ecf20Sopenharmony_ci#define DEF_SAMPLING_DOWN_FACTOR		(1)
358c2ecf20Sopenharmony_ci#define MAX_SAMPLING_DOWN_FACTOR		(10)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic inline unsigned int get_freq_step(struct cs_dbs_tuners *cs_tuners,
388c2ecf20Sopenharmony_ci					 struct cpufreq_policy *policy)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	unsigned int freq_step = (cs_tuners->freq_step * policy->max) / 100;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	/* max freq cannot be less than 100. But who knows... */
438c2ecf20Sopenharmony_ci	if (unlikely(freq_step == 0))
448c2ecf20Sopenharmony_ci		freq_step = DEF_FREQUENCY_STEP;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	return freq_step;
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/*
508c2ecf20Sopenharmony_ci * Every sampling_rate, we check, if current idle time is less than 20%
518c2ecf20Sopenharmony_ci * (default), then we try to increase frequency. Every sampling_rate *
528c2ecf20Sopenharmony_ci * sampling_down_factor, we check, if current idle time is more than 80%
538c2ecf20Sopenharmony_ci * (default), then we try to decrease frequency
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci * Frequency updates happen at minimum steps of 5% (default) of maximum
568c2ecf20Sopenharmony_ci * frequency
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_cistatic unsigned int cs_dbs_update(struct cpufreq_policy *policy)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct policy_dbs_info *policy_dbs = policy->governor_data;
618c2ecf20Sopenharmony_ci	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
628c2ecf20Sopenharmony_ci	unsigned int requested_freq = dbs_info->requested_freq;
638c2ecf20Sopenharmony_ci	struct dbs_data *dbs_data = policy_dbs->dbs_data;
648c2ecf20Sopenharmony_ci	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
658c2ecf20Sopenharmony_ci	unsigned int load = dbs_update(policy);
668c2ecf20Sopenharmony_ci	unsigned int freq_step;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	/*
698c2ecf20Sopenharmony_ci	 * break out if we 'cannot' reduce the speed as the user might
708c2ecf20Sopenharmony_ci	 * want freq_step to be zero
718c2ecf20Sopenharmony_ci	 */
728c2ecf20Sopenharmony_ci	if (cs_tuners->freq_step == 0)
738c2ecf20Sopenharmony_ci		goto out;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	/*
768c2ecf20Sopenharmony_ci	 * If requested_freq is out of range, it is likely that the limits
778c2ecf20Sopenharmony_ci	 * changed in the meantime, so fall back to current frequency in that
788c2ecf20Sopenharmony_ci	 * case.
798c2ecf20Sopenharmony_ci	 */
808c2ecf20Sopenharmony_ci	if (requested_freq > policy->max || requested_freq < policy->min) {
818c2ecf20Sopenharmony_ci		requested_freq = policy->cur;
828c2ecf20Sopenharmony_ci		dbs_info->requested_freq = requested_freq;
838c2ecf20Sopenharmony_ci	}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	freq_step = get_freq_step(cs_tuners, policy);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	/*
888c2ecf20Sopenharmony_ci	 * Decrease requested_freq one freq_step for each idle period that
898c2ecf20Sopenharmony_ci	 * we didn't update the frequency.
908c2ecf20Sopenharmony_ci	 */
918c2ecf20Sopenharmony_ci	if (policy_dbs->idle_periods < UINT_MAX) {
928c2ecf20Sopenharmony_ci		unsigned int freq_steps = policy_dbs->idle_periods * freq_step;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci		if (requested_freq > policy->min + freq_steps)
958c2ecf20Sopenharmony_ci			requested_freq -= freq_steps;
968c2ecf20Sopenharmony_ci		else
978c2ecf20Sopenharmony_ci			requested_freq = policy->min;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci		policy_dbs->idle_periods = UINT_MAX;
1008c2ecf20Sopenharmony_ci	}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	/* Check for frequency increase */
1038c2ecf20Sopenharmony_ci	if (load > dbs_data->up_threshold) {
1048c2ecf20Sopenharmony_ci		dbs_info->down_skip = 0;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci		/* if we are already at full speed then break out early */
1078c2ecf20Sopenharmony_ci		if (requested_freq == policy->max)
1088c2ecf20Sopenharmony_ci			goto out;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci		requested_freq += freq_step;
1118c2ecf20Sopenharmony_ci		if (requested_freq > policy->max)
1128c2ecf20Sopenharmony_ci			requested_freq = policy->max;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci		__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H);
1158c2ecf20Sopenharmony_ci		dbs_info->requested_freq = requested_freq;
1168c2ecf20Sopenharmony_ci		goto out;
1178c2ecf20Sopenharmony_ci	}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	/* if sampling_down_factor is active break out early */
1208c2ecf20Sopenharmony_ci	if (++dbs_info->down_skip < dbs_data->sampling_down_factor)
1218c2ecf20Sopenharmony_ci		goto out;
1228c2ecf20Sopenharmony_ci	dbs_info->down_skip = 0;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	/* Check for frequency decrease */
1258c2ecf20Sopenharmony_ci	if (load < cs_tuners->down_threshold) {
1268c2ecf20Sopenharmony_ci		/*
1278c2ecf20Sopenharmony_ci		 * if we cannot reduce the frequency anymore, break out early
1288c2ecf20Sopenharmony_ci		 */
1298c2ecf20Sopenharmony_ci		if (requested_freq == policy->min)
1308c2ecf20Sopenharmony_ci			goto out;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci		if (requested_freq > freq_step)
1338c2ecf20Sopenharmony_ci			requested_freq -= freq_step;
1348c2ecf20Sopenharmony_ci		else
1358c2ecf20Sopenharmony_ci			requested_freq = policy->min;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci		__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L);
1388c2ecf20Sopenharmony_ci		dbs_info->requested_freq = requested_freq;
1398c2ecf20Sopenharmony_ci	}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci out:
1428c2ecf20Sopenharmony_ci	return dbs_data->sampling_rate;
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci/************************** sysfs interface ************************/
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistatic ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
1488c2ecf20Sopenharmony_ci					  const char *buf, size_t count)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	struct dbs_data *dbs_data = to_dbs_data(attr_set);
1518c2ecf20Sopenharmony_ci	unsigned int input;
1528c2ecf20Sopenharmony_ci	int ret;
1538c2ecf20Sopenharmony_ci	ret = sscanf(buf, "%u", &input);
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
1568c2ecf20Sopenharmony_ci		return -EINVAL;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	dbs_data->sampling_down_factor = input;
1598c2ecf20Sopenharmony_ci	return count;
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic ssize_t store_up_threshold(struct gov_attr_set *attr_set,
1638c2ecf20Sopenharmony_ci				  const char *buf, size_t count)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	struct dbs_data *dbs_data = to_dbs_data(attr_set);
1668c2ecf20Sopenharmony_ci	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
1678c2ecf20Sopenharmony_ci	unsigned int input;
1688c2ecf20Sopenharmony_ci	int ret;
1698c2ecf20Sopenharmony_ci	ret = sscanf(buf, "%u", &input);
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	if (ret != 1 || input > 100 || input <= cs_tuners->down_threshold)
1728c2ecf20Sopenharmony_ci		return -EINVAL;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	dbs_data->up_threshold = input;
1758c2ecf20Sopenharmony_ci	return count;
1768c2ecf20Sopenharmony_ci}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_cistatic ssize_t store_down_threshold(struct gov_attr_set *attr_set,
1798c2ecf20Sopenharmony_ci				    const char *buf, size_t count)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	struct dbs_data *dbs_data = to_dbs_data(attr_set);
1828c2ecf20Sopenharmony_ci	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
1838c2ecf20Sopenharmony_ci	unsigned int input;
1848c2ecf20Sopenharmony_ci	int ret;
1858c2ecf20Sopenharmony_ci	ret = sscanf(buf, "%u", &input);
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	/* cannot be lower than 1 otherwise freq will not fall */
1888c2ecf20Sopenharmony_ci	if (ret != 1 || input < 1 || input > 100 ||
1898c2ecf20Sopenharmony_ci			input >= dbs_data->up_threshold)
1908c2ecf20Sopenharmony_ci		return -EINVAL;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	cs_tuners->down_threshold = input;
1938c2ecf20Sopenharmony_ci	return count;
1948c2ecf20Sopenharmony_ci}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_cistatic ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
1978c2ecf20Sopenharmony_ci				      const char *buf, size_t count)
1988c2ecf20Sopenharmony_ci{
1998c2ecf20Sopenharmony_ci	struct dbs_data *dbs_data = to_dbs_data(attr_set);
2008c2ecf20Sopenharmony_ci	unsigned int input;
2018c2ecf20Sopenharmony_ci	int ret;
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	ret = sscanf(buf, "%u", &input);
2048c2ecf20Sopenharmony_ci	if (ret != 1)
2058c2ecf20Sopenharmony_ci		return -EINVAL;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	if (input > 1)
2088c2ecf20Sopenharmony_ci		input = 1;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	if (input == dbs_data->ignore_nice_load) /* nothing to do */
2118c2ecf20Sopenharmony_ci		return count;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	dbs_data->ignore_nice_load = input;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	/* we need to re-evaluate prev_cpu_idle */
2168c2ecf20Sopenharmony_ci	gov_update_cpu_data(dbs_data);
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	return count;
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_cistatic ssize_t store_freq_step(struct gov_attr_set *attr_set, const char *buf,
2228c2ecf20Sopenharmony_ci			       size_t count)
2238c2ecf20Sopenharmony_ci{
2248c2ecf20Sopenharmony_ci	struct dbs_data *dbs_data = to_dbs_data(attr_set);
2258c2ecf20Sopenharmony_ci	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
2268c2ecf20Sopenharmony_ci	unsigned int input;
2278c2ecf20Sopenharmony_ci	int ret;
2288c2ecf20Sopenharmony_ci	ret = sscanf(buf, "%u", &input);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	if (ret != 1)
2318c2ecf20Sopenharmony_ci		return -EINVAL;
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	if (input > 100)
2348c2ecf20Sopenharmony_ci		input = 100;
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	/*
2378c2ecf20Sopenharmony_ci	 * no need to test here if freq_step is zero as the user might actually
2388c2ecf20Sopenharmony_ci	 * want this, they would be crazy though :)
2398c2ecf20Sopenharmony_ci	 */
2408c2ecf20Sopenharmony_ci	cs_tuners->freq_step = input;
2418c2ecf20Sopenharmony_ci	return count;
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_cigov_show_one_common(sampling_rate);
2458c2ecf20Sopenharmony_cigov_show_one_common(sampling_down_factor);
2468c2ecf20Sopenharmony_cigov_show_one_common(up_threshold);
2478c2ecf20Sopenharmony_cigov_show_one_common(ignore_nice_load);
2488c2ecf20Sopenharmony_cigov_show_one(cs, down_threshold);
2498c2ecf20Sopenharmony_cigov_show_one(cs, freq_step);
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_cigov_attr_rw(sampling_rate);
2528c2ecf20Sopenharmony_cigov_attr_rw(sampling_down_factor);
2538c2ecf20Sopenharmony_cigov_attr_rw(up_threshold);
2548c2ecf20Sopenharmony_cigov_attr_rw(ignore_nice_load);
2558c2ecf20Sopenharmony_cigov_attr_rw(down_threshold);
2568c2ecf20Sopenharmony_cigov_attr_rw(freq_step);
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_cistatic struct attribute *cs_attributes[] = {
2598c2ecf20Sopenharmony_ci	&sampling_rate.attr,
2608c2ecf20Sopenharmony_ci	&sampling_down_factor.attr,
2618c2ecf20Sopenharmony_ci	&up_threshold.attr,
2628c2ecf20Sopenharmony_ci	&down_threshold.attr,
2638c2ecf20Sopenharmony_ci	&ignore_nice_load.attr,
2648c2ecf20Sopenharmony_ci	&freq_step.attr,
2658c2ecf20Sopenharmony_ci	NULL
2668c2ecf20Sopenharmony_ci};
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci/************************** sysfs end ************************/
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_cistatic struct policy_dbs_info *cs_alloc(void)
2718c2ecf20Sopenharmony_ci{
2728c2ecf20Sopenharmony_ci	struct cs_policy_dbs_info *dbs_info;
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	dbs_info = kzalloc(sizeof(*dbs_info), GFP_KERNEL);
2758c2ecf20Sopenharmony_ci	return dbs_info ? &dbs_info->policy_dbs : NULL;
2768c2ecf20Sopenharmony_ci}
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_cistatic void cs_free(struct policy_dbs_info *policy_dbs)
2798c2ecf20Sopenharmony_ci{
2808c2ecf20Sopenharmony_ci	kfree(to_dbs_info(policy_dbs));
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic int cs_init(struct dbs_data *dbs_data)
2848c2ecf20Sopenharmony_ci{
2858c2ecf20Sopenharmony_ci	struct cs_dbs_tuners *tuners;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
2888c2ecf20Sopenharmony_ci	if (!tuners)
2898c2ecf20Sopenharmony_ci		return -ENOMEM;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD;
2928c2ecf20Sopenharmony_ci	tuners->freq_step = DEF_FREQUENCY_STEP;
2938c2ecf20Sopenharmony_ci	dbs_data->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
2948c2ecf20Sopenharmony_ci	dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
2958c2ecf20Sopenharmony_ci	dbs_data->ignore_nice_load = 0;
2968c2ecf20Sopenharmony_ci	dbs_data->tuners = tuners;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	return 0;
2998c2ecf20Sopenharmony_ci}
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_cistatic void cs_exit(struct dbs_data *dbs_data)
3028c2ecf20Sopenharmony_ci{
3038c2ecf20Sopenharmony_ci	kfree(dbs_data->tuners);
3048c2ecf20Sopenharmony_ci}
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_cistatic void cs_start(struct cpufreq_policy *policy)
3078c2ecf20Sopenharmony_ci{
3088c2ecf20Sopenharmony_ci	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	dbs_info->down_skip = 0;
3118c2ecf20Sopenharmony_ci	dbs_info->requested_freq = policy->cur;
3128c2ecf20Sopenharmony_ci}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_cistatic struct dbs_governor cs_governor = {
3158c2ecf20Sopenharmony_ci	.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"),
3168c2ecf20Sopenharmony_ci	.kobj_type = { .default_attrs = cs_attributes },
3178c2ecf20Sopenharmony_ci	.gov_dbs_update = cs_dbs_update,
3188c2ecf20Sopenharmony_ci	.alloc = cs_alloc,
3198c2ecf20Sopenharmony_ci	.free = cs_free,
3208c2ecf20Sopenharmony_ci	.init = cs_init,
3218c2ecf20Sopenharmony_ci	.exit = cs_exit,
3228c2ecf20Sopenharmony_ci	.start = cs_start,
3238c2ecf20Sopenharmony_ci};
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci#define CPU_FREQ_GOV_CONSERVATIVE	(cs_governor.gov)
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ciMODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
3288c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for "
3298c2ecf20Sopenharmony_ci		"Low Latency Frequency Transition capable processors "
3308c2ecf20Sopenharmony_ci		"optimised for use in a battery environment");
3318c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
3348c2ecf20Sopenharmony_cistruct cpufreq_governor *cpufreq_default_governor(void)
3358c2ecf20Sopenharmony_ci{
3368c2ecf20Sopenharmony_ci	return &CPU_FREQ_GOV_CONSERVATIVE;
3378c2ecf20Sopenharmony_ci}
3388c2ecf20Sopenharmony_ci#endif
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_cicpufreq_governor_init(CPU_FREQ_GOV_CONSERVATIVE);
3418c2ecf20Sopenharmony_cicpufreq_governor_exit(CPU_FREQ_GOV_CONSERVATIVE);
342