Subject: [PATCH v2 00/17] thermal: enable+check sensor after its setup is finished

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:

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 fix all abovementioned issues sensor registration,
enable and check operations are separated in the core DT thermal
code and corresponding DT thermal drivers are modified to do sensor
setup correctly.

Changes since v1:
- rebased on the current -next kernel (next-20181015)
- enhanced patch descriptions and cover letter
- renamed thermal_zone_device_toggler() to thermal_zone_set_mode()
- converted thermal_zone_set_mode() to use enum thermal_device_mode
- added CONFIG_THERMAL=n stubs for thermal_zone_set_mode() and
thermal_zone_device_check()
- fixed uses of [devm]_thermal_zone_of_sensor_register() outside of
drivers/thermal/
- changed ordering between patch #2 and #3 in order to add all
needed core helpers first before fixing sensor setup code
- changed ordering between patch #3 and #4 in order to simplify them
- renamed patch #3 to "thermal: separate sensor enable and check
operations"
- renamed patch #4 to "thermal: separate sensor registration and
enable+check operations"

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


Bartlomiej Zolnierkiewicz (17):
thermal: add thermal_zone_set_mode() helper
thermal: add thermal_zone_device_check() helper
thermal: separate sensor enable and check operations
thermal: separate sensor registration and enable+check operations
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/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/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
drivers/platform/x86/acerhdf.c | 6 +++-
drivers/regulator/max8973-regulator.c | 6 ++--
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/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 | 7 ++--
drivers/thermal/rockchip_thermal.c | 38 +++++++++++-----------
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 | 32 ++++++++++++++++++
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 | 11 +++++++
44 files changed, 220 insertions(+), 87 deletions(-)

--
1.9.1



Subject: [PATCH v2 02/17] thermal: add thermal_zone_device_check() helper

In order to remove the code duplication and prepare for further
changes:

* 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.

There should be no functional changes caused by this patch.

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 | 3 +++
25 files changed, 47 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 6d29dc4..b0afd36 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -169,7 +169,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 5052242..5a2b93a 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -417,7 +417,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 7cd493e..9a522ed 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 b3f8d9f..63d4fc3 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 aa452ac..22f57ef 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -384,7 +384,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;
}
@@ -635,7 +636,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 159bbce..e6bc69f 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 118910c..c422b08 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -271,7 +271,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 ad4f3a8..d3910be 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -188,7 +188,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 7aed533..e0d9424 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -256,8 +256,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 78f9328..6619a48 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -391,8 +391,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 2edd44c..5640675 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 48eef55..9e98b12 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -789,7 +789,7 @@ static void exynos_tmu_work(struct work_struct *work)
struct exynos_tmu_data *data = container_of(work,
struct exynos_tmu_data, irq_work);

- thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(data->tzd);

mutex_lock(&data->lock);
clk_enable(data->clk);
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 6ab9823..1fbd4bd 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -501,12 +501,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);
}

/*
@@ -990,8 +990,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;
@@ -1273,12 +1272,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;

@@ -1502,8 +1501,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 b18cee2..14b7a7e 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -238,3 +238,9 @@ int thermal_zone_set_mode(struct thermal_zone_device *tz,
return tz->ops->set_mode(tz, mode);
}
EXPORT_SYMBOL_GPL(thermal_zone_set_mode);
+
+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 2e9e762..3b38fb9 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -141,7 +141,7 @@
if (ret)
return ret;

- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);

return count;
}
@@ -246,7 +246,7 @@

tz->forced_passive = state;

- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+ thermal_zone_device_check(tz);

return count;
}
@@ -313,7 +313,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 b4f981d..b80b6e2 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 55477d7..bb95983 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 1ef937d..745defc 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 9d21fd1..3e325b3 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -454,6 +454,7 @@ struct thermal_cooling_device *
int thermal_zone_get_offset(struct thermal_zone_device *tz);
int thermal_zone_set_mode(struct thermal_zone_device *tz,
enum thermal_device_mode mode);
+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 *,
@@ -523,6 +524,8 @@ static inline int thermal_zone_get_offset(
static inline int thermal_zone_set_mode(
struct thermal_zone_device *tz, enum thermal_device_mode mode)
{ return -ENODEV; }
+static inline void thermal_zone_device_check(struct thermal_zone_device *tz)
+{ }
static inline int get_tz_trend(struct thermal_zone_device *tz, int trip)
{ return -ENODEV; }
static inline struct thermal_instance *
--
1.9.1


Subject: [PATCH v2 05/17] thermal: bcm2835: enable+check sensor after its setup is finished

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 687a00c..ec82fef 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_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.
@@ -276,6 +273,9 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)

data->tz = tz;

+ thermal_zone_set_mode(tz, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tz);
+
platform_set_drvdata(pdev, tz);

bcm2835_thermal_debugfs(pdev);
--
1.9.1


Subject: [PATCH v2 06/17] thermal: brcmstb: enable+check sensor after its setup is finished

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 3511ce6..5650a6a 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_set_mode(thermal, THERMAL_DEVICE_ENABLED);
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


Subject: [PATCH v2 07/17] thermal: hisi_thermal: enable+check sensor after its setup is finished

* 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 cc4e2ca..370696c 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_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++) {
@@ -553,6 +550,9 @@ static int hisi_thermal_probe(struct platform_device *pdev)
return ret;
}

+ thermal_zone_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_ENABLED);
+ 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_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_ENABLED);
- thermal_zone_device_check((&data->sensor)->tzd);
-
return 0;
}

--
1.9.1


Subject: [PATCH v2 08/17] thermal: qcom: tsens: enable+check sensor after its setup is finished

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 dbd2556..01bff96 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -105,13 +105,13 @@ static int tsens_register(struct tsens_device *tmdev)
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);
+
+ thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(tzd);
}
return 0;
}
--
1.9.1


Subject: [PATCH v2 09/17] thermal: qoriq: enable+check sensor after its setup is finished

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 d8a80448..fb1750f 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -233,13 +233,13 @@ 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);

+ thermal_zone_set_mode(data->tz, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(data->tz);
+
return 0;

err_tmu:
--
1.9.1


Subject: [PATCH v2 01/17] thermal: add thermal_zone_set_mode() helper

In order to remove the code duplication and prepare for further
changes:

* Add thermal_zone_set_mode() helper. Then update core code and
drivers to use it.

There should be no functional changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/thermal/hisi_thermal.c | 14 ++------------
drivers/thermal/of-thermal.c | 3 ++-
drivers/thermal/rockchip_thermal.c | 26 +++++++++-----------------
drivers/thermal/thermal_helpers.c | 14 ++++++++++++++
drivers/thermal/thermal_sysfs.c | 8 +++++---
include/linux/thermal.h | 5 +++++
6 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 761d055..b3f8d9f 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_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_ENABLED);

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_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_DISABLED);

data->disable_sensor(data);

diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 4f28165..118910c 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -496,7 +496,8 @@ 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_set_mode(tzd,
+ THERMAL_DEVICE_ENABLED);

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..2edd44c 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,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++)
- rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
+ thermal_zone_set_mode((&thermal->sensors[i])->tzd,
+ THERMAL_DEVICE_ENABLED);

platform_set_drvdata(pdev, thermal);

@@ -1311,11 +1303,9 @@ 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_set_mode((&thermal->sensors[i])->tzd,
+ THERMAL_DEVICE_DISABLED);

thermal->chip->control(thermal->regs, false);

@@ -1332,7 +1322,8 @@ 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_set_mode((&thermal->sensors[i])->tzd,
+ THERMAL_DEVICE_DISABLED);

thermal->chip->control(thermal->regs, false);

@@ -1383,7 +1374,8 @@ 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_set_mode((&thermal->sensors[i])->tzd,
+ THERMAL_DEVICE_ENABLED);

pinctrl_pm_select_default_state(dev);

diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index 2ba756a..b18cee2 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -224,3 +224,17 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz)
return 0;
}
EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
+
+/**
+ * thermal_zone_set_mode() - sets mode of thermal zone device
+ * @tz: a valid pointer to a struct thermal_zone_device
+ * @mode: mode to be set
+ *
+ * Return: On success returns 0, an error code otherwise.
+ */
+int thermal_zone_set_mode(struct thermal_zone_device *tz,
+ enum thermal_device_mode mode)
+{
+ return tz->ops->set_mode(tz, mode);
+}
+EXPORT_SYMBOL_GPL(thermal_zone_set_mode);
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 2241cea..2e9e762 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -69,17 +69,19 @@
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
int result;
+ enum thermal_device_mode mode;

