@@ -1141,6 +1141,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
IS_ENABLED(CONFIG_HWMON)) {
/* Add the temperature monitor */
struct device *hwmon_dev;
+ struct thermal_zone_device *tzd;
hwmon_dev =
devm_hwmon_device_register_with_groups(dev,
@@ -1151,8 +1152,13 @@ static int imx_ahci_probe(struct platform_device *pdev)
ret = PTR_ERR(hwmon_dev);
goto disable_clk;
}
- devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev,
- &fsl_sata_ahci_of_thermal_ops);
+ tzd = devm_thermal_zone_of_sensor_register(hwmon_dev, 0,
+ hwmon_dev,
+ &fsl_sata_ahci_of_thermal_ops);
+ if (!IS_ERR(tzd)) {
+ thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
+ }
dev_info(dev, "%s: sensor 'sata_ahci'\n", dev_name(hwmon_dev));
}
@@ -161,6 +161,11 @@ static int hwmon_thermal_add_sensor(struct device *dev,
if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV))
return PTR_ERR(tzd);
+ if (!IS_ERR(tzd)) {
+ thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
+ }
+
return 0;
}
#else
@@ -647,6 +647,10 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
&ntc_of_thermal_ops);
if (IS_ERR(tz))
dev_dbg(dev, "Failed to register to thermal fw.\n");
+ else {
+ thermal_zone_set_mode(tz, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tz);
+ }
return 0;
}
@@ -288,6 +288,10 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
*/
if (IS_ERR(z))
devm_kfree(dev, zone);
+ else {
+ thermal_zone_set_mode(z, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(z);
+ }
}
return 0;
@@ -659,6 +659,11 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
PTR_ERR(info->tzd));
return PTR_ERR(info->tzd);
}
+ if (!IS_ERR(info->tzd)) {
+ thermal_zone_set_mode(info->tzd,
+ THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(info->tzd);
+ }
}
ret = devm_iio_device_register(&pdev->dev, indio_dev);
@@ -246,6 +246,7 @@ static int sun4i_ts_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct device *hwmon;
+ struct thermal_zone_device *tzd;
int error;
u32 reg;
bool ts_attached;
@@ -365,7 +366,12 @@ static int sun4i_ts_probe(struct platform_device *pdev)
if (IS_ERR(hwmon))
return PTR_ERR(hwmon);
- devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, &sun4i_ts_tz_ops);
+ tzd = devm_thermal_zone_of_sensor_register(ts->dev, 0, ts,
+ &sun4i_ts_tz_ops);
+ if (!IS_ERR(tzd)) {
+ thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
+ }
writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC);
@@ -523,6 +523,9 @@ static int max8973_thermal_init(struct max8973_chip *mchip)
return ret;
}
+ thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
+
if (mchip->irq <= 0)
return 0;
@@ -692,6 +692,9 @@ static int armada_thermal_probe(struct platform_device *pdev)
devm_kfree(&pdev->dev, sensor);
continue;
}
+
+ thermal_zone_set_mode(tz, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tz);
}
return 0;
@@ -227,6 +227,9 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
goto err_clk;
}
+ thermal_zone_set_mode(tz, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tz);
+
/*
* right now the FW does set up the HW-block, so we are not
* touching the configuration registers.
@@ -336,6 +336,9 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_set_mode(thermal, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(thermal);
+
priv->thermal = thermal;
irq = platform_get_irq(pdev, 0);
@@ -71,6 +71,9 @@ static int ns_thermal_probe(struct platform_device *pdev)
return PTR_ERR(ns_thermal->tz);
}
+ thermal_zone_set_mode(ns_thermal->tz, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(ns_thermal->tz);
+
platform_set_drvdata(pdev, ns_thermal);
return 0;
@@ -488,6 +488,9 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
return ret;
}
+ thermal_zone_set_mode(sensor->tzd, THERMAL_DEVICE_ENABLED);
+ 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++) {
@@ -125,6 +125,9 @@ static int max77620_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_set_mode(mtherm->tz_device, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(mtherm->tz_device);
+
ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm1, NULL,
max77620_thermal_irq,
IRQF_ONESHOT | IRQF_SHARED,
@@ -766,6 +766,9 @@ static int mtk_thermal_probe(struct platform_device *pdev)
goto err_disable_clk_peri_therm;
}
+ thermal_zone_set_mode(tzdev, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzdev);
+
return 0;
err_disable_clk_peri_therm:
@@ -494,12 +494,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_set_mode(tzd,
- THERMAL_DEVICE_ENABLED);
- thermal_zone_device_check(tzd);
- }
-
of_node_put(sensor_specs.np);
of_node_put(child);
goto exit;
@@ -320,6 +320,9 @@ static int qpnp_tm_probe(struct platform_device *pdev)
return PTR_ERR(chip->tz_dev);
}
+ thermal_zone_set_mode(chip->tz_dev, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(chip->tz_dev);
+
return 0;
}
@@ -98,12 +98,18 @@ 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_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
+
tmdev->sensor[i].tzd = tzd;
+
if (tmdev->ops->enable)
tmdev->ops->enable(tmdev, i);
}
@@ -233,6 +233,9 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
goto err_tmu;
}
+ thermal_zone_set_mode(data->tz, THERMAL_DEVICE_ENABLED);
+ 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);
@@ -420,6 +420,10 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(zone);
goto error_unregister;
}
+
+ thermal_zone_set_mode(zone, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(zone);
+
tsc->zone = zone;
ret = of_thermal_get_ntrips(tsc->zone);
@@ -566,6 +566,10 @@ static int rcar_thermal_probe(struct platform_device *pdev)
}
if (chip->use_of_thermal) {
+ thermal_zone_set_mode(priv->zone,
+ THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(priv->zone);
+
/*
* thermal_zone doesn't enable hwmon as default,
* but, enable it here to keep compatible
@@ -1161,6 +1161,9 @@ static int rockchip_configure_from_dt(struct device *dev,
return error;
}
+ thermal_zone_set_mode(sensor->tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(sensor->tzd);
+
return 0;
}
@@ -1109,6 +1109,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto err_sclk;
}
+ thermal_zone_set_mode(data->tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(data->tzd);
+
ret = exynos_tmu_initialize(pdev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize TMU\n");
@@ -90,6 +90,11 @@ 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_set_mode(tzdev, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzdev);
+ }
+
return PTR_ERR_OR_ZERO(tzdev);
}
@@ -1375,6 +1375,9 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
goto disable_clocks;
}
+ thermal_zone_set_mode(z, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(z);
+
zone->tz = z;
tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
@@ -213,6 +213,9 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
continue;
}
+ thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
+
zone->tzd = tzd;
INIT_WORK(&zone->tz_device_update_work,
tz_device_update_work_fn);
@@ -143,6 +143,9 @@ static int gadc_thermal_probe(struct platform_device *pdev)
return ret;
}
+ thermal_zone_set_mode(gti->tz_dev, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(gti->tz_dev);
+
return 0;
}
@@ -197,6 +197,9 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
return PTR_ERR(data->ti_thermal);
}
+ thermal_zone_set_mode(data->ti_thermal, THERMAL_DEVICE_ENABLED);
+ 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);
@@ -307,6 +307,9 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return PTR_ERR(tdev->tz_dev);
}
+ thermal_zone_set_mode(tdev->tz_dev, THERMAL_DEVICE_ENABLED);
+ 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);
@@ -168,6 +168,9 @@ static int zx2967_thermal_probe(struct platform_device *pdev)
goto disable_clk_all;
}
+ thermal_zone_set_mode(priv->tzd, THERMAL_DEVICE_ENABLED);
+ 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");
[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: tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED) (->set_mode is set to of_thermal_set_mode() in of-thermal.c) - checks it (indirectly by using of_thermal_set_mode()): thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); (which in turn 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) There is also related issue for DT thermal drivers that support IRQ (i.e. exynos and rockchip ones): - sensor hardware 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 (i.e. that IRQ handler has been requested and sensor hardware has been enabled) In order to prepare for fixing all abovementioned issues separate sensor registration and enable+check operations in the core DT thermal code and update DT thermal drivers accordingly: * Move thermal_zone_[set_mode,device_check]() calls to the users of [devm]_thermal_zone_of_sensor_register(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/ahci_imx.c | 10 ++++++++-- drivers/hwmon/hwmon.c | 5 +++++ drivers/hwmon/ntc_thermistor.c | 4 ++++ drivers/hwmon/scpi-hwmon.c | 4 ++++ drivers/iio/adc/sun4i-gpadc-iio.c | 5 +++++ drivers/input/touchscreen/sun4i-ts.c | 8 +++++++- drivers/regulator/max8973-regulator.c | 3 +++ drivers/thermal/armada_thermal.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/hisi_thermal.c | 3 +++ drivers/thermal/max77620_thermal.c | 3 +++ drivers/thermal/mtk_thermal.c | 3 +++ drivers/thermal/of-thermal.c | 6 ------ drivers/thermal/qcom-spmi-temp-alarm.c | 3 +++ drivers/thermal/qcom/tsens.c | 6 ++++++ drivers/thermal/qoriq_thermal.c | 3 +++ drivers/thermal/rcar_gen3_thermal.c | 4 ++++ drivers/thermal/rcar_thermal.c | 4 ++++ drivers/thermal/rockchip_thermal.c | 3 +++ drivers/thermal/samsung/exynos_tmu.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/ti-soc-thermal/ti-thermal-common.c | 3 +++ drivers/thermal/uniphier_thermal.c | 3 +++ drivers/thermal/zx2967_thermal.c | 3 +++ 29 files changed, 106 insertions(+), 9 deletions(-)