提交 4617c220 编写于 作者: L Linus Torvalds

Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal management fixes from Eduardo Valentin:
 "Specifics in this pull request:

   - Compilation fixes on SPEAR, and U8500 thermal drivers.
   - RCAR thermal driver now recognizes OF-thermal based thermal zones.
   - Small code rework on OF-thermal.
   - These change have been CI tested using KernelCI bot [1,2].  \o/

  I am taking over on Rui's behalf while he is out.  Happy New Chinese
  Year!

  [1] - https://kernelci.org/build/evalenti/kernel/v4.5-rc3-16-ga53b8394ec3c/
  [2] - https://kernelci.org/boot/all/job/evalenti/kernel/v4.5-rc3-16-ga53b8394ec3c/"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal:
  thermal: cpu_cooling: fix out of bounds access in time_in_idle
  thermal: allow u8500-thermal driver to be a module
  thermal: allow spear-thermal driver to be a module
  thermal: spear: use __maybe_unused for PM functions
  thermal: rcar: enable to use thermal-zone on DT
  thermal: of: use for_each_available_child_of_node for child iterator
上级 b4e4334d a53b8394
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
* Renesas R-Car Thermal
Required properties:
- compatible : "renesas,thermal-<soctype>", "renesas,rcar-thermal"
as fallback.
- compatible : "renesas,thermal-<soctype>",
"renesas,rcar-gen2-thermal" (with thermal-zone) or
"renesas,rcar-thermal" (without thermal-zone) as fallback.
Examples with soctypes are:
- "renesas,thermal-r8a73a4" (R-Mobile APE6)
- "renesas,thermal-r8a7779" (R-Car H1)
......@@ -36,3 +37,35 @@ thermal@e61f0000 {
0xe61f0300 0x38>;
interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
};
Example (with thermal-zone):
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&thermal>;
trips {
cpu-crit {
temperature = <115000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
};
};
};
thermal: thermal@e61f0000 {
compatible = "renesas,thermal-r8a7790",
"renesas,rcar-gen2-thermal",
"renesas,rcar-thermal";
reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
power-domains = <&cpg_clocks>;
#thermal-sensor-cells = <0>;
};
......@@ -2048,6 +2048,7 @@ int db8500_prcmu_config_hotmon(u8 low, u8 high)
return 0;
}
EXPORT_SYMBOL_GPL(db8500_prcmu_config_hotmon);
static int config_hot_period(u16 val)
{
......@@ -2074,11 +2075,13 @@ int db8500_prcmu_start_temp_sense(u16 cycles32k)
return config_hot_period(cycles32k);
}
EXPORT_SYMBOL_GPL(db8500_prcmu_start_temp_sense);
int db8500_prcmu_stop_temp_sense(void)
{
return config_hot_period(0xFFFF);
}
EXPORT_SYMBOL_GPL(db8500_prcmu_stop_temp_sense);
static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)
{
......
......@@ -195,7 +195,7 @@ config IMX_THERMAL
passive trip is crossed.
config SPEAR_THERMAL
bool "SPEAr thermal sensor driver"
tristate "SPEAr thermal sensor driver"
depends on PLAT_SPEAR || COMPILE_TEST
depends on OF
help
......@@ -237,8 +237,8 @@ config DOVE_THERMAL
framework.
config DB8500_THERMAL
bool "DB8500 thermal management"
depends on ARCH_U8500
tristate "DB8500 thermal management"
depends on MFD_DB8500_PRCMU
default y
help
Adds DB8500 thermal management implementation according to the thermal
......
......@@ -377,26 +377,28 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_device,
* get_load() - get load for a cpu since last updated
* @cpufreq_device: &struct cpufreq_cooling_device for this cpu
* @cpu: cpu number
* @cpu_idx: index of the cpu in cpufreq_device->allowed_cpus
*
* Return: The average load of cpu @cpu in percentage since this
* function was last called.
*/
static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu)
static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu,
int cpu_idx)
{
u32 load;
u64 now, now_idle, delta_time, delta_idle;
now_idle = get_cpu_idle_time(cpu, &now, 0);
delta_idle = now_idle - cpufreq_device->time_in_idle[cpu];
delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu];
delta_idle = now_idle - cpufreq_device->time_in_idle[cpu_idx];
delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu_idx];
if (delta_time <= delta_idle)
load = 0;
else
load = div64_u64(100 * (delta_time - delta_idle), delta_time);
cpufreq_device->time_in_idle[cpu] = now_idle;
cpufreq_device->time_in_idle_timestamp[cpu] = now;
cpufreq_device->time_in_idle[cpu_idx] = now_idle;
cpufreq_device->time_in_idle_timestamp[cpu_idx] = now;
return load;
}
......@@ -598,7 +600,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
u32 load;
if (cpu_online(cpu))
load = get_load(cpufreq_device, cpu);
load = get_load(cpufreq_device, cpu, i);
else
load = 0;
......
......@@ -475,14 +475,10 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
sensor_np = of_node_get(dev->of_node);
for_each_child_of_node(np, child) {
for_each_available_child_of_node(np, child) {
struct of_phandle_args sensor_specs;
int ret, id;
/* Check whether child is enabled or not */
if (!of_device_is_available(child))
continue;
/* For now, thermal framework supports only 1 sensor per zone */
ret = of_parse_phandle_with_args(child, "thermal-sensors",
"#thermal-sensor-cells",
......@@ -881,16 +877,12 @@ int __init of_parse_thermal_zones(void)
return 0; /* Run successfully on systems without thermal DT */
}
for_each_child_of_node(np, child) {
for_each_available_child_of_node(np, child) {
struct thermal_zone_device *zone;
struct thermal_zone_params *tzp;
int i, mask = 0;
u32 prop;
/* Check whether child is enabled or not */
if (!of_device_is_available(child))
continue;
tz = thermal_of_build_thermal_zone(child);
if (IS_ERR(tz)) {
pr_err("failed to build thermal zone %s: %ld\n",
......@@ -968,13 +960,9 @@ void of_thermal_destroy_zones(void)
return;
}
for_each_child_of_node(np, child) {
for_each_available_child_of_node(np, child) {
struct thermal_zone_device *zone;
/* Check whether child is enabled or not */
if (!of_device_is_available(child))
continue;
zone = thermal_zone_get_zone_by_name(child->name);
if (IS_ERR(zone))
continue;
......
......@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reboot.h>
......@@ -75,8 +76,10 @@ struct rcar_thermal_priv {
#define rcar_has_irq_support(priv) ((priv)->common->base)
#define rcar_id_to_shift(priv) ((priv)->id * 8)
#define USE_OF_THERMAL 1
static const struct of_device_id rcar_thermal_dt_ids[] = {
{ .compatible = "renesas,rcar-thermal", },
{ .compatible = "renesas,rcar-gen2-thermal", .data = (void *)USE_OF_THERMAL },
{},
};
MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
......@@ -200,9 +203,9 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
return ret;
}
static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
int *temp)
{
struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
int tmp;
int ret;
......@@ -226,6 +229,20 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
return 0;
}
static int rcar_thermal_of_get_temp(void *data, int *temp)
{
struct rcar_thermal_priv *priv = data;
return rcar_thermal_get_current_temp(priv, temp);
}
static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
{
struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
return rcar_thermal_get_current_temp(priv, temp);
}
static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone,
int trip, enum thermal_trip_type *type)
{
......@@ -282,6 +299,10 @@ static int rcar_thermal_notify(struct thermal_zone_device *zone,
return 0;
}
static const struct thermal_zone_of_device_ops rcar_thermal_zone_of_ops = {
.get_temp = rcar_thermal_of_get_temp,
};
static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
.get_temp = rcar_thermal_get_temp,
.get_trip_type = rcar_thermal_get_trip_type,
......@@ -318,14 +339,20 @@ static void rcar_thermal_work(struct work_struct *work)
priv = container_of(work, struct rcar_thermal_priv, work.work);
rcar_thermal_get_temp(priv->zone, &cctemp);
ret = rcar_thermal_get_current_temp(priv, &cctemp);
if (ret < 0)
return;
ret = rcar_thermal_update_temp(priv);
if (ret < 0)
return;
rcar_thermal_irq_enable(priv);
rcar_thermal_get_temp(priv->zone, &nctemp);
ret = rcar_thermal_get_current_temp(priv, &nctemp);
if (ret < 0)
return;
if (nctemp != cctemp)
thermal_zone_device_update(priv->zone);
}
......@@ -403,6 +430,8 @@ static int rcar_thermal_probe(struct platform_device *pdev)
struct rcar_thermal_priv *priv;
struct device *dev = &pdev->dev;
struct resource *res, *irq;
const struct of_device_id *of_id = of_match_device(rcar_thermal_dt_ids, dev);
unsigned long of_data = (unsigned long)of_id->data;
int mres = 0;
int i;
int ret = -ENODEV;
......@@ -463,7 +492,13 @@ static int rcar_thermal_probe(struct platform_device *pdev)
if (ret < 0)
goto error_unregister;
priv->zone = thermal_zone_device_register("rcar_thermal",
if (of_data == USE_OF_THERMAL)
priv->zone = thermal_zone_of_sensor_register(
dev, i, priv,
&rcar_thermal_zone_of_ops);
else
priv->zone = thermal_zone_device_register(
"rcar_thermal",
1, 0, priv,
&rcar_thermal_zone_ops, NULL, 0,
idle);
......
......@@ -54,8 +54,7 @@ static struct thermal_zone_device_ops ops = {
.get_temp = thermal_get_temp,
};
#ifdef CONFIG_PM
static int spear_thermal_suspend(struct device *dev)
static int __maybe_unused spear_thermal_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev);
......@@ -72,7 +71,7 @@ static int spear_thermal_suspend(struct device *dev)
return 0;
}
static int spear_thermal_resume(struct device *dev)
static int __maybe_unused spear_thermal_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev);
......@@ -94,7 +93,6 @@ static int spear_thermal_resume(struct device *dev)
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(spear_thermal_pm_ops, spear_thermal_suspend,
spear_thermal_resume);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部