if (!tz->ops->set_mode)
return -EPERM;

if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
- result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+ mode = THERMAL_DEVICE_ENABLED;
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
- result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+ mode = THERMAL_DEVICE_DISABLED;
else
- result = -EINVAL;
+ return -EINVAL;

+ result = thermal_zone_set_mode(tz, mode);
if (result)
return result;

diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 5f4705f..9d21fd1 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -452,6 +452,8 @@ 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_set_mode(struct thermal_zone_device *tz,
+ enum thermal_device_mode mode);

int get_tz_trend(struct thermal_zone_device *, int);
struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
@@ -518,6 +520,9 @@ static inline int thermal_zone_get_slope(
static inline int thermal_zone_get_offset(
struct thermal_zone_device *tz)
{ return -ENODEV; }
+static inline int thermal_zone_set_mode(
+ struct thermal_zone_device *tz, enum thermal_device_mode mode)
+{ return -ENODEV; }
static inline int get_tz_trend(struct thermal_zone_device *tz, int trip)
{ return -ENODEV; }
static inline struct thermal_instance *
--
1.9.1


Subject: [PATCH v2 11/17] thermal: rockchip_thermal: enable+check sensor after its setup is finished

* 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]>
---
drivers/thermal/rockchip_thermal.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 90d8175..ef9e2aa 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_set_mode(sensor->tzd, THERMAL_DEVICE_ENABLED);
- thermal_zone_device_check(sensor->tzd);
-
return 0;
}

@@ -1272,6 +1269,10 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
}
}

+ for (i = 0; i < thermal->chip->chn_num; i++)
+ thermal_zone_set_mode((&thermal->sensors[i])->tzd,
+ THERMAL_DEVICE_ENABLED);
+
error = devm_request_threaded_irq(&pdev->dev, irq, NULL,
&rockchip_thermal_alarm_irq_thread,
IRQF_ONESHOT,
@@ -1284,11 +1285,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_set_mode((&thermal->sensors[i])->tzd,
- THERMAL_DEVICE_ENABLED);
+ 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


Subject: [PATCH v2 03/17] thermal: separate sensor enable and check operations

[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 enable and check operations in the core thermal code and
update thermal drivers accordingly:

* 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_set_mode() (only place which calls
->set_mode). Modify mode_store() in thermal_sysfs.c accordingly.

There should be no functional changes caused by this patch.

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/db8500_thermal.c | 2 ++
drivers/thermal/hisi_thermal.c | 2 ++
drivers/thermal/imx_thermal.c | 2 --
drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
drivers/thermal/of-thermal.c | 6 +++---
drivers/thermal/rockchip_thermal.c | 16 ++++++++++++----
drivers/thermal/thermal_sysfs.c | 3 +++
include/linux/thermal.h | 2 ++
11 files changed, 29 insertions(+), 11 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 b0afd36..5f4b3bd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -170,8 +170,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 5a2b93a..884fd83 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -507,6 +507,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/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 63d4fc3..6151e55 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -561,6 +561,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
}

thermal_zone_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check((&data->sensor)->tzd);

return 0;
}
@@ -570,6 +571,7 @@ static int hisi_thermal_remove(struct platform_device *pdev)
struct hisi_thermal_data *data = platform_get_drvdata(pdev);

thermal_zone_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_DISABLED);
+ 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 22f57ef..7abad6c 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -385,8 +385,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/of-thermal.c b/drivers/thermal/of-thermal.c
index c422b08..f1dcb7d 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -272,8 +272,6 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,

data->mode = mode;

- thermal_zone_device_check(tz);
-
return 0;
}

@@ -496,9 +494,11 @@ 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))
+ 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);
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 5640675..715f4cd 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1281,9 +1281,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }

platform_set_drvdata(pdev, thermal);

@@ -1302,9 +1304,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
THERMAL_DEVICE_DISABLED);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }

thermal->chip->control(thermal->regs, false);

@@ -1320,9 +1324,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
THERMAL_DEVICE_DISABLED);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }

thermal->chip->control(thermal->regs, false);

@@ -1372,9 +1378,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check((&thermal->sensors[i])->tzd);
+ }

pinctrl_pm_select_default_state(dev);

diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 3b38fb9..ac39fb6 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -85,6 +85,9 @@
if (result)
return result;

+ if (!tz->ops->set_mode_skip_check)
+ thermal_zone_device_check(tz);
+
return count;
}

diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 3e325b3..92c460e 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -113,6 +113,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


Subject: [PATCH v2 14/17] thermal: ti-soc-thermal: enable+check sensor after its setup is finished

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 aa15719..4675d96 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_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);

+ thermal_zone_device_check(data->ti_thermal);
+
return 0;
}

--
1.9.1


Subject: [PATCH v2 15/17] thermal: uniphier: enable+check sensor after its setup is finished

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 ed3a920..9ccc1fc 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_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);
@@ -332,8 +329,12 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return -EINVAL;
}

+ thermal_zone_set_mode(tdev->tz_dev, THERMAL_DEVICE_ENABLED);
+
uniphier_tm_enable_sensor(tdev);

+ thermal_zone_device_check(tdev->tz_dev);
+
return 0;
}

--
1.9.1


Subject: [PATCH v2 16/17] thermal: zx2967: enable+check sensor after its setup is finished

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 3c08e1d..4e30b1f 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_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");
@@ -178,6 +175,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);
+
priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);

--
1.9.1


Subject: [PATCH v2 04/17] thermal: separate sensor registration and enable+check operations

[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 <[email protected]>
---
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(-)

diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index b00799d..f1dcc3d 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -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));
}

diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index ac1cdf8..486d7a0 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -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
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
index c52d07c..d423b0f 100644
--- a/drivers/hwmon/ntc_thermistor.c
+++ b/drivers/hwmon/ntc_thermistor.c
@@ -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;
}
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c
index 111d521..ad5c5d7 100644
--- a/drivers/hwmon/scpi-hwmon.c
+++ b/drivers/hwmon/scpi-hwmon.c
@@ -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;
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 04d7147..ff67f72 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -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);
diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c
index d2e14d9..d38bf69 100644
--- a/drivers/input/touchscreen/sun4i-ts.c
+++ b/drivers/input/touchscreen/sun4i-ts.c
@@ -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);

diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 9a522ed..65b445e 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -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;

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 2c2f6d9..5a07a8d 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -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;
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
index 23ad4f9..687a00c 100644
--- a/drivers/thermal/broadcom/bcm2835_thermal.c
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
@@ -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.
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
index 1919f91..3511ce6 100644
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -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);
diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c
index 322e741..8ace201 100644
--- a/drivers/thermal/broadcom/ns-thermal.c
+++ b/drivers/thermal/broadcom/ns-thermal.c
@@ -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;
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 6151e55..cc4e2ca 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -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++) {
diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c
index e6bc69f..ffca9a7 100644
--- a/drivers/thermal/max77620_thermal.c
+++ b/drivers/thermal/max77620_thermal.c
@@ -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,
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 0691f26..e18cb0e 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -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:
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index f1dcb7d..523ac5c 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -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;
diff --git a/drivers/thermal/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom-spmi-temp-alarm.c
index d3910be..7ba73ca 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -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;
}

diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index a2c9bfa..dbd2556 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -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);
}
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 450ed66..d8a80448 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -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);
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index e0d9424..c72453e 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -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);
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 6619a48..f2f7ad3 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -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
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 715f4cd..90d8175 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -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;
}

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 9e98b12..8ec74a62 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -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");
diff --git a/drivers/thermal/tango_thermal.c b/drivers/thermal/tango_thermal.c
index 4e67795..caa4036 100644
--- a/drivers/thermal/tango_thermal.c
+++ b/drivers/thermal/tango_thermal.c
@@ -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);
}

diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index ed28110..2ac9f81 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -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;

diff --git a/drivers/thermal/tegra/tegra-bpmp-thermal.c b/drivers/thermal/tegra/tegra-bpmp-thermal.c
index b0980db..3181110 100644
--- a/drivers/thermal/tegra/tegra-bpmp-thermal.c
+++ b/drivers/thermal/tegra/tegra-bpmp-thermal.c
@@ -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);
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index bf1c628..c1c3746 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -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;
}

diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index b80b6e2..aa15719 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -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);
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index bb95983..ed3a920 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -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);
diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
index 6acce0b..3c08e1d 100644
--- a/drivers/thermal/zx2967_thermal.c
+++ b/drivers/thermal/zx2967_thermal.c
@@ -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");
--
1.9.1


Subject: [PATCH v2 10/17] thermal: rcar_gen3_thermal: enable+check sensor after its setup is finished

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 c72453e..eb50f33 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -421,9 +421,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
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);
@@ -431,6 +428,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_set_mode(zone, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(zone);
}

