forked from luck/tmp_suning_uos_patched
cpufreq: imx6q/thermal: imx: register cooling device depending on OF
The cooling device should be part of the i.MX cpufreq driver, but it cannot be removed for the sake of DT stability. So turn the cooling device registration into a separate function and perform the registration only if the CPU OF node does not have the #cooling-cells property. Use of_cpufreq_power_cooling_register in imx_thermal code to link the cooling device to the device tree node provided. This makes it possible to bind the cpufreq cooling device to a custom thermal zone via a cooling-maps entry like: cooling-maps { map0 { trip = <&board_alert>; cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; Assuming a cpu node exists with label "cpu0" and #cooling-cells property. Signed-off-by: Bastian Stender <bst@pengutronix.de> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
1111b7836c
commit
a1d0015423
|
@ -9,6 +9,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -50,6 +51,7 @@ static struct clk_bulk_data clks[] = {
|
|||
};
|
||||
|
||||
static struct device *cpu_dev;
|
||||
static struct thermal_cooling_device *cdev;
|
||||
static bool free_opp;
|
||||
static struct cpufreq_frequency_table *freq_table;
|
||||
static unsigned int max_freq;
|
||||
|
@ -191,6 +193,16 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void imx6q_cpufreq_ready(struct cpufreq_policy *policy)
|
||||
{
|
||||
cdev = of_cpufreq_cooling_register(policy);
|
||||
|
||||
if (!cdev)
|
||||
dev_err(cpu_dev,
|
||||
"running cpufreq without cooling device: %ld\n",
|
||||
PTR_ERR(cdev));
|
||||
}
|
||||
|
||||
static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int ret;
|
||||
|
@ -202,13 +214,22 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int imx6q_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
cpufreq_cooling_unregister(cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver imx6q_cpufreq_driver = {
|
||||
.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
|
||||
.verify = cpufreq_generic_frequency_table_verify,
|
||||
.target_index = imx6q_set_target,
|
||||
.get = cpufreq_generic_get,
|
||||
.init = imx6q_cpufreq_init,
|
||||
.exit = imx6q_cpufreq_exit,
|
||||
.name = "imx6q-cpufreq",
|
||||
.ready = imx6q_cpufreq_ready,
|
||||
.attr = cpufreq_generic_attr,
|
||||
.suspend = cpufreq_generic_suspend,
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// Copyright 2013 Freescale Semiconductor, Inc.
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -644,6 +645,27 @@ static const struct of_device_id of_imx_thermal_match[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
|
||||
|
||||
/*
|
||||
* Create cooling device in case no #cooling-cells property is available in
|
||||
* CPU node
|
||||
*/
|
||||
static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
|
||||
{
|
||||
struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL);
|
||||
int ret;
|
||||
|
||||
if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
|
||||
data->cdev = cpufreq_cooling_register(data->policy);
|
||||
if (IS_ERR(data->cdev)) {
|
||||
ret = PTR_ERR(data->cdev);
|
||||
cpufreq_cpu_put(data->policy);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_thermal_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_thermal_data *data;
|
||||
|
@ -724,12 +746,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
|
|||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
data->cdev = cpufreq_cooling_register(data->policy);
|
||||
if (IS_ERR(data->cdev)) {
|
||||
ret = PTR_ERR(data->cdev);
|
||||
ret = imx_thermal_register_legacy_cooling(data);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to register cpufreq cooling device: %d\n", ret);
|
||||
cpufreq_cpu_put(data->policy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user