+++ /dev/null
-From db2b0332608c8e648ea1e44727d36ad37cdb56cb Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Thu, 19 Oct 2017 19:05:47 +0200
-Subject: thermal/drivers/hisi: Fix multiple alarm interrupts firing
-
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-
-commit db2b0332608c8e648ea1e44727d36ad37cdb56cb upstream.
-
-The DT specifies a threshold of 65000, we setup the register with a value in
-the temperature resolution for the controller, 64656.
-
-When we reach 64656, the interrupt fires, the interrupt is disabled. Then the
-irq thread runs and calls thermal_zone_device_update() which will call in turn
-hisi_thermal_get_temp().
-
-The function will look if the temperature decreased, assuming it was more than
-65000, but that is not the case because the current temperature is 64656
-(because of the rounding when setting the threshold). This condition being
-true, we re-enable the interrupt which fires immediately after exiting the irq
-thread. That happens again and again until the temperature goes to more than
-65000.
-
-Potentially, there is here an interrupt storm if the temperature stabilizes at
-this temperature. A very unlikely case but possible.
-
-In any case, it does not make sense to handle dozens of alarm interrupt for
-nothing.
-
-Fix this by rounding the threshold value to the controller resolution so the
-check against the threshold is consistent with the one set in the controller.
-
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Reviewed-by: Leo Yan <leo.yan@linaro.org>
-Tested-by: Leo Yan <leo.yan@linaro.org>
-Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
-Signed-off-by: Kevin Wangtao <kevin.wangtao@hisilicon.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/thermal/hisi_thermal.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/drivers/thermal/hisi_thermal.c
-+++ b/drivers/thermal/hisi_thermal.c
-@@ -76,6 +76,12 @@ static inline long _temp_to_step(long te
- return ((temp / 1000 - HISI_TEMP_BASE) * 255 / 200);
- }
-
-+static inline long hisi_thermal_round_temp(int temp)
-+{
-+ return hisi_thermal_step_to_temp(
-+ hisi_thermal_temp_to_step(temp));
-+}
-+
- static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data,
- struct hisi_thermal_sensor *sensor)
- {
-@@ -223,7 +229,7 @@ static irqreturn_t hisi_thermal_alarm_ir
- sensor = &data->sensors[data->irq_bind_sensor];
-
- dev_crit(&data->pdev->dev, "THERMAL ALARM: T > %d\n",
-- sensor->thres_temp / 1000);
-+ sensor->thres_temp);
- mutex_unlock(&data->thermal_lock);
-
- for (i = 0; i < HISI_MAX_SENSORS; i++)
-@@ -256,7 +262,7 @@ static int hisi_thermal_register_sensor(
-
- for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) {
- if (trip[i].type == THERMAL_TRIP_PASSIVE) {
-- sensor->thres_temp = trip[i].temperature;
-+ sensor->thres_temp = hisi_thermal_round_temp(trip[i].temperature);
- break;
- }
- }