priv->num_tscs = i;
--
1.9.1


Subject: [PATCH v2 12/17] thermal: exynos: enable+check sensor after its setup is finished

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 8ec74a62..796a868 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1109,15 +1109,14 @@ 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");
goto err_thermal;
}

+ thermal_zone_set_mode(data->tzd, THERMAL_DEVICE_ENABLED);
+
ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
if (ret) {
@@ -1126,6 +1125,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


Subject: [PATCH v2 13/17] thermal: tegra: enable+check sensor after its setup is finished

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 2ac9f81..394b34e 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -1375,9 +1375,6 @@ 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;

@@ -1385,6 +1382,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_set_mode(z, THERMAL_DEVICE_ENABLED);
+ thermal_zone_device_check(z);
}

soctherm_debug_init(pdev);
--
1.9.1


Subject: [PATCH v2 17/17] thermal: warn on attempts to read temperature on disabled sensors

* 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 523ac5c..912bd85 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -378,6 +378,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 14b7a7e..12d1f53 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -84,6 +84,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 92c460e..2215e11 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -115,6 +115,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


2018-10-26 12:12:05

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 08/17] thermal: qcom: tsens: enable+check sensor after its setup is finished

On Wed, Oct 17, 2018 at 9:24 PM Bartlomiej Zolnierkiewicz
<[email protected]> wrote:
>
> 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 dbd2556..01bff96 100644
> --- a/drivers/thermal/qcom/tsens.c
> +++ b/drivers/thermal/qcom/tsens.c
> @@ -105,13 +105,13 @@ static int tsens_register(struct tsens_device *tmdev)
> if (IS_ERR(tzd))
> continue;
>
> - thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
> - thermal_zone_device_check(tzd);
> -

I don't quite understand why you're making this move explicitly in a
separate patch for each of the drivers? You added it here in patch 4
in the first place, why not add it in the correct place there itself?


> tmdev->sensor[i].tzd = tzd;
>
> if (tmdev->ops->enable)
> tmdev->ops->enable(tmdev, i);
> +
> + thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
> + thermal_zone_device_check(tzd);
>
> }
> return 0;
> }
> --
> 1.9.1
>

2018-10-26 12:12:14

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 03/17] thermal: separate sensor enable and check operations

On Wed, Oct 17, 2018 at 9:23 PM Bartlomiej Zolnierkiewicz
<[email protected]> wrote:
>
> [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 enable and check operations in the core thermal code and
> update thermal drivers accordingly:

The commit message on this patch and patch 4 are identical upto here.
Perhaps consider moving the actual difference in the commit message to
the top and post the TL;DR version below it?

> * 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_set_mode() (only place which calls
> ->set_mode). Modify mode_store() in thermal_sysfs.c accordingly.
>
> There should be no functional changes caused by this patch.
>
> 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/db8500_thermal.c | 2 ++
> drivers/thermal/hisi_thermal.c | 2 ++
> drivers/thermal/imx_thermal.c | 2 --
> drivers/thermal/int340x_thermal/int3400_thermal.c | 1 +
> drivers/thermal/of-thermal.c | 6 +++---
> drivers/thermal/rockchip_thermal.c | 16 ++++++++++++----
> drivers/thermal/thermal_sysfs.c | 3 +++
> include/linux/thermal.h | 2 ++
> 11 files changed, 29 insertions(+), 11 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 b0afd36..5f4b3bd 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
> @@ -170,8 +170,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 5a2b93a..884fd83 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -507,6 +507,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/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 63d4fc3..6151e55 100644
> --- a/drivers/thermal/hisi_thermal.c
> +++ b/drivers/thermal/hisi_thermal.c
> @@ -561,6 +561,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
> }
>
> thermal_zone_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_ENABLED);
> + thermal_zone_device_check((&data->sensor)->tzd);
>
> return 0;
> }
> @@ -570,6 +571,7 @@ static int hisi_thermal_remove(struct platform_device *pdev)
> struct hisi_thermal_data *data = platform_get_drvdata(pdev);
>
> thermal_zone_set_mode((&data->sensor)->tzd, THERMAL_DEVICE_DISABLED);
> + 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 22f57ef..7abad6c 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -385,8 +385,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/of-thermal.c b/drivers/thermal/of-thermal.c
> index c422b08..f1dcb7d 100644
> --- a/drivers/thermal/of-thermal.c
> +++ b/drivers/thermal/of-thermal.c
> @@ -272,8 +272,6 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
>
> data->mode = mode;
>
> - thermal_zone_device_check(tz);
> -
> return 0;
> }
>
> @@ -496,9 +494,11 @@ 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))
> + if (!IS_ERR(tzd)) {
> thermal_zone_set_mode(tzd,
> THERMAL_DEVICE_ENABLED);
> + thermal_zone_device_check(tzd);
> + }

You add this here and then remove it in patch 4. I'm guessing this is
to help with git-bisect. But...

> 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 5640675..715f4cd 100644
> --- a/drivers/thermal/rockchip_thermal.c
> +++ b/drivers/thermal/rockchip_thermal.c
> @@ -1281,9 +1281,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
> THERMAL_DEVICE_ENABLED);
> + thermal_zone_device_check((&thermal->sensors[i])->tzd);
> + }

Similarly, most of patch 4 are about calling set_mode and device_check
after the registration across all drivers. So it seems to be that it
might be easier to just merge these two patches to make it easier to
understand what is happening.

