Hi,
[devm]_thermal_zone_of_sensor_register() is used to register
thermal sensor by thermal drivers using DeviceTree. Besides
registering sensor this function also immediately enables it
(using ->set_mode method) and then checks it with a update call
to the thermal core (which ends up using ->get_temp method).
For many DT thermal drivers this causes a problem because
[devm]_thermal_zone_of_sensor_register() need to be called in
order to obtain data about thermal trips which are then used to
finish hardware sensor setup (only after which ->get_temp can
be used). The issue has been observed when using Samsung Exynos
thermal driver and fixed internally in the driver in commit
d8efad71e5b6 ("thermal: exynos: Reading temperature makes sense
only when TMU is turned on"). However after this commit there
are now following warnings from the thermal core visible:
[ 3.453602] thermal thermal_zone0: failed to read out thermal zone (-22)
[ 3.483468] thermal thermal_zone1: failed to read out thermal zone (-22)
[ 3.505965] thermal thermal_zone2: failed to read out thermal zone (-22)
[ 3.528455] thermal thermal_zone3: failed to read out thermal zone (-22)
[ 3.550939] thermal thermal_zone4: failed to read out thermal zone (-22)
This patchset attempts to directly address the thermal core
problem with [devm]_thermal_zone_of_sensor_register() and
affected DT thermal drivers. In order to achieve this sensor
registration, enable and check operations are separated and
corresponding drivers are modified to use the new helpers to
enable and check sensor explicitly.
Tested on Exynos5422 based Odroid-XU3 Lite board (aforementioned
warnings from the thermal core are now gone).
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
Bartlomiej Zolnierkiewicz (17):
thermal: add thermal_zone_device_toggle() helper
thermal: separate sensor registration and enable
thermal: add thermal_zone_device_check() helper
thermal: do sensor checking explicitly in drivers
thermal: bcm2835: enable/check sensor after its setup is finished
thermal: brcmstb: enable/check sensor after its setup is finished
thermal: hisi_thermal: enable/check sensor after its setup is finished
thermal: qcom: tsens: enable/check sensor after its setup is finished
thermal: qoriq: enable/check sensor after its setup is finished
thermal: rcar_gen3_thermal: enable/check sensor after its setup is
finished
thermal: rockchip_thermal: enable/check sensor after its setup is
finished
thermal: exynos: enable/check sensor after its setup is finished
thermal: tegra: enable/check sensor after its setup is finished
thermal: ti-soc-thermal: enable/check sensor after its setup is
finished
thermal: uniphier: enable/check sensor after its setup is
finished
thermal: zx2967: enable/check sensor after its setup is finished
thermal: warn on attempts to read temperature on disabled sensors
drivers/acpi/thermal.c | 5 ++--
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
drivers/platform/x86/acerhdf.c | 6 +++-
drivers/regulator/max8973-regulator.c | 3 +-
drivers/thermal/broadcom/bcm2835_thermal.c | 3 ++
drivers/thermal/broadcom/brcmstb_thermal.c | 3 ++
drivers/thermal/broadcom/ns-thermal.c | 3 ++
drivers/thermal/da9062-thermal.c | 7 ++---
drivers/thermal/db8500_thermal.c | 5 +++-
drivers/thermal/hisi_thermal.c | 22 ++++----------
drivers/thermal/imx_thermal.c | 3 +-
drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
drivers/thermal/intel_bxt_pmic_thermal.c | 3 +-
drivers/thermal/intel_soc_dts_iosf.c | 3 +-
drivers/thermal/max77620_thermal.c | 6 ++--
drivers/thermal/mtk_thermal.c | 3 ++
drivers/thermal/of-thermal.c | 6 ++--
drivers/thermal/qcom-spmi-temp-alarm.c | 5 +++-
drivers/thermal/qcom/tsens.c | 6 ++++
drivers/thermal/qoriq_thermal.c | 3 ++
drivers/thermal/rcar_gen3_thermal.c | 7 +++--
drivers/thermal/rcar_thermal.c | 8 +++--
drivers/thermal/rockchip_thermal.c | 34 ++++++++++------------
drivers/thermal/samsung/exynos_tmu.c | 7 ++++-
drivers/thermal/st/st_thermal_memmap.c | 3 +-
drivers/thermal/tango_thermal.c | 5 ++++
drivers/thermal/tegra/soctherm.c | 3 ++
drivers/thermal/tegra/tegra-bpmp-thermal.c | 3 ++
drivers/thermal/thermal-generic-adc.c | 3 ++
drivers/thermal/thermal_core.c | 14 ++++-----
drivers/thermal/thermal_helpers.c | 33 +++++++++++++++++++++
drivers/thermal/thermal_sysfs.c | 17 +++++++----
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 7 ++++-
drivers/thermal/uniphier_thermal.c | 6 +++-
drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
drivers/thermal/zx2967_thermal.c | 3 ++
include/linux/thermal.h | 5 ++++
37 files changed, 173 insertions(+), 84 deletions(-)
--
1.9.1
Move thermal_zone_device_toggle() call to the users of
[devm]_thermal_zone_of_sensor_register().
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/broadcom/bcm2835_thermal.c | 2 ++
drivers/thermal/broadcom/brcmstb_thermal.c | 2 ++
drivers/thermal/broadcom/ns-thermal.c | 2 ++
drivers/thermal/hisi_thermal.c | 2 ++
drivers/thermal/max77620_thermal.c | 2 ++
drivers/thermal/mtk_thermal.c | 2 ++
drivers/thermal/of-thermal.c | 3 ---
drivers/thermal/qcom-spmi-temp-alarm.c | 2 ++
drivers/thermal/qcom/tsens.c | 5 +++++
drivers/thermal/qoriq_thermal.c | 2 ++
drivers/thermal/rcar_gen3_thermal.c | 3 +++
drivers/thermal/rcar_thermal.c | 3 +++
drivers/thermal/rockchip_thermal.c | 2 ++
drivers/thermal/samsung/exynos_tmu.c | 2 ++
drivers/thermal/tango_thermal.c | 3 +++
drivers/thermal/tegra/soctherm.c | 2 ++
drivers/thermal/tegra/tegra-bpmp-thermal.c | 2 ++
drivers/thermal/thermal-generic-adc.c | 2 ++
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 ++
drivers/thermal/uniphier_thermal.c | 2 ++
drivers/thermal/zx2967_thermal.c | 2 ++
21 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
index a4d6a0e..f5e913c 100644
--- a/drivers/thermal/broadcom/bcm2835_thermal.c
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
@@ -227,6 +227,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
goto err_clk;
}
+ thermal_zone_device_toggle(tz, true);
+
/*
* right now the FW does set up the HW-block, so we are not
* touching the configuration registers.
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
index 1919f91..075c9b7 100644
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -336,6 +336,8 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_device_toggle(thermal, true);
+
priv->thermal = thermal;
irq = platform_get_irq(pdev, 0);
diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c
index 322e741..aa151dd 100644
--- a/drivers/thermal/broadcom/ns-thermal.c
+++ b/drivers/thermal/broadcom/ns-thermal.c
@@ -71,6 +71,8 @@ static int ns_thermal_probe(struct platform_device *pdev)
return PTR_ERR(ns_thermal->tz);
}
+ thermal_zone_device_toggle(ns_thermal->tz, true);
+
platform_set_drvdata(pdev, ns_thermal);
return 0;
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 9428499..d7237d1 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -490,6 +490,8 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
return ret;
}
+ thermal_zone_device_toggle(sensor->tzd, true);
+
trip = of_thermal_get_trip_points(sensor->tzd);
for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) {
diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c
index 159bbce..337d695 100644
--- a/drivers/thermal/max77620_thermal.c
+++ b/drivers/thermal/max77620_thermal.c
@@ -126,6 +126,8 @@ static int max77620_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_device_toggle(mtherm->tz_device, true);
+
ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm1, NULL,
max77620_thermal_irq,
IRQF_ONESHOT | IRQF_SHARED,
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index e709acb..806df57 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -769,6 +769,8 @@ static int mtk_thermal_probe(struct platform_device *pdev)
goto err_disable_clk_peri_therm;
}
+ thermal_zone_device_toggle(tzdev, true);
+
return 0;
err_disable_clk_peri_therm:
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index f138b78..890e272 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -509,9 +509,6 @@ struct thermal_zone_device *
if (sensor_specs.np == sensor_np && id == sensor_id) {
tzd = thermal_zone_of_add_sensor(child, sensor_np,
data, ops);
- if (!IS_ERR(tzd))
- thermal_zone_device_toggle(tzd, true);
-
of_node_put(sensor_specs.np);
of_node_put(child);
goto exit;
diff --git a/drivers/thermal/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom-spmi-temp-alarm.c
index 95f987d..cb46555 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -270,6 +270,8 @@ static int qpnp_tm_probe(struct platform_device *pdev)
return PTR_ERR(chip->tz_dev);
}
+ thermal_zone_device_toggle(chip->tz_dev, true);
+
return 0;
}
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 3f9fe6a..3405dea 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -95,12 +95,17 @@ static int tsens_register(struct tsens_device *tmdev)
for (i = 0; i < tmdev->num_sensors; i++) {
tmdev->sensor[i].tmdev = tmdev;
tmdev->sensor[i].id = i;
+
tzd = devm_thermal_zone_of_sensor_register(tmdev->dev, i,
&tmdev->sensor[i],
&tsens_of_ops);
if (IS_ERR(tzd))
continue;
+
+ thermal_zone_device_toggle(tzd, true);
+
tmdev->sensor[i].tzd = tzd;
+
if (tmdev->ops->enable)
tmdev->ops->enable(tmdev, i);
}
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index c866cc1..1ce2d93 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -242,6 +242,8 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
goto err_tmu;
}
+ thermal_zone_device_toggle(data->tz, true);
+
/* Enable monitoring */
site |= 0x1 << (15 - data->sensor_id);
tmu_write(data, site | TMR_ME | TMR_ALPF, &data->regs->tmr);
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 561a0a3..5d26aab 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -429,6 +429,9 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(zone);
goto error_unregister;
}
+
+ thermal_zone_device_toggle(zone, true);
+
tsc->zone = zone;
ret = of_thermal_get_ntrips(tsc->zone);
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 73e5fee..5c2a42d 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -515,6 +515,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
goto error_unregister;
}
+ if (rcar_use_of_thermal(dev))
+ thermal_zone_device_toggle(priv->zone, true);
+
if (rcar_use_of_thermal(dev)) {
/*
* thermal_zone doesn't enable hwmon as default,
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index c191e41..c41bb6c 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1162,6 +1162,8 @@ static int rockchip_configure_from_dt(struct device *dev,
return error;
}
+ thermal_zone_device_toggle(sensor->tzd, true);
+
return 0;
}
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 2ec8548..cbe5471 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1403,6 +1403,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto err_sclk;
}
+ thermal_zone_device_toggle(data->tzd, true);
+
ret = exynos_tmu_initialize(pdev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize TMU\n");
diff --git a/drivers/thermal/tango_thermal.c b/drivers/thermal/tango_thermal.c
index 4e67795..6bbd766 100644
--- a/drivers/thermal/tango_thermal.c
+++ b/drivers/thermal/tango_thermal.c
@@ -90,6 +90,9 @@ static int tango_thermal_probe(struct platform_device *pdev)
tango_thermal_init(priv);
tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &ops);
+ if (!IS_ERR(tzdev))
+ thermal_zone_device_toggle(tzdev, true);
+
return PTR_ERR_OR_ZERO(tzdev);
}
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 455b58c..0236e18 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -1400,6 +1400,8 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
goto disable_clocks;
}
+ thermal_zone_device_toggle(z, true);
+
zone->tz = z;
tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
diff --git a/drivers/thermal/tegra/tegra-bpmp-thermal.c b/drivers/thermal/tegra/tegra-bpmp-thermal.c
index b0980db..aa40f70 100644
--- a/drivers/thermal/tegra/tegra-bpmp-thermal.c
+++ b/drivers/thermal/tegra/tegra-bpmp-thermal.c
@@ -213,6 +213,8 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
continue;
}
+ thermal_zone_device_toggle(tzd, true);
+
zone->tzd = tzd;
INIT_WORK(&zone->tz_device_update_work,
tz_device_update_work_fn);
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index 46d3005..f74eebc 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -142,6 +142,8 @@ static int gadc_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_device_toggle(gti->tz_dev, true);
+
return 0;
}
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index b4f981d..621add3 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -197,6 +197,8 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
return PTR_ERR(data->ti_thermal);
}
+ thermal_zone_device_toggle(data->ti_thermal, true);
+
ti_bandgap_set_sensor_data(bgp, id, data);
ti_bandgap_write_update_interval(bgp, data->sensor_id,
data->ti_thermal->polling_delay);
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index 9570473..f83bb3e 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -307,6 +307,8 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return PTR_ERR(tdev->tz_dev);
}
+ thermal_zone_device_toggle(tdev->tz_dev, true);
+
/* get trip points */
trips = of_thermal_get_trip_points(tdev->tz_dev);
ntrips = of_thermal_get_ntrips(tdev->tz_dev);
diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
index 6acce0b..ff406a4 100644
--- a/drivers/thermal/zx2967_thermal.c
+++ b/drivers/thermal/zx2967_thermal.c
@@ -168,6 +168,8 @@ static int zx2967_thermal_probe(struct platform_device *pdev)
goto disable_clk_all;
}
+ thermal_zone_device_toggle(priv->tzd, true);
+
if (priv->tzd->tzp->slope == 0) {
thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
dev_err(&pdev->dev, "coefficients of sensor is invalid\n");
--
1.9.1
* Add set_mode_skip_check flag to struct thermal_zone_device_ops and
set it in drivers that don't check the thermal zone device in their
->set_mode method implementations.
* Move thermal_zone_device_check() from ->set_mode implementations to
the users of thermal_zone_device_toggle() (only place which calls
->set_mode). Modify mode_store() in thermal_sysfs.c accordingly.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/acpi/thermal.c | 2 ++
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 2 --
drivers/platform/x86/acerhdf.c | 2 ++
drivers/thermal/broadcom/bcm2835_thermal.c | 1 +
drivers/thermal/broadcom/brcmstb_thermal.c | 1 +
drivers/thermal/broadcom/ns-thermal.c | 1 +
drivers/thermal/db8500_thermal.c | 2 ++
drivers/thermal/hisi_thermal.c | 3 +++
drivers/thermal/imx_thermal.c | 2 --
drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
drivers/thermal/max77620_thermal.c | 1 +
drivers/thermal/mtk_thermal.c | 1 +
drivers/thermal/of-thermal.c | 2 --
drivers/thermal/qcom-spmi-temp-alarm.c | 1 +
drivers/thermal/qcom/tsens.c | 1 +
drivers/thermal/qoriq_thermal.c | 1 +
drivers/thermal/rcar_gen3_thermal.c | 1 +
drivers/thermal/rcar_thermal.c | 4 +++-
drivers/thermal/rockchip_thermal.c | 17 +++++++++++++----
drivers/thermal/samsung/exynos_tmu.c | 1 +
drivers/thermal/tango_thermal.c | 4 +++-
drivers/thermal/tegra/soctherm.c | 1 +
drivers/thermal/tegra/tegra-bpmp-thermal.c | 1 +
drivers/thermal/thermal-generic-adc.c | 1 +
drivers/thermal/thermal_sysfs.c | 3 +++
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 1 +
drivers/thermal/uniphier_thermal.c | 1 +
drivers/thermal/zx2967_thermal.c | 1 +
include/linux/thermal.h | 2 ++
29 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index b8b275e1..a7e3d9e 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -879,6 +879,8 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
.get_crit_temp = thermal_get_crit_temp,
.get_trend = thermal_get_trend,
.notify = thermal_notify,
+
+ .set_mode_skip_check = true,
};
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 7513359..6b388b0 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -198,8 +198,6 @@ static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
thermal->mode = mode;
- thermal_zone_device_check(tzdev);
-
return 0;
}
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 19b9bc9..a4dfd2e 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -495,6 +495,8 @@ static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal,
.get_trip_hyst = acerhdf_get_trip_hyst,
.get_trip_temp = acerhdf_get_trip_temp,
.get_crit_temp = acerhdf_get_crit_temp,
+
+ .set_mode_skip_check = true,
};
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
index f5e913c..1270e3f 100644
--- a/drivers/thermal/broadcom/bcm2835_thermal.c
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
@@ -228,6 +228,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(tz, true);
+ thermal_zone_device_check(tz);
/*
* right now the FW does set up the HW-block, so we are not
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
index 075c9b7..fead74f 100644
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -337,6 +337,7 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(thermal, true);
+ thermal_zone_device_check(thermal);
priv->thermal = thermal;
diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c
index aa151dd..728b4dc 100644
--- a/drivers/thermal/broadcom/ns-thermal.c
+++ b/drivers/thermal/broadcom/ns-thermal.c
@@ -72,6 +72,7 @@ static int ns_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(ns_thermal->tz, true);
+ thermal_zone_device_check(ns_thermal->tz);
platform_set_drvdata(pdev, ns_thermal);
diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c
index ab66b2d7..c4d0fb1 100644
--- a/drivers/thermal/db8500_thermal.c
+++ b/drivers/thermal/db8500_thermal.c
@@ -220,6 +220,8 @@ static int db8500_sys_get_crit_temp(struct thermal_zone_device *thermal,
.get_trip_type = db8500_sys_get_trip_type,
.get_trip_temp = db8500_sys_get_trip_temp,
.get_crit_temp = db8500_sys_get_crit_temp,
+
+ .set_mode_skip_check = true,
};
static void db8500_thermal_update_config(struct db8500_thermal_zone *pzone,
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 8cfe3d2..1936eb4 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -489,6 +489,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
}
thermal_zone_device_toggle(sensor->tzd, true);
+ thermal_zone_device_check(sensor->tzd);
trip = of_thermal_get_trip_points(sensor->tzd);
@@ -563,6 +564,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle((&data->sensor)->tzd, true);
+ thermal_zone_device_check((&data->sensor)->tzd);
return 0;
}
@@ -572,6 +574,7 @@ static int hisi_thermal_remove(struct platform_device *pdev)
struct hisi_thermal_data *data = platform_get_drvdata(pdev);
thermal_zone_device_toggle((&data->sensor)->tzd, false);
+ thermal_zone_device_check((&data->sensor)->tzd);
data->disable_sensor(data);
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 2cd1921..6bbc70b 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -389,8 +389,6 @@ static int imx_set_mode(struct thermal_zone_device *tz,
data->mode = mode;
- thermal_zone_device_check(tz);
-
return 0;
}
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c
index e26b01c..d1f0641 100644
--- a/drivers/thermal/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3400_thermal.c
@@ -305,6 +305,7 @@ static int int3400_thermal_probe(struct platform_device *pdev)
if (priv->uuid_bitmap & 1 << INT3400_THERMAL_PASSIVE_1) {
int3400_thermal_ops.get_mode = int3400_thermal_get_mode;
int3400_thermal_ops.set_mode = int3400_thermal_set_mode;
+ int3400_thermal_ops.set_mode_skip_check = true;
}
priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0,
priv, &int3400_thermal_ops,
diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c
index f896a97..ee4ccd9 100644
--- a/drivers/thermal/max77620_thermal.c
+++ b/drivers/thermal/max77620_thermal.c
@@ -126,6 +126,7 @@ static int max77620_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(mtherm->tz_device, true);
+ thermal_zone_device_check(mtherm->tz_device);
ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm1, NULL,
max77620_thermal_irq,
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 806df57..9743ca2 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -770,6 +770,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(tzdev, true);
+ thermal_zone_device_check(tzdev);
return 0;
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index a65b515..f60ccf1 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -286,8 +286,6 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
data->mode = mode;
- thermal_zone_device_check(tz);
-
return 0;
}
diff --git a/drivers/thermal/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom-spmi-temp-alarm.c
index fa42517..7af3458 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -271,6 +271,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(chip->tz_dev, true);
+ thermal_zone_device_check(chip->tz_dev);
return 0;
}
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 3405dea..0d119c1 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -103,6 +103,7 @@ static int tsens_register(struct tsens_device *tmdev)
continue;
thermal_zone_device_toggle(tzd, true);
+ thermal_zone_device_check(tzd);
tmdev->sensor[i].tzd = tzd;
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 1ce2d93..cdd6f59 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -243,6 +243,7 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(data->tz, true);
+ thermal_zone_device_check(data->tz);
/* Enable monitoring */
site |= 0x1 << (15 - data->sensor_id);
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 69142c2..87061b1 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -430,6 +430,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(zone, true);
+ thermal_zone_device_check(zone);
tsc->zone = zone;
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 080e6ec..5c2df6a 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -514,8 +514,10 @@ static int rcar_thermal_probe(struct platform_device *pdev)
goto error_unregister;
}
- if (rcar_use_of_thermal(dev))
+ if (rcar_use_of_thermal(dev)) {
thermal_zone_device_toggle(priv->zone, true);
+ thermal_zone_device_check(priv->zone);
+ }
if (rcar_use_of_thermal(dev)) {
/*
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index d0e4042..500cfc3 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1162,6 +1162,7 @@ static int rockchip_configure_from_dt(struct device *dev,
}
thermal_zone_device_toggle(sensor->tzd, true);
+ thermal_zone_device_check(sensor->tzd);
return 0;
}
@@ -1283,8 +1284,10 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
thermal->chip->control(thermal->regs, true);
- for (i = 0; i < thermal->chip->chn_num; i++)
+ for (i = 0; i < thermal->chip->chn_num; i++) {
thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }
platform_set_drvdata(pdev, thermal);
@@ -1303,8 +1306,10 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < thermal->chip->chn_num; i++)
+ for (i = 0; i < thermal->chip->chn_num; i++) {
thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }
thermal->chip->control(thermal->regs, false);
@@ -1320,8 +1325,10 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < thermal->chip->chn_num; i++)
+ for (i = 0; i < thermal->chip->chn_num; i++) {
thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }
thermal->chip->control(thermal->regs, false);
@@ -1371,8 +1378,10 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
thermal->chip->control(thermal->regs, true);
- for (i = 0; i < thermal->chip->chn_num; i++)
+ for (i = 0; i < thermal->chip->chn_num; i++) {
thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }
pinctrl_pm_select_default_state(dev);
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 5b07a8f..af1902d 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1404,6 +1404,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(data->tzd, true);
+ thermal_zone_device_check(data->tzd);
ret = exynos_tmu_initialize(pdev);
if (ret) {
diff --git a/drivers/thermal/tango_thermal.c b/drivers/thermal/tango_thermal.c
index 6bbd766..0d2f14e 100644
--- a/drivers/thermal/tango_thermal.c
+++ b/drivers/thermal/tango_thermal.c
@@ -90,8 +90,10 @@ static int tango_thermal_probe(struct platform_device *pdev)
tango_thermal_init(priv);
tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &ops);
- if (!IS_ERR(tzdev))
+ if (!IS_ERR(tzdev)) {
thermal_zone_device_toggle(tzdev, true);
+ thermal_zone_device_check(tzdev);
+ }
return PTR_ERR_OR_ZERO(tzdev);
}
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 0236e18..9554613 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -1401,6 +1401,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(z, true);
+ thermal_zone_device_check(z);
zone->tz = z;
tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
diff --git a/drivers/thermal/tegra/tegra-bpmp-thermal.c b/drivers/thermal/tegra/tegra-bpmp-thermal.c
index aa40f70..1d89a14 100644
--- a/drivers/thermal/tegra/tegra-bpmp-thermal.c
+++ b/drivers/thermal/tegra/tegra-bpmp-thermal.c
@@ -214,6 +214,7 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(tzd, true);
+ thermal_zone_device_check(tzd);
zone->tzd = tzd;
INIT_WORK(&zone->tz_device_update_work,
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index f74eebc..6f45dab 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -143,6 +143,7 @@ static int gadc_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(gti->tz_dev, true);
+ thermal_zone_device_check(gti->tz_dev);
return 0;
}
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 109be2f..d6da2c2 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -88,6 +88,9 @@
if (result)
return result;
+ if (!tz->ops->set_mode_skip_check)
+ thermal_zone_device_check(tz);
+
return count;
}
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index d1b55d9..3c2299b 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -198,6 +198,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
}
thermal_zone_device_toggle(data->ti_thermal, true);
+ thermal_zone_device_check(data->ti_thermal);
ti_bandgap_set_sensor_data(bgp, id, data);
ti_bandgap_write_update_interval(bgp, data->sensor_id,
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index f2f8b2b..8070747 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -308,6 +308,7 @@ static int uniphier_tm_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(tdev->tz_dev, true);
+ thermal_zone_device_check(tdev->tz_dev);
/* get trip points */
trips = of_thermal_get_trip_points(tdev->tz_dev);
diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
index ff406a4..ffd2b07 100644
--- a/drivers/thermal/zx2967_thermal.c
+++ b/drivers/thermal/zx2967_thermal.c
@@ -169,6 +169,7 @@ static int zx2967_thermal_probe(struct platform_device *pdev)
}
thermal_zone_device_toggle(priv->tzd, true);
+ thermal_zone_device_check(priv->tzd);
if (priv->tzd->tzp->slope == 0) {
thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 4ef79c8..7de102f 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -128,6 +128,8 @@ struct thermal_zone_device_ops {
enum thermal_trend *);
int (*notify) (struct thermal_zone_device *, int,
enum thermal_trip_type);
+
+ bool set_mode_skip_check;
};
struct thermal_cooling_device_ops {
--
1.9.1
Enable/check sensor after setting tmdev->sensor[i].tzd and calling
chipset specific enable operation.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/qcom/tsens.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 0d119c1..da44494 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -102,13 +102,13 @@ static int tsens_register(struct tsens_device *tmdev)
if (IS_ERR(tzd))
continue;
- thermal_zone_device_toggle(tzd, true);
- thermal_zone_device_check(tzd);
-
tmdev->sensor[i].tzd = tzd;
if (tmdev->ops->enable)
tmdev->ops->enable(tmdev, i);
+
+ thermal_zone_device_toggle(tzd, true);
+ thermal_zone_device_check(tzd);
}
return 0;
}
--
1.9.1
Enable/check sensor after enabling monitoring.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/qoriq_thermal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index cdd6f59..2695021 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -242,13 +242,13 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
goto err_tmu;
}
- thermal_zone_device_toggle(data->tz, true);
- thermal_zone_device_check(data->tz);
-
/* Enable monitoring */
site |= 0x1 << (15 - data->sensor_id);
tmu_write(data, site | TMR_ME | TMR_ALPF, &data->regs->tmr);
+ thermal_zone_device_toggle(data->tz, true);
+ thermal_zone_device_check(data->tz);
+
return 0;
err_tmu:
--
1.9.1
* Enable/check sensor after checking ntrips and doing chipset specific
enable operation.
* Remove superfluous second sensor enable/check attempt.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/hisi_thermal.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 1936eb4..d4c5055 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -488,9 +488,6 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
return ret;
}
- thermal_zone_device_toggle(sensor->tzd, true);
- thermal_zone_device_check(sensor->tzd);
-
trip = of_thermal_get_trip_points(sensor->tzd);
for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) {
@@ -553,6 +550,9 @@ static int hisi_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_device_toggle((&data->sensor)->tzd, true);
+ thermal_zone_device_check((&data->sensor)->tzd);
+
if (data->irq) {
ret = devm_request_threaded_irq(dev, data->irq, NULL,
hisi_thermal_alarm_irq_thread,
@@ -563,9 +563,6 @@ static int hisi_thermal_probe(struct platform_device *pdev)
}
}
- thermal_zone_device_toggle((&data->sensor)->tzd, true);
- thermal_zone_device_check((&data->sensor)->tzd);
-
return 0;
}
--
1.9.1
Enable/check sensor after setting tsc->zone and checking ntrips.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/rcar_gen3_thermal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 87061b1..98d418b 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -429,9 +429,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
goto error_unregister;
}
- thermal_zone_device_toggle(zone, true);
- thermal_zone_device_check(zone);
-
tsc->zone = zone;
ret = of_thermal_get_ntrips(tsc->zone);
@@ -439,6 +436,9 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
goto error_unregister;
dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret);
+
+ thermal_zone_device_toggle(zone, true);
+ thermal_zone_device_check(zone);
}
priv->num_tscs = i;
--
1.9.1
Enable/check sensor after setting zone->tz and programming hwtrips.
Cc: Thierry Reding <[email protected]>
Cc: Jonathan Hunter <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/tegra/soctherm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 9554613..81784b8 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -1400,9 +1400,6 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
goto disable_clocks;
}
- thermal_zone_device_toggle(z, true);
- thermal_zone_device_check(z);
-
zone->tz = z;
tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
@@ -1410,6 +1407,9 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
if (err)
goto disable_clocks;
+
+ thermal_zone_device_toggle(z, true);
+ thermal_zone_device_check(z);
}
soctherm_debug_init(pdev);
--
1.9.1
* Enable/check sensor explicitly in rockchip_thermal_probe() (also
check sensor after doing chipset specific control operation).
* Remove superfluous second sensor enable/check attempt.
Cc: Heiko Stuebner <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
This driver may require some more fixing (probably IRQ should be
requested after ->control call).
drivers/thermal/rockchip_thermal.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 500cfc3..0b3509b 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1161,9 +1161,6 @@ static int rockchip_configure_from_dt(struct device *dev,
return error;
}
- thermal_zone_device_toggle(sensor->tzd, true);
- thermal_zone_device_check(sensor->tzd);
-
return 0;
}
@@ -1272,6 +1269,9 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
}
}
+ for (i = 0; i < thermal->chip->chn_num; i++)
+ thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
+
error = devm_request_threaded_irq(&pdev->dev, irq, NULL,
&rockchip_thermal_alarm_irq_thread,
IRQF_ONESHOT,
@@ -1284,10 +1284,8 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
thermal->chip->control(thermal->regs, true);
- for (i = 0; i < thermal->chip->chn_num; i++) {
- thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
+ for (i = 0; i < thermal->chip->chn_num; i++)
thermal_zone_device_check((&thermal->sensors[i])->tzd);
- }
platform_set_drvdata(pdev, thermal);
--
1.9.1
Enable sensor after checking trip points (unipher_tm_enable_sensor()
enables IRQ so we need to toggle sensor before calling it) and check
sensor after doing chipset specific enable sensor operation.
Cc: Masahiro Yamada <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/uniphier_thermal.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index 8070747..cdecccd 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -307,9 +307,6 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return PTR_ERR(tdev->tz_dev);
}
- thermal_zone_device_toggle(tdev->tz_dev, true);
- thermal_zone_device_check(tdev->tz_dev);
-
/* get trip points */
trips = of_thermal_get_trip_points(tdev->tz_dev);
ntrips = of_thermal_get_ntrips(tdev->tz_dev);
@@ -332,8 +329,12 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return -EINVAL;
}
+ thermal_zone_device_toggle(tdev->tz_dev, true);
+
uniphier_tm_enable_sensor(tdev);
+ thermal_zone_device_check(tdev->tz_dev);
+
return 0;
}
--
1.9.1
Enable/check sensor after checking sensor coefficients.
Cc: Jun Nie <[email protected]>
Cc: Baoyou Xie <[email protected]>
Cc: Shawn Guo <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/zx2967_thermal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
index ffd2b07..45ed17f 100644
--- a/drivers/thermal/zx2967_thermal.c
+++ b/drivers/thermal/zx2967_thermal.c
@@ -168,9 +168,6 @@ static int zx2967_thermal_probe(struct platform_device *pdev)
goto disable_clk_all;
}
- thermal_zone_device_toggle(priv->tzd, true);
- thermal_zone_device_check(priv->tzd);
-
if (priv->tzd->tzp->slope == 0) {
thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
dev_err(&pdev->dev, "coefficients of sensor is invalid\n");
@@ -178,6 +175,9 @@ static int zx2967_thermal_probe(struct platform_device *pdev)
goto disable_clk_all;
}
+ thermal_zone_device_toggle(priv->tzd, true);
+ thermal_zone_device_check(priv->tzd);
+
priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);
--
1.9.1
* Add ops_of_thermal flag to struct thermal_zone_device_ops and
set it in of-thermal.c.
* Add checking sensor mode for drivers using of-thermal.c to
thermal_zone_get_temp() (print a warning if sensor is disabled).
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/of-thermal.c | 2 ++
drivers/thermal/thermal_helpers.c | 12 ++++++++++++
include/linux/thermal.h | 1 +
3 files changed, 15 insertions(+)
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index f60ccf1..68ebcda 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -392,6 +392,8 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
.bind = of_thermal_bind,
.unbind = of_thermal_unbind,
+
+ .ops_of_thermal = true,
};
/*** sensor API ***/
diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index bd10b4d..e3fc1c6 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -87,6 +87,18 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
if (!tz || IS_ERR(tz) || !tz->ops->get_temp)
goto exit;
+ if (tz->ops->ops_of_thermal) {
+ enum thermal_device_mode mode;
+
+ ret = tz->ops->get_mode(tz, &mode);
+ if (ret)
+ goto exit;
+
+ if (mode == THERMAL_DEVICE_DISABLED)
+ dev_warn_once(&tz->device,
+ "trying to read out disabled thermal zone\n");
+ }
+
mutex_lock(&tz->lock);
ret = tz->ops->get_temp(tz, temp);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 7de102f..31560b4 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -130,6 +130,7 @@ struct thermal_zone_device_ops {
enum thermal_trip_type);
bool set_mode_skip_check;
+ bool ops_of_thermal;
};
struct thermal_cooling_device_ops {
--
1.9.1
Add thermal_zone_device_toggle() helper. Then update core code and
drivers to use it.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/hisi_thermal.c | 14 ++------------
drivers/thermal/of-thermal.c | 2 +-
drivers/thermal/rockchip_thermal.c | 22 +++++-----------------
drivers/thermal/thermal_helpers.c | 15 +++++++++++++++
drivers/thermal/thermal_sysfs.c | 8 +++++---
include/linux/thermal.h | 1 +
6 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 761d055..9428499 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -515,15 +515,6 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
};
MODULE_DEVICE_TABLE(of, of_hisi_thermal_match);
-static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
- bool on)
-{
- struct thermal_zone_device *tzd = sensor->tzd;
-
- tzd->ops->set_mode(tzd,
- on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
-}
-
static int hisi_thermal_probe(struct platform_device *pdev)
{
struct hisi_thermal_data *data;
@@ -571,7 +562,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
}
}
- hisi_thermal_toggle_sensor(&data->sensor, true);
+ thermal_zone_device_toggle((&data->sensor)->tzd, true);
return 0;
}
@@ -579,9 +570,8 @@ static int hisi_thermal_probe(struct platform_device *pdev)
static int hisi_thermal_remove(struct platform_device *pdev)
{
struct hisi_thermal_data *data = platform_get_drvdata(pdev);
- struct hisi_thermal_sensor *sensor = &data->sensor;
- hisi_thermal_toggle_sensor(sensor, false);
+ thermal_zone_device_toggle((&data->sensor)->tzd, false);
data->disable_sensor(data);
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index e09f035..f138b78 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -510,7 +510,7 @@ struct thermal_zone_device *
tzd = thermal_zone_of_add_sensor(child, sensor_np,
data, ops);
if (!IS_ERR(tzd))
- tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_toggle(tzd, true);
of_node_put(sensor_specs.np);
of_node_put(child);
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index f36375d..c191e41 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1022,15 +1022,6 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
};
MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
-static void
-rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on)
-{
- struct thermal_zone_device *tzd = sensor->tzd;
-
- tzd->ops->set_mode(tzd,
- on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
-}
-
static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
{
struct rockchip_thermal_data *thermal = dev;
@@ -1292,7 +1283,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
thermal->chip->control(thermal->regs, true);
for (i = 0; i < thermal->chip->chn_num; i++)
- rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
+ thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
platform_set_drvdata(pdev, thermal);
@@ -1311,11 +1302,8 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < thermal->chip->chn_num; i++) {
- struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
-
- rockchip_thermal_toggle_sensor(sensor, false);
- }
+ for (i = 0; i < thermal->chip->chn_num; i++)
+ thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
thermal->chip->control(thermal->regs, false);
@@ -1332,7 +1320,7 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
int i;
for (i = 0; i < thermal->chip->chn_num; i++)
- rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
+ thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
thermal->chip->control(thermal->regs, false);
@@ -1383,7 +1371,7 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
thermal->chip->control(thermal->regs, true);
for (i = 0; i < thermal->chip->chn_num; i++)
- rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
+ thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
pinctrl_pm_select_default_state(dev);
diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index eb03d7e..d5db101 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -227,3 +227,18 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz)
return 0;
}
EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
+
+/**
+ * thermal_zone_device_toggle() - enables/disables thermal zone device
+ * @tz: a valid pointer to a struct thermal_zone_device
+ *
+ * Enables/Disables thermal zone device.
+ *
+ * Return: On success returns 0, an error code otherwise.
+ */
+int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on)
+{
+ return tz->ops->set_mode(tz,
+ on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
+}
+EXPORT_SYMBOL_GPL(thermal_zone_device_toggle);
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 23b5e0a..343f52b 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -72,17 +72,19 @@
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
int result;
+ bool on;
if (!tz->ops->set_mode)
return -EPERM;
if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
- result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+ on = true;
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
- result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+ on = false;
else
- result = -EINVAL;
+ return -EINVAL;
+ result = thermal_zone_device_toggle(tz, on);
if (result)
return result;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 7834be6..4fbbabe 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -467,6 +467,7 @@ struct thermal_cooling_device *
int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
int thermal_zone_get_slope(struct thermal_zone_device *tz);
int thermal_zone_get_offset(struct thermal_zone_device *tz);
+int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on);
int get_tz_trend(struct thermal_zone_device *, int);
struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
--
1.9.1
Enable sensor after doing chipset specific initialization operation and
check sensor after doing chipset specific control operation.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/samsung/exynos_tmu.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index af1902d..68457f5 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1403,15 +1403,14 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto err_sclk;
}
- thermal_zone_device_toggle(data->tzd, true);
- thermal_zone_device_check(data->tzd);
-
ret = exynos_tmu_initialize(pdev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize TMU\n");
goto err_thermal;
}
+ thermal_zone_device_toggle(data->tzd, true);
+
ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
if (ret) {
@@ -1420,6 +1419,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
}
exynos_tmu_control(pdev, true);
+
+ thermal_zone_device_check(data->tzd);
+
return 0;
err_thermal:
--
1.9.1
* Rename static thermal_zone_device_check() helper in thermal_core.c
to thermal_zone_device_work_check().
* Add thermal_zone_device_check() helper. Then update core code and
drivers to use it.
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/acpi/thermal.c | 3 +--
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 3 ++-
drivers/platform/x86/acerhdf.c | 4 +++-
drivers/regulator/max8973-regulator.c | 3 +--
drivers/thermal/da9062-thermal.c | 7 ++-----
drivers/thermal/db8500_thermal.c | 3 ++-
drivers/thermal/hisi_thermal.c | 4 +---
drivers/thermal/imx_thermal.c | 5 +++--
drivers/thermal/intel_bxt_pmic_thermal.c | 3 +--
drivers/thermal/intel_soc_dts_iosf.c | 3 +--
drivers/thermal/max77620_thermal.c | 3 +--
drivers/thermal/of-thermal.c | 3 ++-
drivers/thermal/qcom-spmi-temp-alarm.c | 2 +-
drivers/thermal/rcar_gen3_thermal.c | 3 +--
drivers/thermal/rcar_thermal.c | 3 +--
drivers/thermal/rockchip_thermal.c | 3 +--
drivers/thermal/samsung/exynos_tmu.c | 2 +-
drivers/thermal/st/st_thermal_memmap.c | 3 +--
drivers/thermal/thermal_core.c | 14 ++++++--------
drivers/thermal/thermal_helpers.c | 6 ++++++
drivers/thermal/thermal_sysfs.c | 6 +++---
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
drivers/thermal/uniphier_thermal.c | 2 +-
drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
include/linux/thermal.h | 1 +
25 files changed, 45 insertions(+), 48 deletions(-)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 551b71a..b8b275e1 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -520,8 +520,7 @@ static void acpi_thermal_check(void *data)
if (!tz->tz_enabled)
return;
- thermal_zone_device_update(tz->thermal_zone,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz->thermal_zone);
}
/* sys I/F for generic thermal sysfs support */
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index d866c98..7513359 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -197,7 +197,8 @@ static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
mutex_unlock(&tzdev->lock);
thermal->mode = mode;
- thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
+
+ thermal_zone_device_check(tzdev);
return 0;
}
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index ea22591..19b9bc9 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -405,7 +405,9 @@ static inline void acerhdf_enable_kernelmode(void)
kernelmode = 1;
thz_dev->polling_delay = interval*1000;
- thermal_zone_device_update(thz_dev, THERMAL_EVENT_UNSPECIFIED);
+
+ thermal_zone_device_check(thz_dev);
+
pr_notice("kernel mode fan control ON\n");
}
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index e0c747a..1f15a6d 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -495,8 +495,7 @@ static irqreturn_t max8973_thermal_irq(int irq, void *data)
{
struct max8973_chip *mchip = data;
- thermal_zone_device_update(mchip->tz_device,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(mchip->tz_device);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c
index dd8dd94..8c6721b 100644
--- a/drivers/thermal/da9062-thermal.c
+++ b/drivers/thermal/da9062-thermal.c
@@ -102,9 +102,7 @@ static void da9062_thermal_poll_on(struct work_struct *work)
mutex_lock(&thermal->lock);
thermal->temperature = DA9062_MILLI_CELSIUS(125);
mutex_unlock(&thermal->lock);
- thermal_zone_device_update(thermal->zone,
- THERMAL_EVENT_UNSPECIFIED);
-
+ thermal_zone_device_check(thermal->zone);
delay = msecs_to_jiffies(thermal->zone->passive_delay);
schedule_delayed_work(&thermal->work, delay);
return;
@@ -113,8 +111,7 @@ static void da9062_thermal_poll_on(struct work_struct *work)
mutex_lock(&thermal->lock);
thermal->temperature = DA9062_MILLI_CELSIUS(0);
mutex_unlock(&thermal->lock);
- thermal_zone_device_update(thermal->zone,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(thermal->zone);
err_enable_irq:
enable_irq(thermal->irq);
diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c
index f491faf..ab66b2d7 100644
--- a/drivers/thermal/db8500_thermal.c
+++ b/drivers/thermal/db8500_thermal.c
@@ -306,7 +306,8 @@ static void db8500_thermal_work(struct work_struct *work)
if (cur_mode == THERMAL_DEVICE_DISABLED)
return;
- thermal_zone_device_update(pzone->therm_dev, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(pzone->therm_dev);
+
dev_dbg(&pzone->therm_dev->device, "thermal work finished.\n");
}
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index d7237d1..8cfe3d2 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -461,9 +461,7 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n",
temp, sensor->thres_temp);
- thermal_zone_device_update(data->sensor.tzd,
- THERMAL_EVENT_UNSPECIFIED);
-
+ thermal_zone_device_check(data->sensor.tzd);
} else {
dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n",
temp, sensor->thres_temp);
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index c30dc21..2cd1921 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -388,7 +388,8 @@ static int imx_set_mode(struct thermal_zone_device *tz,
}
data->mode = mode;
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+
+ thermal_zone_device_check(tz);
return 0;
}
@@ -636,7 +637,7 @@ static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n",
data->alarm_temp / 1000);
- thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(data->tz);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c b/drivers/thermal/intel_bxt_pmic_thermal.c
index 94cfd00..73fe97b 100644
--- a/drivers/thermal/intel_bxt_pmic_thermal.c
+++ b/drivers/thermal/intel_bxt_pmic_thermal.c
@@ -203,8 +203,7 @@ static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
tzd = thermal_zone_get_zone_by_name(td->maps[i].handle);
if (!IS_ERR(tzd))
- thermal_zone_device_update(tzd,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tzd);
/* Clear the appropriate irq */
regmap_write(regmap, reg, reg_val & mask);
diff --git a/drivers/thermal/intel_soc_dts_iosf.c b/drivers/thermal/intel_soc_dts_iosf.c
index e0813df..caa8776 100644
--- a/drivers/thermal/intel_soc_dts_iosf.c
+++ b/drivers/thermal/intel_soc_dts_iosf.c
@@ -391,8 +391,7 @@ void intel_soc_dts_iosf_interrupt_handler(struct intel_soc_dts_sensors *sensors)
for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
pr_debug("TZD update for zone %d\n", i);
- thermal_zone_device_update(sensors->soc_dts[i].tzone,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(sensors->soc_dts[i].tzone);
}
} else
spin_unlock_irqrestore(&sensors->intr_notify_lock, flags);
diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c
index 337d695..f896a97 100644
--- a/drivers/thermal/max77620_thermal.c
+++ b/drivers/thermal/max77620_thermal.c
@@ -82,8 +82,7 @@ static irqreturn_t max77620_thermal_irq(int irq, void *data)
else if (irq == mtherm->irq_tjalarm2)
dev_crit(mtherm->dev, "Junction Temp Alarm2(140C) occurred\n");
- thermal_zone_device_update(mtherm->tz_device,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(mtherm->tz_device);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 890e272..a65b515 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -285,7 +285,8 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
mutex_unlock(&tz->lock);
data->mode = mode;
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+
+ thermal_zone_device_check(tz);
return 0;
}
diff --git a/drivers/thermal/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom-spmi-temp-alarm.c
index cb46555..fa42517 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -150,7 +150,7 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
{
struct qpnp_tm_chip *chip = data;
- thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(chip->tz_dev);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 5d26aab..69142c2 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -265,8 +265,7 @@ static irqreturn_t rcar_gen3_thermal_irq_thread(int irq, void *data)
int i;
for (i = 0; i < priv->num_tscs; i++)
- thermal_zone_device_update(priv->tscs[i]->zone,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(priv->tscs[i]->zone);
spin_lock_irqsave(&priv->lock, flags);
rcar_thermal_irq_set(priv, true);
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 5c2a42d..080e6ec 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -358,8 +358,7 @@ static void rcar_thermal_work(struct work_struct *work)
return;
if (nctemp != cctemp)
- thermal_zone_device_update(priv->zone,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(priv->zone);
}
static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index c41bb6c..d0e4042 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1032,8 +1032,7 @@ static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
thermal->chip->irq_ack(thermal->regs);
for (i = 0; i < thermal->chip->chn_num; i++)
- thermal_zone_device_update(thermal->sensors[i].tzd,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(thermal->sensors[i].tzd);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index cbe5471..5b07a8f 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -263,7 +263,7 @@ static void exynos_report_trigger(struct exynos_tmu_data *p)
return;
}
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
mutex_lock(&tz->lock);
/* Find the level for which trip happened */
diff --git a/drivers/thermal/st/st_thermal_memmap.c b/drivers/thermal/st/st_thermal_memmap.c
index 91d4231..323c42f 100644
--- a/drivers/thermal/st/st_thermal_memmap.c
+++ b/drivers/thermal/st/st_thermal_memmap.c
@@ -42,8 +42,7 @@ static irqreturn_t st_mmap_thermal_trip_handler(int irq, void *sdata)
{
struct st_thermal_sensor *sensor = sdata;
- thermal_zone_device_update(sensor->thermal_dev,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(sensor->thermal_dev);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d64325e..50085c0 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -504,12 +504,12 @@ void thermal_notify_framework(struct thermal_zone_device *tz, int trip)
}
EXPORT_SYMBOL_GPL(thermal_notify_framework);
-static void thermal_zone_device_check(struct work_struct *work)
+static void thermal_zone_device_work_check(struct work_struct *work)
{
struct thermal_zone_device *tz = container_of(work, struct
thermal_zone_device,
poll_queue.work);
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
}
/*
@@ -993,8 +993,7 @@ static void bind_cdev(struct thermal_cooling_device *cdev)
mutex_lock(&thermal_list_lock);
list_for_each_entry(pos, &thermal_tz_list, node)
if (atomic_cmpxchg(&pos->need_update, 1, 0))
- thermal_zone_device_update(pos,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(pos);
mutex_unlock(&thermal_list_lock);
return cdev;
@@ -1276,12 +1275,12 @@ struct thermal_zone_device *
/* Bind cooling devices for this zone */
bind_tz(tz);
- INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
+ INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_work_check);
thermal_zone_device_reset(tz);
/* Update the new thermal zone and mark it as already updated. */
if (atomic_cmpxchg(&tz->need_update, 1, 0))
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
return tz;
@@ -1505,8 +1504,7 @@ static int thermal_pm_notify(struct notifier_block *nb,
atomic_set(&in_suspend, 0);
list_for_each_entry(tz, &thermal_tz_list, node) {
thermal_zone_device_reset(tz);
- thermal_zone_device_update(tz,
- THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
}
break;
default:
diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index d5db101..bd10b4d 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -242,3 +242,9 @@ int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on)
on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
}
EXPORT_SYMBOL_GPL(thermal_zone_device_toggle);
+
+void thermal_zone_device_check(struct thermal_zone_device *tz)
+{
+ thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+}
+EXPORT_SYMBOL_GPL(thermal_zone_device_check);
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 343f52b..109be2f 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -144,7 +144,7 @@
if (ret)
return ret;
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
return count;
}
@@ -249,7 +249,7 @@
tz->forced_passive = state;
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
return count;
}
@@ -316,7 +316,7 @@
}
if (!ret)
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);
return ret ? ret : count;
}
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index 621add3..d1b55d9 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -54,7 +54,7 @@ static void ti_thermal_work(struct work_struct *work)
struct ti_thermal_data *data = container_of(work,
struct ti_thermal_data, thermal_wq);
- thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(data->ti_thermal);
dev_dbg(&data->ti_thermal->device, "updated thermal zone %s\n",
data->ti_thermal->type);
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index f83bb3e..f2f8b2b 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -248,7 +248,7 @@ static irqreturn_t uniphier_tm_alarm_irq_thread(int irq, void *_tdev)
{
struct uniphier_tm_dev *tdev = _tdev;
- thermal_zone_device_update(tdev->tz_dev, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tdev->tz_dev);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
index 1a6c88b..cb6ebc6 100644
--- a/drivers/thermal/x86_pkg_temp_thermal.c
+++ b/drivers/thermal/x86_pkg_temp_thermal.c
@@ -317,7 +317,7 @@ static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
* concurrent removal in the cpu offline callback.
*/
if (tzone)
- thermal_zone_device_update(tzone, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tzone);
mutex_unlock(&thermal_zone_mutex);
}
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 4fbbabe..4ef79c8 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -468,6 +468,7 @@ struct thermal_cooling_device *
int thermal_zone_get_slope(struct thermal_zone_device *tz);
int thermal_zone_get_offset(struct thermal_zone_device *tz);
int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on);
+void thermal_zone_device_check(struct thermal_zone_device *tz);
int get_tz_trend(struct thermal_zone_device *, int);
struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
--
1.9.1
Enable/check sensor after HW-block setup (if necessary) and setting
data->tz.
Cc: Eric Anholt <[email protected]>
Cc: Stefan Wahren <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/broadcom/bcm2835_thermal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
index 1270e3f..d52c125 100644
--- a/drivers/thermal/broadcom/bcm2835_thermal.c
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
@@ -227,9 +227,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
goto err_clk;
}
- thermal_zone_device_toggle(tz, true);
- thermal_zone_device_check(tz);
-
/*
* right now the FW does set up the HW-block, so we are not
* touching the configuration registers.
@@ -276,6 +273,9 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
data->tz = tz;
+ thermal_zone_device_toggle(tz, true);
+ thermal_zone_device_check(tz);
+
platform_set_drvdata(pdev, tz);
bcm2835_thermal_debugfs(pdev);
--
1.9.1
Enable/check sensor after setting priv->thermal.
Cc: Markus Mayer <[email protected]>
Cc: [email protected]
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/broadcom/brcmstb_thermal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
index fead74f..eada8c1 100644
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -336,11 +336,11 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
return ret;
}
+ priv->thermal = thermal;
+
thermal_zone_device_toggle(thermal, true);
thermal_zone_device_check(thermal);
- priv->thermal = thermal;
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "could not get IRQ\n");
--
1.9.1
Enable sensor after setting sensor data and check sensor after
writing update interval.
Cc: Eduardo Valentin <[email protected]>
Cc: Keerthy <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index 3c2299b..a9afbf9 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -197,13 +197,15 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
return PTR_ERR(data->ti_thermal);
}
+ ti_bandgap_set_sensor_data(bgp, id, data);
+
thermal_zone_device_toggle(data->ti_thermal, true);
- thermal_zone_device_check(data->ti_thermal);
- ti_bandgap_set_sensor_data(bgp, id, data);
ti_bandgap_write_update_interval(bgp, data->sensor_id,
data->ti_thermal->polling_delay);
+ thermal_zone_device_check(data->ti_thermal);
+
return 0;
}
--
1.9.1
Hi Bartlomiej,
> Bartlomiej Zolnierkiewicz <[email protected]> hat am 10. April 2018 um 14:41 geschrieben:
>
>
> Hi,
>
> [devm]_thermal_zone_of_sensor_register() is used to register
> thermal sensor by thermal drivers using DeviceTree. Besides
> registering sensor this function also immediately enables it
> (using ->set_mode method) and then checks it with a update call
> to the thermal core (which ends up using ->get_temp method).
> For many DT thermal drivers this causes a problem because
> [devm]_thermal_zone_of_sensor_register() need to be called in
> order to obtain data about thermal trips which are then used to
> finish hardware sensor setup (only after which ->get_temp can
> be used). The issue has been observed when using Samsung Exynos
> thermal driver and fixed internally in the driver in commit
> d8efad71e5b6 ("thermal: exynos: Reading temperature makes sense
> only when TMU is turned on"). However after this commit there
> are now following warnings from the thermal core visible:
>
> [ 3.453602] thermal thermal_zone0: failed to read out thermal zone (-22)
> [ 3.483468] thermal thermal_zone1: failed to read out thermal zone (-22)
> [ 3.505965] thermal thermal_zone2: failed to read out thermal zone (-22)
> [ 3.528455] thermal thermal_zone3: failed to read out thermal zone (-22)
> [ 3.550939] thermal thermal_zone4: failed to read out thermal zone (-22)
>
> This patchset attempts to directly address the thermal core
> problem with [devm]_thermal_zone_of_sensor_register() and
> affected DT thermal drivers. In order to achieve this sensor
> registration, enable and check operations are separated and
> corresponding drivers are modified to use the new helpers to
> enable and check sensor explicitly.
i've tested patch 1-5 + 17 on a Raspberry Pi 1 B and didn't see any regressions.
Tested-by: Stefan Wahren <[email protected]>
On Tuesday, April 10, 2018 02:41:54 PM Bartlomiej Zolnierkiewicz wrote:
> Hi,
>
> [devm]_thermal_zone_of_sensor_register() is used to register
> thermal sensor by thermal drivers using DeviceTree. Besides
> registering sensor this function also immediately enables it
> (using ->set_mode method) and then checks it with a update call
> to the thermal core (which ends up using ->get_temp method).
> For many DT thermal drivers this causes a problem because
> [devm]_thermal_zone_of_sensor_register() need to be called in
> order to obtain data about thermal trips which are then used to
> finish hardware sensor setup (only after which ->get_temp can
> be used). The issue has been observed when using Samsung Exynos
> thermal driver and fixed internally in the driver in commit
> d8efad71e5b6 ("thermal: exynos: Reading temperature makes sense
> only when TMU is turned on"). However after this commit there
> are now following warnings from the thermal core visible:
>
> [ 3.453602] thermal thermal_zone0: failed to read out thermal zone (-22)
> [ 3.483468] thermal thermal_zone1: failed to read out thermal zone (-22)
> [ 3.505965] thermal thermal_zone2: failed to read out thermal zone (-22)
> [ 3.528455] thermal thermal_zone3: failed to read out thermal zone (-22)
> [ 3.550939] thermal thermal_zone4: failed to read out thermal zone (-22)
>
> This patchset attempts to directly address the thermal core
> problem with [devm]_thermal_zone_of_sensor_register() and
> affected DT thermal drivers. In order to achieve this sensor
> registration, enable and check operations are separated and
> corresponding drivers are modified to use the new helpers to
> enable and check sensor explicitly.
>
> Tested on Exynos5422 based Odroid-XU3 Lite board (aforementioned
> warnings from the thermal core are now gone).
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
>
>
> Bartlomiej Zolnierkiewicz (17):
> thermal: add thermal_zone_device_toggle() helper
> thermal: separate sensor registration and enable
> thermal: add thermal_zone_device_check() helper
> thermal: do sensor checking explicitly in drivers
> thermal: bcm2835: enable/check sensor after its setup is finished
> thermal: brcmstb: enable/check sensor after its setup is finished
> thermal: hisi_thermal: enable/check sensor after its setup is finished
> thermal: qcom: tsens: enable/check sensor after its setup is finished
> thermal: qoriq: enable/check sensor after its setup is finished
> thermal: rcar_gen3_thermal: enable/check sensor after its setup is
> finished
> thermal: rockchip_thermal: enable/check sensor after its setup is
> finished
> thermal: exynos: enable/check sensor after its setup is finished
> thermal: tegra: enable/check sensor after its setup is finished
> thermal: ti-soc-thermal: enable/check sensor after its setup is
> finished
> thermal: uniphier: enable/check sensor after its setup is
> finished
> thermal: zx2967: enable/check sensor after its setup is finished
> thermal: warn on attempts to read temperature on disabled sensors
>
> drivers/acpi/thermal.c | 5 ++--
> drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
> drivers/platform/x86/acerhdf.c | 6 +++-
> drivers/regulator/max8973-regulator.c | 3 +-
> drivers/thermal/broadcom/bcm2835_thermal.c | 3 ++
> drivers/thermal/broadcom/brcmstb_thermal.c | 3 ++
> drivers/thermal/broadcom/ns-thermal.c | 3 ++
> drivers/thermal/da9062-thermal.c | 7 ++---
> drivers/thermal/db8500_thermal.c | 5 +++-
> drivers/thermal/hisi_thermal.c | 22 ++++----------
> drivers/thermal/imx_thermal.c | 3 +-
> drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
> drivers/thermal/intel_bxt_pmic_thermal.c | 3 +-
> drivers/thermal/intel_soc_dts_iosf.c | 3 +-
> drivers/thermal/max77620_thermal.c | 6 ++--
> drivers/thermal/mtk_thermal.c | 3 ++
> drivers/thermal/of-thermal.c | 6 ++--
> drivers/thermal/qcom-spmi-temp-alarm.c | 5 +++-
> drivers/thermal/qcom/tsens.c | 6 ++++
> drivers/thermal/qoriq_thermal.c | 3 ++
> drivers/thermal/rcar_gen3_thermal.c | 7 +++--
> drivers/thermal/rcar_thermal.c | 8 +++--
> drivers/thermal/rockchip_thermal.c | 34 ++++++++++------------
> drivers/thermal/samsung/exynos_tmu.c | 7 ++++-
> drivers/thermal/st/st_thermal_memmap.c | 3 +-
> drivers/thermal/tango_thermal.c | 5 ++++
> drivers/thermal/tegra/soctherm.c | 3 ++
> drivers/thermal/tegra/tegra-bpmp-thermal.c | 3 ++
> drivers/thermal/thermal-generic-adc.c | 3 ++
> drivers/thermal/thermal_core.c | 14 ++++-----
> drivers/thermal/thermal_helpers.c | 33 +++++++++++++++++++++
> drivers/thermal/thermal_sysfs.c | 17 +++++++----
> drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 7 ++++-
> drivers/thermal/uniphier_thermal.c | 6 +++-
> drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
> drivers/thermal/zx2967_thermal.c | 3 ++
> include/linux/thermal.h | 5 ++++
> 37 files changed, 173 insertions(+), 84 deletions(-)
Gentle ping.
Eduardo/Rui, do you see any issues with this patchset that should
be addressed before posting refreshed version?
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
Hi Bartlomiej,
Do you have an updated version of this patchset on 4.19-rc1 somewhere
that I can look at? I might be seeing this issue on the QCom TSENS
driver and would like to verify.
Regards,
Amit
On Tue, Apr 10, 2018 at 6:11 PM, Bartlomiej Zolnierkiewicz
<[email protected]> wrote:
> Hi,
>
> [devm]_thermal_zone_of_sensor_register() is used to register
> thermal sensor by thermal drivers using DeviceTree. Besides
> registering sensor this function also immediately enables it
> (using ->set_mode method) and then checks it with a update call
> to the thermal core (which ends up using ->get_temp method).
> For many DT thermal drivers this causes a problem because
> [devm]_thermal_zone_of_sensor_register() need to be called in
> order to obtain data about thermal trips which are then used to
> finish hardware sensor setup (only after which ->get_temp can
> be used). The issue has been observed when using Samsung Exynos
> thermal driver and fixed internally in the driver in commit
> d8efad71e5b6 ("thermal: exynos: Reading temperature makes sense
> only when TMU is turned on"). However after this commit there
> are now following warnings from the thermal core visible:
>
> [ 3.453602] thermal thermal_zone0: failed to read out thermal zone (-22)
> [ 3.483468] thermal thermal_zone1: failed to read out thermal zone (-22)
> [ 3.505965] thermal thermal_zone2: failed to read out thermal zone (-22)
> [ 3.528455] thermal thermal_zone3: failed to read out thermal zone (-22)
> [ 3.550939] thermal thermal_zone4: failed to read out thermal zone (-22)
>
> This patchset attempts to directly address the thermal core
> problem with [devm]_thermal_zone_of_sensor_register() and
> affected DT thermal drivers. In order to achieve this sensor
> registration, enable and check operations are separated and
> corresponding drivers are modified to use the new helpers to
> enable and check sensor explicitly.
>
> Tested on Exynos5422 based Odroid-XU3 Lite board (aforementioned
> warnings from the thermal core are now gone).
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
>
>
> Bartlomiej Zolnierkiewicz (17):
> thermal: add thermal_zone_device_toggle() helper
> thermal: separate sensor registration and enable
> thermal: add thermal_zone_device_check() helper
> thermal: do sensor checking explicitly in drivers
> thermal: bcm2835: enable/check sensor after its setup is finished
> thermal: brcmstb: enable/check sensor after its setup is finished
> thermal: hisi_thermal: enable/check sensor after its setup is finished
> thermal: qcom: tsens: enable/check sensor after its setup is finished
> thermal: qoriq: enable/check sensor after its setup is finished
> thermal: rcar_gen3_thermal: enable/check sensor after its setup is
> finished
> thermal: rockchip_thermal: enable/check sensor after its setup is
> finished
> thermal: exynos: enable/check sensor after its setup is finished
> thermal: tegra: enable/check sensor after its setup is finished
> thermal: ti-soc-thermal: enable/check sensor after its setup is
> finished
> thermal: uniphier: enable/check sensor after its setup is
> finished
> thermal: zx2967: enable/check sensor after its setup is finished
> thermal: warn on attempts to read temperature on disabled sensors
>
> drivers/acpi/thermal.c | 5 ++--
> drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
> drivers/platform/x86/acerhdf.c | 6 +++-
> drivers/regulator/max8973-regulator.c | 3 +-
> drivers/thermal/broadcom/bcm2835_thermal.c | 3 ++
> drivers/thermal/broadcom/brcmstb_thermal.c | 3 ++
> drivers/thermal/broadcom/ns-thermal.c | 3 ++
> drivers/thermal/da9062-thermal.c | 7 ++---
> drivers/thermal/db8500_thermal.c | 5 +++-
> drivers/thermal/hisi_thermal.c | 22 ++++----------
> drivers/thermal/imx_thermal.c | 3 +-
> drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
> drivers/thermal/intel_bxt_pmic_thermal.c | 3 +-
> drivers/thermal/intel_soc_dts_iosf.c | 3 +-
> drivers/thermal/max77620_thermal.c | 6 ++--
> drivers/thermal/mtk_thermal.c | 3 ++
> drivers/thermal/of-thermal.c | 6 ++--
> drivers/thermal/qcom-spmi-temp-alarm.c | 5 +++-
> drivers/thermal/qcom/tsens.c | 6 ++++
> drivers/thermal/qoriq_thermal.c | 3 ++
> drivers/thermal/rcar_gen3_thermal.c | 7 +++--
> drivers/thermal/rcar_thermal.c | 8 +++--
> drivers/thermal/rockchip_thermal.c | 34 ++++++++++------------
> drivers/thermal/samsung/exynos_tmu.c | 7 ++++-
> drivers/thermal/st/st_thermal_memmap.c | 3 +-
> drivers/thermal/tango_thermal.c | 5 ++++
> drivers/thermal/tegra/soctherm.c | 3 ++
> drivers/thermal/tegra/tegra-bpmp-thermal.c | 3 ++
> drivers/thermal/thermal-generic-adc.c | 3 ++
> drivers/thermal/thermal_core.c | 14 ++++-----
> drivers/thermal/thermal_helpers.c | 33 +++++++++++++++++++++
> drivers/thermal/thermal_sysfs.c | 17 +++++++----
> drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 7 ++++-
> drivers/thermal/uniphier_thermal.c | 6 +++-
> drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
> drivers/thermal/zx2967_thermal.c | 3 ++
> include/linux/thermal.h | 5 ++++
> 37 files changed, 173 insertions(+), 84 deletions(-)
>
> --
> 1.9.1
On Tue, Apr 10, 2018 at 02:41:55PM +0200, Bartlomiej Zolnierkiewicz wrote:
> Add thermal_zone_device_toggle() helper. Then update core code and
> drivers to use it.
Cool, but I think it would be good to have some sort of rational here
at the commit message telling why this helper is being added,
don't you agree?
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> ---
> drivers/thermal/hisi_thermal.c | 14 ++------------
> drivers/thermal/of-thermal.c | 2 +-
> drivers/thermal/rockchip_thermal.c | 22 +++++-----------------
> drivers/thermal/thermal_helpers.c | 15 +++++++++++++++
> drivers/thermal/thermal_sysfs.c | 8 +++++---
> include/linux/thermal.h | 1 +
> 6 files changed, 29 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
> index 761d055..9428499 100644
> --- a/drivers/thermal/hisi_thermal.c
> +++ b/drivers/thermal/hisi_thermal.c
> @@ -515,15 +515,6 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
> };
> MODULE_DEVICE_TABLE(of, of_hisi_thermal_match);
>
> -static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
> - bool on)
> -{
> - struct thermal_zone_device *tzd = sensor->tzd;
> -
> - tzd->ops->set_mode(tzd,
> - on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
> -}
> -
> static int hisi_thermal_probe(struct platform_device *pdev)
> {
> struct hisi_thermal_data *data;
> @@ -571,7 +562,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
> }
> }
>
> - hisi_thermal_toggle_sensor(&data->sensor, true);
> + thermal_zone_device_toggle((&data->sensor)->tzd, true);
>
> return 0;
> }
> @@ -579,9 +570,8 @@ static int hisi_thermal_probe(struct platform_device *pdev)
> static int hisi_thermal_remove(struct platform_device *pdev)
> {
> struct hisi_thermal_data *data = platform_get_drvdata(pdev);
> - struct hisi_thermal_sensor *sensor = &data->sensor;
>
> - hisi_thermal_toggle_sensor(sensor, false);
> + thermal_zone_device_toggle((&data->sensor)->tzd, false);
>
> data->disable_sensor(data);
>
> diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
> index e09f035..f138b78 100644
> --- a/drivers/thermal/of-thermal.c
> +++ b/drivers/thermal/of-thermal.c
> @@ -510,7 +510,7 @@ struct thermal_zone_device *
> tzd = thermal_zone_of_add_sensor(child, sensor_np,
> data, ops);
> if (!IS_ERR(tzd))
> - tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
> + thermal_zone_device_toggle(tzd, true);
>
> of_node_put(sensor_specs.np);
> of_node_put(child);
> diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
> index f36375d..c191e41 100644
> --- a/drivers/thermal/rockchip_thermal.c
> +++ b/drivers/thermal/rockchip_thermal.c
> @@ -1022,15 +1022,6 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
> };
> MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
>
> -static void
> -rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on)
> -{
> - struct thermal_zone_device *tzd = sensor->tzd;
> -
> - tzd->ops->set_mode(tzd,
> - on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
> -}
> -
> static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
> {
> struct rockchip_thermal_data *thermal = dev;
> @@ -1292,7 +1283,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
> thermal->chip->control(thermal->regs, true);
>
> for (i = 0; i < thermal->chip->chn_num; i++)
> - rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
>
> platform_set_drvdata(pdev, thermal);
>
> @@ -1311,11 +1302,8 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
> struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
> int i;
>
> - for (i = 0; i < thermal->chip->chn_num; i++) {
> - struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
> -
> - rockchip_thermal_toggle_sensor(sensor, false);
> - }
> + for (i = 0; i < thermal->chip->chn_num; i++)
> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
>
> thermal->chip->control(thermal->regs, false);
>
> @@ -1332,7 +1320,7 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
> int i;
>
> for (i = 0; i < thermal->chip->chn_num; i++)
> - rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
>
> thermal->chip->control(thermal->regs, false);
>
> @@ -1383,7 +1371,7 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
> thermal->chip->control(thermal->regs, true);
>
> for (i = 0; i < thermal->chip->chn_num; i++)
> - rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
>
> pinctrl_pm_select_default_state(dev);
>
> diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
> index eb03d7e..d5db101 100644
> --- a/drivers/thermal/thermal_helpers.c
> +++ b/drivers/thermal/thermal_helpers.c
> @@ -227,3 +227,18 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz)
> return 0;
> }
> EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
> +
> +/**
> + * thermal_zone_device_toggle() - enables/disables thermal zone device
> + * @tz: a valid pointer to a struct thermal_zone_device
> + *
> + * Enables/Disables thermal zone device.
> + *
> + * Return: On success returns 0, an error code otherwise.
> + */
> +int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on)
> +{
> + return tz->ops->set_mode(tz,
> + on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
why not simply getting a mode type (enum thermal_device_mode)?
> +}
> +EXPORT_SYMBOL_GPL(thermal_zone_device_toggle);
I know naming is always the hardest part :-), but to me, this function
is more a thermal_zone_set_mode() than device_toggle(). At least, based
on what I see in the code, we are not really toggling device per si,
just setting a mode.
> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
> index 23b5e0a..343f52b 100644
> --- a/drivers/thermal/thermal_sysfs.c
> +++ b/drivers/thermal/thermal_sysfs.c
> @@ -72,17 +72,19 @@
> {
> struct thermal_zone_device *tz = to_thermal_zone(dev);
> int result;
> + bool on;
>
> if (!tz->ops->set_mode)
> return -EPERM;
>
> if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
> - result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
> + on = true;
> else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
> - result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
> + on = false;
> else
> - result = -EINVAL;
> + return -EINVAL;
>
> + result = thermal_zone_device_toggle(tz, on);
> if (result)
> return result;
>
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 7834be6..4fbbabe 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -467,6 +467,7 @@ struct thermal_cooling_device *
> int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
> int thermal_zone_get_slope(struct thermal_zone_device *tz);
> int thermal_zone_get_offset(struct thermal_zone_device *tz);
> +int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on);
>
You missed the #else section of the #if IS_ENABLED(CONFIG_THERMAL),
didn't you?
We want to have a stub when config thermal is not set.
> int get_tz_trend(struct thermal_zone_device *, int);
> struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
> --
> 1.9.1
>
On Tue, Apr 10, 2018 at 02:41:54PM +0200, Bartlomiej Zolnierkiewicz wrote:
> Hi,
>
> [devm]_thermal_zone_of_sensor_register() is used to register
> thermal sensor by thermal drivers using DeviceTree. Besides
> registering sensor this function also immediately enables it
> (using ->set_mode method) and then checks it with a update call
> to the thermal core (which ends up using ->get_temp method).
Yeah, pretty much the driver needs to be ready to answer to callbacks
once it calls thermal_*_register() method.
> For many DT thermal drivers this causes a problem because
Can you be more specific? Are you seeing this problem in samsung driver
or in other drivers too?
> [devm]_thermal_zone_of_sensor_register() need to be called in
> order to obtain data about thermal trips which are then used to
> finish hardware sensor setup (only after which ->get_temp can
> be used). The issue has been observed when using Samsung Exynos
Oh I see, this is because trip info is read by the of thermal thermal
then, correct?
> thermal driver and fixed internally in the driver in commit
> d8efad71e5b6 ("thermal: exynos: Reading temperature makes sense
> only when TMU is turned on"). However after this commit there
> are now following warnings from the thermal core visible:
>
> [ 3.453602] thermal thermal_zone0: failed to read out thermal zone (-22)
> [ 3.483468] thermal thermal_zone1: failed to read out thermal zone (-22)
> [ 3.505965] thermal thermal_zone2: failed to read out thermal zone (-22)
> [ 3.528455] thermal thermal_zone3: failed to read out thermal zone (-22)
> [ 3.550939] thermal thermal_zone4: failed to read out thermal zone (-22)
>
> This patchset attempts to directly address the thermal core
> problem with [devm]_thermal_zone_of_sensor_register() and
> affected DT thermal drivers. In order to achieve this sensor
> registration, enable and check operations are separated and
> corresponding drivers are modified to use the new helpers to
> enable and check sensor explicitly.
>
Ok. Up to this point I followed that this is a samsung driver issue, not
we need to change the core to fix adapt to it?
And adapting the core should be fine to fit a new use/fix something,
as long the issue is well described..
> Tested on Exynos5422 based Odroid-XU3 Lite board (aforementioned
> warnings from the thermal core are now gone).
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
>
>
> Bartlomiej Zolnierkiewicz (17):
> thermal: add thermal_zone_device_toggle() helper
> thermal: separate sensor registration and enable
> thermal: add thermal_zone_device_check() helper
> thermal: do sensor checking explicitly in drivers
> thermal: bcm2835: enable/check sensor after its setup is finished
> thermal: brcmstb: enable/check sensor after its setup is finished
> thermal: hisi_thermal: enable/check sensor after its setup is finished
> thermal: qcom: tsens: enable/check sensor after its setup is finished
> thermal: qoriq: enable/check sensor after its setup is finished
> thermal: rcar_gen3_thermal: enable/check sensor after its setup is
> finished
> thermal: rockchip_thermal: enable/check sensor after its setup is
> finished
> thermal: exynos: enable/check sensor after its setup is finished
> thermal: tegra: enable/check sensor after its setup is finished
> thermal: ti-soc-thermal: enable/check sensor after its setup is
> finished
> thermal: uniphier: enable/check sensor after its setup is
> finished
> thermal: zx2967: enable/check sensor after its setup is finished
> thermal: warn on attempts to read temperature on disabled sensors
>
> drivers/acpi/thermal.c | 5 ++--
> drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
> drivers/platform/x86/acerhdf.c | 6 +++-
> drivers/regulator/max8973-regulator.c | 3 +-
> drivers/thermal/broadcom/bcm2835_thermal.c | 3 ++
> drivers/thermal/broadcom/brcmstb_thermal.c | 3 ++
> drivers/thermal/broadcom/ns-thermal.c | 3 ++
> drivers/thermal/da9062-thermal.c | 7 ++---
> drivers/thermal/db8500_thermal.c | 5 +++-
> drivers/thermal/hisi_thermal.c | 22 ++++----------
> drivers/thermal/imx_thermal.c | 3 +-
> drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
> drivers/thermal/intel_bxt_pmic_thermal.c | 3 +-
> drivers/thermal/intel_soc_dts_iosf.c | 3 +-
> drivers/thermal/max77620_thermal.c | 6 ++--
> drivers/thermal/mtk_thermal.c | 3 ++
> drivers/thermal/of-thermal.c | 6 ++--
> drivers/thermal/qcom-spmi-temp-alarm.c | 5 +++-
> drivers/thermal/qcom/tsens.c | 6 ++++
> drivers/thermal/qoriq_thermal.c | 3 ++
> drivers/thermal/rcar_gen3_thermal.c | 7 +++--
> drivers/thermal/rcar_thermal.c | 8 +++--
> drivers/thermal/rockchip_thermal.c | 34 ++++++++++------------
> drivers/thermal/samsung/exynos_tmu.c | 7 ++++-
> drivers/thermal/st/st_thermal_memmap.c | 3 +-
> drivers/thermal/tango_thermal.c | 5 ++++
> drivers/thermal/tegra/soctherm.c | 3 ++
> drivers/thermal/tegra/tegra-bpmp-thermal.c | 3 ++
> drivers/thermal/thermal-generic-adc.c | 3 ++
> drivers/thermal/thermal_core.c | 14 ++++-----
> drivers/thermal/thermal_helpers.c | 33 +++++++++++++++++++++
> drivers/thermal/thermal_sysfs.c | 17 +++++++----
> drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 7 ++++-
> drivers/thermal/uniphier_thermal.c | 6 +++-
> drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
> drivers/thermal/zx2967_thermal.c | 3 ++
> include/linux/thermal.h | 5 ++++
> 37 files changed, 173 insertions(+), 84 deletions(-)
>
> --
> 1.9.1
On 09/10/2018 07:16 PM, Eduardo Valentin wrote:
> On Tue, Apr 10, 2018 at 02:41:55PM +0200, Bartlomiej Zolnierkiewicz wrote:
>> Add thermal_zone_device_toggle() helper. Then update core code and
>> drivers to use it.
>
> Cool, but I think it would be good to have some sort of rational here
> at the commit message telling why this helper is being added,
> don't you agree?
Ok, I will enhance the patch description (the rationale is removing
code duplication and preparation for changes in the later patches from
the series).
>> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
>> ---
>> drivers/thermal/hisi_thermal.c | 14 ++------------
>> drivers/thermal/of-thermal.c | 2 +-
>> drivers/thermal/rockchip_thermal.c | 22 +++++-----------------
>> drivers/thermal/thermal_helpers.c | 15 +++++++++++++++
>> drivers/thermal/thermal_sysfs.c | 8 +++++---
>> include/linux/thermal.h | 1 +
>> 6 files changed, 29 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
>> index 761d055..9428499 100644
>> --- a/drivers/thermal/hisi_thermal.c
>> +++ b/drivers/thermal/hisi_thermal.c
>> @@ -515,15 +515,6 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
>> };
>> MODULE_DEVICE_TABLE(of, of_hisi_thermal_match);
>>
>> -static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
>> - bool on)
>> -{
>> - struct thermal_zone_device *tzd = sensor->tzd;
>> -
>> - tzd->ops->set_mode(tzd,
>> - on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
>> -}
>> -
>> static int hisi_thermal_probe(struct platform_device *pdev)
>> {
>> struct hisi_thermal_data *data;
>> @@ -571,7 +562,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
>> }
>> }
>>
>> - hisi_thermal_toggle_sensor(&data->sensor, true);
>> + thermal_zone_device_toggle((&data->sensor)->tzd, true);
>>
>> return 0;
>> }
>> @@ -579,9 +570,8 @@ static int hisi_thermal_probe(struct platform_device *pdev)
>> static int hisi_thermal_remove(struct platform_device *pdev)
>> {
>> struct hisi_thermal_data *data = platform_get_drvdata(pdev);
>> - struct hisi_thermal_sensor *sensor = &data->sensor;
>>
>> - hisi_thermal_toggle_sensor(sensor, false);
>> + thermal_zone_device_toggle((&data->sensor)->tzd, false);
>>
>> data->disable_sensor(data);
>>
>> diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
>> index e09f035..f138b78 100644
>> --- a/drivers/thermal/of-thermal.c
>> +++ b/drivers/thermal/of-thermal.c
>> @@ -510,7 +510,7 @@ struct thermal_zone_device *
>> tzd = thermal_zone_of_add_sensor(child, sensor_np,
>> data, ops);
>> if (!IS_ERR(tzd))
>> - tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
>> + thermal_zone_device_toggle(tzd, true);
>>
>> of_node_put(sensor_specs.np);
>> of_node_put(child);
>> diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
>> index f36375d..c191e41 100644
>> --- a/drivers/thermal/rockchip_thermal.c
>> +++ b/drivers/thermal/rockchip_thermal.c
>> @@ -1022,15 +1022,6 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
>> };
>> MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
>>
>> -static void
>> -rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on)
>> -{
>> - struct thermal_zone_device *tzd = sensor->tzd;
>> -
>> - tzd->ops->set_mode(tzd,
>> - on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
>> -}
>> -
>> static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
>> {
>> struct rockchip_thermal_data *thermal = dev;
>> @@ -1292,7 +1283,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
>> thermal->chip->control(thermal->regs, true);
>>
>> for (i = 0; i < thermal->chip->chn_num; i++)
>> - rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
>> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
>>
>> platform_set_drvdata(pdev, thermal);
>>
>> @@ -1311,11 +1302,8 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
>> struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
>> int i;
>>
>> - for (i = 0; i < thermal->chip->chn_num; i++) {
>> - struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
>> -
>> - rockchip_thermal_toggle_sensor(sensor, false);
>> - }
>> + for (i = 0; i < thermal->chip->chn_num; i++)
>> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
>>
>> thermal->chip->control(thermal->regs, false);
>>
>> @@ -1332,7 +1320,7 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
>> int i;
>>
>> for (i = 0; i < thermal->chip->chn_num; i++)
>> - rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
>> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, false);
>>
>> thermal->chip->control(thermal->regs, false);
>>
>> @@ -1383,7 +1371,7 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
>> thermal->chip->control(thermal->regs, true);
>>
>> for (i = 0; i < thermal->chip->chn_num; i++)
>> - rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
>> + thermal_zone_device_toggle((&thermal->sensors[i])->tzd, true);
>>
>> pinctrl_pm_select_default_state(dev);
>>
>> diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
>> index eb03d7e..d5db101 100644
>> --- a/drivers/thermal/thermal_helpers.c
>> +++ b/drivers/thermal/thermal_helpers.c
>> @@ -227,3 +227,18 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz)
>> return 0;
>> }
>> EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
>> +
>> +/**
>> + * thermal_zone_device_toggle() - enables/disables thermal zone device
>> + * @tz: a valid pointer to a struct thermal_zone_device
>> + *
>> + * Enables/Disables thermal zone device.
>> + *
>> + * Return: On success returns 0, an error code otherwise.
>> + */
>> +int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on)
>> +{
>> + return tz->ops->set_mode(tz,
>> + on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
>
> why not simply getting a mode type (enum thermal_device_mode)?
Well, none of open-coded instances that thermal_zone_device_toggle()
replaces used enum thermal_device_mode. Using bool is simpler and
this enum looks a bit like over-engineering, though I can use it if
you insist.
>> +}
>> +EXPORT_SYMBOL_GPL(thermal_zone_device_toggle);
>
> I know naming is always the hardest part :-), but to me, this function
> is more a thermal_zone_set_mode() than device_toggle(). At least, based
> on what I see in the code, we are not really toggling device per si,
> just setting a mode.
Ok, I will change it (the naming was based on existing helpers from
hisi_thermal.c and rockchip_thermal.c).
>> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
>> index 23b5e0a..343f52b 100644
>> --- a/drivers/thermal/thermal_sysfs.c
>> +++ b/drivers/thermal/thermal_sysfs.c
>> @@ -72,17 +72,19 @@
>> {
>> struct thermal_zone_device *tz = to_thermal_zone(dev);
>> int result;
>> + bool on;
>>
>> if (!tz->ops->set_mode)
>> return -EPERM;
>>
>> if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
>> - result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
>> + on = true;
>> else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
>> - result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
>> + on = false;
>> else
>> - result = -EINVAL;
>> + return -EINVAL;
>>
>> + result = thermal_zone_device_toggle(tz, on);
>> if (result)
>> return result;
>>
>> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>> index 7834be6..4fbbabe 100644
>> --- a/include/linux/thermal.h
>> +++ b/include/linux/thermal.h
>> @@ -467,6 +467,7 @@ struct thermal_cooling_device *
>> int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
>> int thermal_zone_get_slope(struct thermal_zone_device *tz);
>> int thermal_zone_get_offset(struct thermal_zone_device *tz);
>> +int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on);
>>
>
> You missed the #else section of the #if IS_ENABLED(CONFIG_THERMAL),
> didn't you?
No, this function shouldn't be used outside of CONFIG_THERMAL.
> We want to have a stub when config thermal is not set.
Actually it seems that a lot of these existing stubs don't make sense
outside of CONFIG_THERMAL and should be cleaned up.
>> int get_tz_trend(struct thermal_zone_device *, int);
>> struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
On 09/10/2018 07:37 PM, Eduardo Valentin wrote:
> On Tue, Apr 10, 2018 at 02:41:54PM +0200, Bartlomiej Zolnierkiewicz wrote:
>> Hi,
>>
>> [devm]_thermal_zone_of_sensor_register() is used to register
>> thermal sensor by thermal drivers using DeviceTree. Besides
>> registering sensor this function also immediately enables it
>> (using ->set_mode method) and then checks it with a update call
>> to the thermal core (which ends up using ->get_temp method).
>
> Yeah, pretty much the driver needs to be ready to answer to callbacks
> once it calls thermal_*_register() method.
>
>> For many DT thermal drivers this causes a problem because
>
> Can you be more specific? Are you seeing this problem in samsung driver
> or in other drivers too?
We were hitting the issue in exynos driver and we have added
workaround for it in the driver itself (commit 0eb875d88aaa
"thermal: exynos: Reading temperature makes sense only when TMU
is turned on").
After that I did the audit of all DT thermal drivers and found
the issue in majority of them (patches #5-16):
- bcm2835
- brcmstb
- hisi_thermal
- tsens
- qoriq
- rcar_gen3_thermal
- rockchip_thermal
- exynos
- tegra
- ti-soc-thermal
- uniphier
- zx2967
>> [devm]_thermal_zone_of_sensor_register() need to be called in
>> order to obtain data about thermal trips which are then used to
>> finish hardware sensor setup (only after which ->get_temp can
>> be used). The issue has been observed when using Samsung Exynos
>
> Oh I see, this is because trip info is read by the of thermal thermal
> then, correct?
Yes, some drivers need trip info for sensor configuration.
There is also related issue for drivers that support IRQ
(i.e. exynos and rockchip ones):
- sensor should be enabled only after IRQ handler is requested
(because otherwise we might get IRQs that we can't handle)
- IRQ handler needs tzd structure which is obtained from
[devm_]thermal_zone_of_sensor_register()
- after [devm_]thermal_zone_of_sensor_register() call core
thermal code assumes that sensor is enabled and ready to
use (the core may call ->get_temp)
>> thermal driver and fixed internally in the driver in commit
>> d8efad71e5b6 ("thermal: exynos: Reading temperature makes sense
>> only when TMU is turned on"). However after this commit there
>> are now following warnings from the thermal core visible:
>>
>> [ 3.453602] thermal thermal_zone0: failed to read out thermal zone (-22)
>> [ 3.483468] thermal thermal_zone1: failed to read out thermal zone (-22)
>> [ 3.505965] thermal thermal_zone2: failed to read out thermal zone (-22)
>> [ 3.528455] thermal thermal_zone3: failed to read out thermal zone (-22)
>> [ 3.550939] thermal thermal_zone4: failed to read out thermal zone (-22)
>>
>> This patchset attempts to directly address the thermal core
>> problem with [devm]_thermal_zone_of_sensor_register() and
>> affected DT thermal drivers. In order to achieve this sensor
>> registration, enable and check operations are separated and
>> corresponding drivers are modified to use the new helpers to
>> enable and check sensor explicitly.
>>
>
> Ok. Up to this point I followed that this is a samsung driver issue, not
> we need to change the core to fix adapt to it?
Well, we need core changes (patches #2 and #4) for (IMHO) cleaner and
more straightforward solution (with it the core can have the valid info
about the sensor state all the time).
Alternatively we can add workarounds (like the one we added in exynos
driver) to all affected DT thermal drivers (with this solution sensor
can be disabled while the core will think that it is enabled)..
> And adapting the core should be fine to fit a new use/fix something,
> as long the issue is well described..
>
>> Tested on Exynos5422 based Odroid-XU3 Lite board (aforementioned
>> warnings from the thermal core are now gone).
>>
>> Best regards,
>> --
>> Bartlomiej Zolnierkiewicz
>> Samsung R&D Institute Poland
>> Samsung Electronics
>>
>>
>> Bartlomiej Zolnierkiewicz (17):
>> thermal: add thermal_zone_device_toggle() helper
>> thermal: separate sensor registration and enable
>> thermal: add thermal_zone_device_check() helper
>> thermal: do sensor checking explicitly in drivers
>> thermal: bcm2835: enable/check sensor after its setup is finished
>> thermal: brcmstb: enable/check sensor after its setup is finished
>> thermal: hisi_thermal: enable/check sensor after its setup is finished
>> thermal: qcom: tsens: enable/check sensor after its setup is finished
>> thermal: qoriq: enable/check sensor after its setup is finished
>> thermal: rcar_gen3_thermal: enable/check sensor after its setup is
>> finished
>> thermal: rockchip_thermal: enable/check sensor after its setup is
>> finished
>> thermal: exynos: enable/check sensor after its setup is finished
>> thermal: tegra: enable/check sensor after its setup is finished
>> thermal: ti-soc-thermal: enable/check sensor after its setup is
>> finished
>> thermal: uniphier: enable/check sensor after its setup is
>> finished
>> thermal: zx2967: enable/check sensor after its setup is finished
>> thermal: warn on attempts to read temperature on disabled sensors
>>
>> drivers/acpi/thermal.c | 5 ++--
>> drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
>> drivers/platform/x86/acerhdf.c | 6 +++-
>> drivers/regulator/max8973-regulator.c | 3 +-
>> drivers/thermal/broadcom/bcm2835_thermal.c | 3 ++
>> drivers/thermal/broadcom/brcmstb_thermal.c | 3 ++
>> drivers/thermal/broadcom/ns-thermal.c | 3 ++
>> drivers/thermal/da9062-thermal.c | 7 ++---
>> drivers/thermal/db8500_thermal.c | 5 +++-
>> drivers/thermal/hisi_thermal.c | 22 ++++----------
>> drivers/thermal/imx_thermal.c | 3 +-
>> drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
>> drivers/thermal/intel_bxt_pmic_thermal.c | 3 +-
>> drivers/thermal/intel_soc_dts_iosf.c | 3 +-
>> drivers/thermal/max77620_thermal.c | 6 ++--
>> drivers/thermal/mtk_thermal.c | 3 ++
>> drivers/thermal/of-thermal.c | 6 ++--
>> drivers/thermal/qcom-spmi-temp-alarm.c | 5 +++-
>> drivers/thermal/qcom/tsens.c | 6 ++++
>> drivers/thermal/qoriq_thermal.c | 3 ++
>> drivers/thermal/rcar_gen3_thermal.c | 7 +++--
>> drivers/thermal/rcar_thermal.c | 8 +++--
>> drivers/thermal/rockchip_thermal.c | 34 ++++++++++------------
>> drivers/thermal/samsung/exynos_tmu.c | 7 ++++-
>> drivers/thermal/st/st_thermal_memmap.c | 3 +-
>> drivers/thermal/tango_thermal.c | 5 ++++
>> drivers/thermal/tegra/soctherm.c | 3 ++
>> drivers/thermal/tegra/tegra-bpmp-thermal.c | 3 ++
>> drivers/thermal/thermal-generic-adc.c | 3 ++
>> drivers/thermal/thermal_core.c | 14 ++++-----
>> drivers/thermal/thermal_helpers.c | 33 +++++++++++++++++++++
>> drivers/thermal/thermal_sysfs.c | 17 +++++++----
>> drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 7 ++++-
>> drivers/thermal/uniphier_thermal.c | 6 +++-
>> drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
>> drivers/thermal/zx2967_thermal.c | 3 ++
>> include/linux/thermal.h | 5 ++++
>> 37 files changed, 173 insertions(+), 84 deletions(-)
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
On 09/14/2018 01:40 PM, Bartlomiej Zolnierkiewicz wrote:
[...]
>>> --- a/include/linux/thermal.h
>>> +++ b/include/linux/thermal.h
>>> @@ -467,6 +467,7 @@ struct thermal_cooling_device *
>>> int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
>>> int thermal_zone_get_slope(struct thermal_zone_device *tz);
>>> int thermal_zone_get_offset(struct thermal_zone_device *tz);
>>> +int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on);
>>>
>>
>> You missed the #else section of the #if IS_ENABLED(CONFIG_THERMAL),
>> didn't you?
>
> No, this function shouldn't be used outside of CONFIG_THERMAL.
Please disregard my previous comment. I see now that the CONFIG_THERMAL=n
stub is needed and I will add it in the next patch revision.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
On Mon, Sep 17, 2018 at 11:33:59AM +0200, Bartlomiej Zolnierkiewicz wrote:
>
> On 09/14/2018 01:40 PM, Bartlomiej Zolnierkiewicz wrote:
>
> [...]
>
> >>> --- a/include/linux/thermal.h
> >>> +++ b/include/linux/thermal.h
> >>> @@ -467,6 +467,7 @@ struct thermal_cooling_device *
> >>> int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
> >>> int thermal_zone_get_slope(struct thermal_zone_device *tz);
> >>> int thermal_zone_get_offset(struct thermal_zone_device *tz);
> >>> +int thermal_zone_device_toggle(struct thermal_zone_device *tz, bool on);
> >>>
> >>
> >> You missed the #else section of the #if IS_ENABLED(CONFIG_THERMAL),
> >> didn't you?
> >
> > No, this function shouldn't be used outside of CONFIG_THERMAL.
>
> Please disregard my previous comment. I see now that the CONFIG_THERMAL=n
> stub is needed and I will add it in the next patch revision.
Thanks Bartolomiej for keeping this up.
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics