mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 16:44:10 +08:00
cpufreq: Allow drivers to enable boost support after registering driver
In some cases it wouldn't be known at time of driver registration, if the driver needs to support boost frequencies. For example, while getting boost information from DT with opp-v2 bindings, we need to parse the bindings for all the CPUs to know if turbo/boost OPPs are supported or not. One way out to do that efficiently is to delay supporting boost mode (i.e. creating /sys/devices/system/cpu/cpufreq/boost file), until the time OPP bindings are parsed. At that point, the driver can enable boost support. This can be done at ->init(), where the frequency table is created. To do that, the driver requires few APIs from cpufreq core that let him do this. This patch provides these APIs. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
79eea44a5d
commit
44139ed494
@ -2437,6 +2437,49 @@ int cpufreq_boost_supported(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cpufreq_boost_supported);
|
EXPORT_SYMBOL_GPL(cpufreq_boost_supported);
|
||||||
|
|
||||||
|
static int create_boost_sysfs_file(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!cpufreq_boost_supported())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if driver provides function to enable boost -
|
||||||
|
* if not, use cpufreq_boost_set_sw as default
|
||||||
|
*/
|
||||||
|
if (!cpufreq_driver->set_boost)
|
||||||
|
cpufreq_driver->set_boost = cpufreq_boost_set_sw;
|
||||||
|
|
||||||
|
ret = cpufreq_sysfs_create_file(&boost.attr);
|
||||||
|
if (ret)
|
||||||
|
pr_err("%s: cannot register global BOOST sysfs file\n",
|
||||||
|
__func__);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_boost_sysfs_file(void)
|
||||||
|
{
|
||||||
|
if (cpufreq_boost_supported())
|
||||||
|
cpufreq_sysfs_remove_file(&boost.attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpufreq_enable_boost_support(void)
|
||||||
|
{
|
||||||
|
if (!cpufreq_driver)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (cpufreq_boost_supported())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cpufreq_driver->boost_supported = true;
|
||||||
|
|
||||||
|
/* This will get removed on driver unregister */
|
||||||
|
return create_boost_sysfs_file();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(cpufreq_enable_boost_support);
|
||||||
|
|
||||||
int cpufreq_boost_enabled(void)
|
int cpufreq_boost_enabled(void)
|
||||||
{
|
{
|
||||||
return cpufreq_driver->boost_enabled;
|
return cpufreq_driver->boost_enabled;
|
||||||
@ -2490,21 +2533,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
|
|||||||
if (driver_data->setpolicy)
|
if (driver_data->setpolicy)
|
||||||
driver_data->flags |= CPUFREQ_CONST_LOOPS;
|
driver_data->flags |= CPUFREQ_CONST_LOOPS;
|
||||||
|
|
||||||
if (cpufreq_boost_supported()) {
|
ret = create_boost_sysfs_file();
|
||||||
/*
|
if (ret)
|
||||||
* Check if driver provides function to enable boost -
|
goto err_null_driver;
|
||||||
* if not, use cpufreq_boost_set_sw as default
|
|
||||||
*/
|
|
||||||
if (!cpufreq_driver->set_boost)
|
|
||||||
cpufreq_driver->set_boost = cpufreq_boost_set_sw;
|
|
||||||
|
|
||||||
ret = cpufreq_sysfs_create_file(&boost.attr);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("%s: cannot register global BOOST sysfs file\n",
|
|
||||||
__func__);
|
|
||||||
goto err_null_driver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = subsys_interface_register(&cpufreq_interface);
|
ret = subsys_interface_register(&cpufreq_interface);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -2528,8 +2559,7 @@ out:
|
|||||||
err_if_unreg:
|
err_if_unreg:
|
||||||
subsys_interface_unregister(&cpufreq_interface);
|
subsys_interface_unregister(&cpufreq_interface);
|
||||||
err_boost_unreg:
|
err_boost_unreg:
|
||||||
if (cpufreq_boost_supported())
|
remove_boost_sysfs_file();
|
||||||
cpufreq_sysfs_remove_file(&boost.attr);
|
|
||||||
err_null_driver:
|
err_null_driver:
|
||||||
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
||||||
cpufreq_driver = NULL;
|
cpufreq_driver = NULL;
|
||||||
@ -2558,9 +2588,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
|
|||||||
/* Protect against concurrent cpu hotplug */
|
/* Protect against concurrent cpu hotplug */
|
||||||
get_online_cpus();
|
get_online_cpus();
|
||||||
subsys_interface_unregister(&cpufreq_interface);
|
subsys_interface_unregister(&cpufreq_interface);
|
||||||
if (cpufreq_boost_supported())
|
remove_boost_sysfs_file();
|
||||||
cpufreq_sysfs_remove_file(&boost.attr);
|
|
||||||
|
|
||||||
unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
|
unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
|
||||||
|
|
||||||
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
||||||
|
@ -18,6 +18,21 @@
|
|||||||
* FREQUENCY TABLE HELPERS *
|
* FREQUENCY TABLE HELPERS *
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
|
bool policy_has_boost_freq(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
struct cpufreq_frequency_table *pos, *table = policy->freq_table;
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cpufreq_for_each_valid_entry(pos, table)
|
||||||
|
if (pos->flags & CPUFREQ_BOOST_FREQ)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(policy_has_boost_freq);
|
||||||
|
|
||||||
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
|
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
|
||||||
struct cpufreq_frequency_table *table)
|
struct cpufreq_frequency_table *table)
|
||||||
{
|
{
|
||||||
|
@ -578,6 +578,8 @@ ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf);
|
|||||||
int cpufreq_boost_trigger_state(int state);
|
int cpufreq_boost_trigger_state(int state);
|
||||||
int cpufreq_boost_supported(void);
|
int cpufreq_boost_supported(void);
|
||||||
int cpufreq_boost_enabled(void);
|
int cpufreq_boost_enabled(void);
|
||||||
|
int cpufreq_enable_boost_support(void);
|
||||||
|
bool policy_has_boost_freq(struct cpufreq_policy *policy);
|
||||||
#else
|
#else
|
||||||
static inline int cpufreq_boost_trigger_state(int state)
|
static inline int cpufreq_boost_trigger_state(int state)
|
||||||
{
|
{
|
||||||
@ -591,6 +593,16 @@ static inline int cpufreq_boost_enabled(void)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int cpufreq_enable_boost_support(void)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool policy_has_boost_freq(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/* the following funtion is for cpufreq core use only */
|
/* the following funtion is for cpufreq core use only */
|
||||||
struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
|
struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
|
||||||
|
Loading…
Reference in New Issue
Block a user