> platform_set_drvdata(pdev, thermal);
>
> @@ -1302,9 +1304,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
> THERMAL_DEVICE_DISABLED);
> + thermal_zone_device_check((&thermal->sensors[i])->tzd);
> + }
>
> thermal->chip->control(thermal->regs, false);
>
> @@ -1320,9 +1324,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
> THERMAL_DEVICE_DISABLED);
> + thermal_zone_device_check((&thermal->sensors[i])->tzd);
> + }
>
> thermal->chip->control(thermal->regs, false);
>
> @@ -1372,9 +1378,11 @@ 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_set_mode((&thermal->sensors[i])->tzd,
> THERMAL_DEVICE_ENABLED);
> + thermal_zone_device_check((&thermal->sensors[i])->tzd);
> + }
>
> pinctrl_pm_select_default_state(dev);
>
> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
> index 3b38fb9..ac39fb6 100644
> --- a/drivers/thermal/thermal_sysfs.c
> +++ b/drivers/thermal/thermal_sysfs.c
> @@ -85,6 +85,9 @@
> if (result)
> return result;
>
> + if (!tz->ops->set_mode_skip_check)
> + thermal_zone_device_check(tz);
> +
> return count;
> }
>
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 3e325b3..92c460e 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -113,6 +113,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
>

2018-10-26 12:40:52

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 08/17] thermal: qcom: tsens: enable+check sensor after its setup is finished

On Fri, Oct 26, 2018 at 5:41 PM Amit Kucheria <[email protected]> wrote:
>
> On Wed, Oct 17, 2018 at 9:24 PM Bartlomiej Zolnierkiewicz
> <[email protected]> wrote:
> >
> > 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 dbd2556..01bff96 100644
> > --- a/drivers/thermal/qcom/tsens.c
> > +++ b/drivers/thermal/qcom/tsens.c
> > @@ -105,13 +105,13 @@ static int tsens_register(struct tsens_device *tmdev)
> > if (IS_ERR(tzd))
> > continue;
> >
> > - thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
> > - thermal_zone_device_check(tzd);
> > -
>
> I don't quite understand why you're making this move explicitly in a
> separate patch for each of the drivers? You added it here in patch 4
> in the first place, why not add it in the correct place there itself?

I think I understand now. You wanted to separate patches causing
functional changes from ones that didn't.

IMHO, it makes the series a bit hard to read but I have no better
suggestion than to squash everything (patches 3-16), but that will
make it harder to collect Acks.

> > tmdev->sensor[i].tzd = tzd;
> >
> > if (tmdev->ops->enable)
> > tmdev->ops->enable(tmdev, i);
> > +
> > + thermal_zone_set_mode(tzd, THERMAL_DEVICE_ENABLED);
> > + thermal_zone_device_check(tzd);
> >
> > }
> > return 0;
> > }
> > --
> > 1.9.1
> >

2018-10-31 12:40:51

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 04/17] thermal: separate sensor registration and enable+check operations

<snip>

> --- a/drivers/hwmon/hwmon.c
> +++ b/drivers/hwmon/hwmon.c
> @@ -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
> diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
> index c52d07c..d423b0f 100644
> --- a/drivers/hwmon/ntc_thermistor.c
> +++ b/drivers/hwmon/ntc_thermistor.c
> @@ -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);
> + }

Use the negative check here as above to get rid of the 'else' statement?

> return 0;
> }
> diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c
> index 111d521..ad5c5d7 100644
> --- a/drivers/hwmon/scpi-hwmon.c
> +++ b/drivers/hwmon/scpi-hwmon.c
> @@ -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);
> + }

Use the negative check here (!IS_ERR(z)) as above to get rid of the
'else' statement? The memory is allocated through devm_kzalloc so it
doesn't need to be explicitly freed.

> }
>
> return 0;
> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
> index 04d7147..ff67f72 100644
> --- a/drivers/iio/adc/sun4i-gpadc-iio.c
> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c
> @@ -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);
> + }
> }

Subject: Re: [PATCH v2 00/17] thermal: enable+check sensor after its setup is finished


On 11/05/2018 04:04 AM, Zhang Rui wrote:
> Hi, Bartlomiej,

Hi Rui,

> Interesting, I'm about to bring this issue to Linux Plumber Conference
> this year for discussion, and I'm also proposing a solution to fix the
> issues, but only with thermal core part finished yet.
> can you please take a look at it?
> https://patchwork.kernel.org/project/linux-pm/list/?series=38181

Thank you for the patches but they seem to be far from being
a complete solution for issues fixed by my patchset. Even
thermal core part is not finished yet as it doesn't provide
a way to register disabled sensors for DT thermal drivers (only
for platform ones)..

Why not simply apply my patchset now and incrementally work
on top of it to implement fixes for issues your patchset is
addressing?

My patchset may not be a perfect solution but IMO it is good
enough and it has been practically ready since v1 posted in
April (v2 fixes all issues requested by Eduardo's review from
September)..

> thanks,
> rui
>
> On 三, 2018-10-17 at 17:52 +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:
>>
>> 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 fix all abovementioned issues sensor registration,
>> enable and check operations are separated in the core DT thermal
>> code and corresponding DT thermal drivers are modified to do sensor
>> setup correctly.
>>
>> Changes since v1:
>> - rebased on the current -next kernel (next-20181015)
>> - enhanced patch descriptions and cover letter
>> - renamed thermal_zone_device_toggler() to thermal_zone_set_mode()
>> - converted thermal_zone_set_mode() to use enum thermal_device_mode
>> - added CONFIG_THERMAL=n stubs for thermal_zone_set_mode() and
>> thermal_zone_device_check()
>> - fixed uses of [devm]_thermal_zone_of_sensor_register() outside of
>> drivers/thermal/
>> - changed ordering between patch #2 and #3 in order to add all
>> needed core helpers first before fixing sensor setup code
>> - changed ordering between patch #3 and #4 in order to simplify them
>> - renamed patch #3 to "thermal: separate sensor enable and check
>> operations"
>> - renamed patch #4 to "thermal: separate sensor registration and
>> enable+check operations"
>>
>> Best regards,
>> --
>> Bartlomiej Zolnierkiewicz
>> Samsung R&D Institute Poland
>> Samsung Electronics
>>
>>
>> Bartlomiej Zolnierkiewicz (17):
>> thermal: add thermal_zone_set_mode() helper
>> thermal: add thermal_zone_device_check() helper
>> thermal: separate sensor enable and check operations
>> thermal: separate sensor registration and enable+check operations
>> 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/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/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
>> drivers/platform/x86/acerhdf.c | 6 +++-
>> drivers/regulator/max8973-regulator.c | 6 ++--
>> 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/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 | 7 ++--
>> drivers/thermal/rockchip_thermal.c | 38 +++++++++++-
>> ----------
>> 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 | 32
>> ++++++++++++++++++
>> 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 | 11 +++++++
>> 44 files changed, 220 insertions(+), 87 deletions(-)

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

2018-11-06 00:47:36

by Eduardo Valentin

[permalink] [raw]
Subject: Re: [PATCH v2 00/17] thermal: enable+check sensor after its setup is finished

Hey,

On Mon, Nov 05, 2018 at 05:35:55PM +0100, Bartlomiej Zolnierkiewicz wrote:
>
> On 11/05/2018 04:04 AM, Zhang Rui wrote:
> > Hi, Bartlomiej,
>
> Hi Rui,
>
> > Interesting, I'm about to bring this issue to Linux Plumber Conference
> > this year for discussion, and I'm also proposing a solution to fix the
> > issues, but only with thermal core part finished yet.
> > can you please take a look at it?
> > https://patchwork.kernel.org/project/linux-pm/list/?series=38181
>
> Thank you for the patches but they seem to be far from being
> a complete solution for issues fixed by my patchset. Even
> thermal core part is not finished yet as it doesn't provide
> a way to register disabled sensors for DT thermal drivers (only
> for platform ones)..
>
> Why not simply apply my patchset now and incrementally work
> on top of it to implement fixes for issues your patchset is
> addressing?
>
> My patchset may not be a perfect solution but IMO it is good
> enough and it has been practically ready since v1 posted in
> April (v2 fixes all issues requested by Eduardo's review from
> September)..

Rui, I agree with Bartlomiej here. I propose to create
a topic branch with both series, Bartlomiej's then yours.

Feels to me that this is a wider change across multiple drivers,
and across driver types, platform and of- based, so might be
better to avoid breakage.



>
> > thanks,
> > rui
> >
> > On 三, 2018-10-17 at 17:52 +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:
> >>
> >> 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 fix all abovementioned issues sensor registration,
> >> enable and check operations are separated in the core DT thermal
> >> code and corresponding DT thermal drivers are modified to do sensor
> >> setup correctly.
> >>
> >> Changes since v1:
> >> - rebased on the current -next kernel (next-20181015)
> >> - enhanced patch descriptions and cover letter
> >> - renamed thermal_zone_device_toggler() to thermal_zone_set_mode()
> >> - converted thermal_zone_set_mode() to use enum thermal_device_mode
> >> - added CONFIG_THERMAL=n stubs for thermal_zone_set_mode() and
> >> thermal_zone_device_check()
> >> - fixed uses of [devm]_thermal_zone_of_sensor_register() outside of
> >> drivers/thermal/
> >> - changed ordering between patch #2 and #3 in order to add all
> >> needed core helpers first before fixing sensor setup code
> >> - changed ordering between patch #3 and #4 in order to simplify them
> >> - renamed patch #3 to "thermal: separate sensor enable and check
> >> operations"
> >> - renamed patch #4 to "thermal: separate sensor registration and
> >> enable+check operations"
> >>
> >> Best regards,
> >> --
> >> Bartlomiej Zolnierkiewicz
> >> Samsung R&D Institute Poland
> >> Samsung Electronics
> >>
> >>
> >> Bartlomiej Zolnierkiewicz (17):
> >> thermal: add thermal_zone_set_mode() helper
> >> thermal: add thermal_zone_device_check() helper
> >> thermal: separate sensor enable and check operations
> >> thermal: separate sensor registration and enable+check operations
> >> 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/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/net/ethernet/mellanox/mlxsw/core_thermal.c | 1 -
> >> drivers/platform/x86/acerhdf.c | 6 +++-
> >> drivers/regulator/max8973-regulator.c | 6 ++--
> >> 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/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 | 7 ++--
> >> drivers/thermal/rockchip_thermal.c | 38 +++++++++++-
> >> ----------
> >> 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 | 32
> >> ++++++++++++++++++
> >> 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 | 11 +++++++
> >> 44 files changed, 220 insertions(+), 87 deletions(-)
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics

2018-11-06 07:35:57

by Zhang, Rui

[permalink] [raw]
Subject: Re: [PATCH v2 00/17] thermal: enable+check sensor after its setup is finished

Hi, Bartlomiej,

On 一, 2018-11-05 at 17:35 +0100, Bartlomiej Zolnierkiewicz wrote:
> On 11/05/2018 04:04 AM, Zhang Rui wrote:
> >
> > Hi, Bartlomiej,
> Hi Rui,
>
> >
> > Interesting, I'm about to bring this issue to Linux Plumber
> > Conference
> > this year for discussion, and I'm also proposing a solution to fix
> > the
> > issues, but only with thermal core part finished yet.
> > can you please take a look at it?
> > https://patchwork.kernel.org/project/linux-pm/list/?series=38181
> Thank you for the patches but they seem to be far from being
> a complete solution for issues fixed by my patchset.

Right, as I said, this is a draft patch to illustrate my idea for those
issues. And it is not targeting for upstream.

> Even
> thermal core part is not finished yet as it doesn't provide
> a way to register disabled sensors for DT thermal drivers (only
> for platform ones)..

we need sequential change of of_thermal to set tzp->disable
in of_parse_thermal_zones.

>
> Why not simply apply my patchset now and incrementally work
> on top of it to implement fixes for issues your patchset is
> addressing?

The main concern is that, as you point out, we have too many private
mode implementation, and I'm looking for the possibility to handle them
in the thermal core framework.

>
> My patchset may not be a perfect solution but IMO it is good
> enough and it has been practically ready since v1 posted in
> April (v2 fixes all issues requested by Eduardo's review from
> September)..

I'm not against doing this, as long as it fixes something and doesn't
break the others.
But, I still have a couple of comments about your patches, and let me
comment in lines.

thanks,
rui
>
> >
> > thanks,
> > rui
> >
> > On 三, 2018-10-17 at 17:52 +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:
> > >
> > >   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 fix all abovementioned issues sensor registration,
> > > enable and check operations are separated in the core DT thermal
> > > code and corresponding DT thermal drivers are modified to do
> > > sensor
> > > setup correctly.
> > >
> > > Changes since v1:
> > > - rebased on the current -next kernel (next-20181015)
> > > - enhanced patch descriptions and cover letter
> > > - renamed thermal_zone_device_toggler() to
> > > thermal_zone_set_mode()
> > > - converted thermal_zone_set_mode() to use enum
> > > thermal_device_mode
> > > - added CONFIG_THERMAL=n stubs for thermal_zone_set_mode() and
> > >   thermal_zone_device_check()
> > > - fixed uses of [devm]_thermal_zone_of_sensor_register() outside
> > > of
> > >   drivers/thermal/
> > > - changed ordering between patch #2 and #3 in order to add all
> > >   needed core helpers first before fixing sensor setup code
> > > - changed ordering between patch #3 and #4 in order to simplify
> > > them
> > > - renamed patch #3 to "thermal: separate sensor enable and check
> > >   operations"
> > > - renamed patch #4 to "thermal: separate sensor registration and
> > >   enable+check operations"
> > >
> > > Best regards,
> > > --
> > > Bartlomiej Zolnierkiewicz
> > > Samsung R&D Institute Poland
> > > Samsung Electronics
> > >
> > >
> > > Bartlomiej Zolnierkiewicz (17):
> > >   thermal: add thermal_zone_set_mode() helper
> > >   thermal: add thermal_zone_device_check() helper
> > >   thermal: separate sensor enable and check operations
> > >   thermal: separate sensor registration and enable+check
> > > operations
> > >   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/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/net/ethernet/mellanox/mlxsw/core_thermal.c |  1 -
> > >  drivers/platform/x86/acerhdf.c                     |  6 +++-
> > >  drivers/regulator/max8973-regulator.c              |  6 ++--
> > >  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/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                     |  7 ++--
> > >  drivers/thermal/rockchip_thermal.c                 | 38
> > > +++++++++++-
> > > ----------
> > >  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                  | 32
> > > ++++++++++++++++++
> > >  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                            | 11 +++++++
> > >  44 files changed, 220 insertions(+), 87 deletions(-)
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics

2018-11-06 08:12:35

by Zhang, Rui

[permalink] [raw]
Subject: Re: [PATCH v2 01/17] thermal: add thermal_zone_set_mode() helper

On 三, 2018-10-17 at 17:52 +0200, Bartlomiej Zolnierkiewicz wrote:
> In order to remove the code duplication and prepare for further
> changes:
>
> * Add thermal_zone_set_mode() helper. Then update core code and
>   drivers to use it.
>
> There should be no functional changes caused by this patch.
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> ---
>  drivers/thermal/hisi_thermal.c     | 14 ++------------
>  drivers/thermal/of-thermal.c       |  3 ++-
>  drivers/thermal/rockchip_thermal.c | 26 +++++++++-----------------
>  drivers/thermal/thermal_helpers.c  | 14 ++++++++++++++
>  drivers/thermal/thermal_sysfs.c    |  8 +++++---
>  include/linux/thermal.h            |  5 +++++
>  6 files changed, 37 insertions(+), 33 deletions(-)
>

>  
> diff --git a/drivers/thermal/thermal_helpers.c
> b/drivers/thermal/thermal_helpers.c
> index 2ba756a..b18cee2 100644
> --- a/drivers/thermal/thermal_helpers.c
> +++ b/drivers/thermal/thermal_helpers.c
> @@ -224,3 +224,17 @@ int thermal_zone_get_offset(struct
> thermal_zone_device *tz)
>   return 0;
>  }
>  EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
> +
> +/**
> + * thermal_zone_set_mode() - sets mode of thermal zone device
> + * @tz: a valid pointer to a struct thermal_zone_device
> + * @mode: mode to be set
> + *
> + * Return: On success returns 0, an error code otherwise.
> + */
> +int thermal_zone_set_mode(struct thermal_zone_device *tz,
> +   enum thermal_device_mode mode)
> +{
> + return tz->ops->set_mode(tz, mode);

better to check tz->ops->set_mode first.

thanks,
rui
> +}
> +EXPORT_SYMBOL_GPL(thermal_zone_set_mode);
> diff --git a/drivers/thermal/thermal_sysfs.c
> b/drivers/thermal/thermal_sysfs.c
> index 2241cea..2e9e762 100644
> --- a/drivers/thermal/thermal_sysfs.c
> +++ b/drivers/thermal/thermal_sysfs.c
> @@ -69,17 +69,19 @@
>  {
>   struct thermal_zone_device *tz = to_thermal_zone(dev);
>   int result;
> + enum thermal_device_mode mode;
>  
>   if (!tz->ops->set_mode)
>   return -EPERM;
>  
>   if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
> - result = tz->ops->set_mode(tz,
> THERMAL_DEVICE_ENABLED);
> + mode = THERMAL_DEVICE_ENABLED;
>   else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
> - result = tz->ops->set_mode(tz,
> THERMAL_DEVICE_DISABLED);
> + mode = THERMAL_DEVICE_DISABLED;
>   else
> - result = -EINVAL;
> + return -EINVAL;
>  
> + result = thermal_zone_set_mode(tz, mode);
>   if (result)
>   return result;
>  
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 5f4705f..9d21fd1 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -452,6 +452,8 @@ 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_set_mode(struct thermal_zone_device *tz,
> +   enum thermal_device_mode mode);
>  
>  int get_tz_trend(struct thermal_zone_device *, int);
>  struct thermal_instance *get_thermal_instance(struct
> thermal_zone_device *,
> @@ -518,6 +520,9 @@ static inline int thermal_zone_get_slope(
>  static inline int thermal_zone_get_offset(
>   struct thermal_zone_device *tz)
>  { return -ENODEV; }
> +static inline int thermal_zone_set_mode(
> + struct thermal_zone_device *tz, enum
> thermal_device_mode mode)
> +{ return -ENODEV; }
>  static inline int get_tz_trend(struct thermal_zone_device *tz, int
> trip)
>  { return -ENODEV; }
>  static inline struct thermal_instance *

Subject: Re: [PATCH v2 01/17] thermal: add thermal_zone_set_mode() helper


On 11/06/2018 09:11 AM, Zhang Rui wrote:
> On 三, 2018-10-17 at 17:52 +0200, Bartlomiej Zolnierkiewicz wrote:
>> In order to remove the code duplication and prepare for further
>> changes:
>>
>> * Add thermal_zone_set_mode() helper. Then update core code and
>> drivers to use it.
>>
>> There should be no functional changes caused by this patch.
>>
>> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
>> ---
>> drivers/thermal/hisi_thermal.c | 14 ++------------
>> drivers/thermal/of-thermal.c | 3 ++-
>> drivers/thermal/rockchip_thermal.c | 26 +++++++++-----------------
>> drivers/thermal/thermal_helpers.c | 14 ++++++++++++++
>> drivers/thermal/thermal_sysfs.c | 8 +++++---
>> include/linux/thermal.h | 5 +++++
>> 6 files changed, 37 insertions(+), 33 deletions(-)
>>
>>
>>
>> diff --git a/drivers/thermal/thermal_helpers.c
>> b/drivers/thermal/thermal_helpers.c
>> index 2ba756a..b18cee2 100644
>> --- a/drivers/thermal/thermal_helpers.c
>> +++ b/drivers/thermal/thermal_helpers.c
>> @@ -224,3 +224,17 @@ int thermal_zone_get_offset(struct
>> thermal_zone_device *tz)
>> return 0;
>> }
>> EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
>> +
>> +/**
>> + * thermal_zone_set_mode() - sets mode of thermal zone device
>> + * @tz: a valid pointer to a struct thermal_zone_device
>> + * @mode: mode to be set
>> + *
>> + * Return: On success returns 0, an error code otherwise.
>> + */
>> +int thermal_zone_set_mode(struct thermal_zone_device *tz,
>> + enum thermal_device_mode mode)
>> +{
>> + return tz->ops->set_mode(tz, mode);
>
> better to check tz->ops->set_mode first.

I think that it should be added incrementally later when needed.

We don't do 'defensive coding' in the kernel and in this patchset
thermal_zone_set_mode() is not used in any place which has not used
->set_mode directly previously (actually patches #1-4 should not
cause any functionality changes as noted in patch descriptions).

> thanks,
> rui
>> +}
>> +EXPORT_SYMBOL_GPL(thermal_zone_set_mode);
>> diff --git a/drivers/thermal/thermal_sysfs.c
>> b/drivers/thermal/thermal_sysfs.c
>> index 2241cea..2e9e762 100644
>> --- a/drivers/thermal/thermal_sysfs.c
>> +++ b/drivers/thermal/thermal_sysfs.c
>> @@ -69,17 +69,19 @@
>> {
>> struct thermal_zone_device *tz = to_thermal_zone(dev);
>> int result;
>> + enum thermal_device_mode mode;
>>
>> if (!tz->ops->set_mode)
>> return -EPERM;
>>
>> if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
>> - result = tz->ops->set_mode(tz,
>> THERMAL_DEVICE_ENABLED);
>> + mode = THERMAL_DEVICE_ENABLED;
>> else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
>> - result = tz->ops->set_mode(tz,
>> THERMAL_DEVICE_DISABLED);
>> + mode = THERMAL_DEVICE_DISABLED;
>> else
>> - result = -EINVAL;
>> + return -EINVAL;
>>
>> + result = thermal_zone_set_mode(tz, mode);
>> if (result)
>> return result;
>>
>> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>> index 5f4705f..9d21fd1 100644
>> --- a/include/linux/thermal.h
>> +++ b/include/linux/thermal.h
>> @@ -452,6 +452,8 @@ 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_set_mode(struct thermal_zone_device *tz,
>> + enum thermal_device_mode mode);
>>
>> int get_tz_trend(struct thermal_zone_device *, int);
>> struct thermal_instance *get_thermal_instance(struct
>> thermal_zone_device *,
>> @@ -518,6 +520,9 @@ static inline int thermal_zone_get_slope(
>> static inline int thermal_zone_get_offset(
>> struct thermal_zone_device *tz)
>> { return -ENODEV; }
>> +static inline int thermal_zone_set_mode(
>> + struct thermal_zone_device *tz, enum
>> thermal_device_mode mode)
>> +{ return -ENODEV; }
>> static inline int get_tz_trend(struct thermal_zone_device *tz, int
>> trip)
>> { return -ENODEV; }
>> static inline struct thermal_instance *

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics