From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Leo Yan <leo.yan@linaro.org>,
Eduardo Valentin <edubezval@gmail.com>,
Rafael David Tinoco <rafael.tinoco@linaro.org>
Subject: [PATCH 4.14 52/55] thermal/drivers/hisi: Remove costly sensor inspection
Date: Thu, 6 Dec 2018 15:39:26 +0100 [thread overview]
Message-ID: <20181206143004.548910244@linuxfoundation.org> (raw)
In-Reply-To: <20181206143001.749982936@linuxfoundation.org>
4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Lezcano <daniel.lezcano@linaro.org>
commit 10d7e9a9181f4637640f388d334c6740c1b5d0e8 upstream.
The sensor is all setup, bind, resetted, acked, etc... every single second.
That was the way to workaround a problem with the interrupt bouncing again and
again.
With the following changes, we fix all in one:
- Do the setup, one time, at probe time
- Add the IRQF_ONESHOT, ack the interrupt in the threaded handler
- Remove the interrupt handler
- Set the correct value for the LAG register
- Remove all the irq_enabled stuff in the code as the interruption
handling is fixed
- Remove the 3ms delay
- Reorder the initialization routine to be in the right order
It ends up to a nicer code and more efficient, the 3-5ms delay is removed from
the get_temp() path.
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: Rafael David Tinoco <rafael.tinoco@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/thermal/hisi_thermal.c | 205 ++++++++++++++++++-----------------------
1 file changed, 94 insertions(+), 111 deletions(-)
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -41,6 +41,7 @@
#define HISI_TEMP_BASE (-60000)
#define HISI_TEMP_RESET (100000)
#define HISI_TEMP_STEP (784)
+#define HISI_TEMP_LAG (3500)
#define HISI_MAX_SENSORS 4
#define HISI_DEFAULT_SENSOR 2
@@ -60,8 +61,6 @@ struct hisi_thermal_data {
struct clk *clk;
struct hisi_thermal_sensor sensors;
int irq;
- bool irq_enabled;
-
void __iomem *regs;
};
@@ -99,9 +98,40 @@ static inline long hisi_thermal_round_te
hisi_thermal_temp_to_step(temp));
}
+/*
+ * The lag register contains 5 bits encoding the temperature in steps.
+ *
+ * Each time the temperature crosses the threshold boundary, an
+ * interrupt is raised. It could be when the temperature is going
+ * above the threshold or below. However, if the temperature is
+ * fluctuating around this value due to the load, we can receive
+ * several interrupts which may not desired.
+ *
+ * We can setup a temperature representing the delta between the
+ * threshold and the current temperature when the temperature is
+ * decreasing.
+ *
+ * For instance: the lag register is 5°C, the threshold is 65°C, when
+ * the temperature reaches 65°C an interrupt is raised and when the
+ * temperature decrease to 65°C - 5°C another interrupt is raised.
+ *
+ * A very short lag can lead to an interrupt storm, a long lag
+ * increase the latency to react to the temperature changes. In our
+ * case, that is not really a problem as we are polling the
+ * temperature.
+ *
+ * [0:4] : lag register
+ *
+ * The temperature is coded in steps, cf. HISI_TEMP_STEP.
+ *
+ * Min : 0x00 : 0.0 °C
+ * Max : 0x1F : 24.3 °C
+ *
+ * The 'value' parameter is in milliCelsius.
+ */
static inline void hisi_thermal_set_lag(void __iomem *addr, int value)
{
- writel(value, addr + TEMP0_LAG);
+ writel((value / HISI_TEMP_STEP) & 0x1F, addr + TEMP0_LAG);
}
static inline void hisi_thermal_alarm_clear(void __iomem *addr, int value)
@@ -171,71 +201,6 @@ static inline void hisi_thermal_hdak_set
(value << 4), addr + TEMP0_CFG);
}
-static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data,
- struct hisi_thermal_sensor *sensor)
-{
- long val;
-
- mutex_lock(&data->thermal_lock);
-
- /* disable interrupt */
- hisi_thermal_alarm_enable(data->regs, 0);
- hisi_thermal_alarm_clear(data->regs, 1);
-
- /* disable module firstly */
- hisi_thermal_enable(data->regs, 0);
-
- /* select sensor id */
- hisi_thermal_sensor_select(data->regs, sensor->id);
-
- /* enable module */
- hisi_thermal_enable(data->regs, 1);
-
- usleep_range(3000, 5000);
-
- val = hisi_thermal_get_temperature(data->regs);
-
- mutex_unlock(&data->thermal_lock);
-
- return val;
-}
-
-static void hisi_thermal_enable_bind_irq_sensor
- (struct hisi_thermal_data *data)
-{
- struct hisi_thermal_sensor *sensor;
-
- mutex_lock(&data->thermal_lock);
-
- sensor = &data->sensors;
-
- /* setting the hdak time */
- hisi_thermal_hdak_set(data->regs, 0);
-
- /* disable module firstly */
- hisi_thermal_reset_enable(data->regs, 0);
- hisi_thermal_enable(data->regs, 0);
-
- /* select sensor id */
- hisi_thermal_sensor_select(data->regs, sensor->id);
-
- /* enable for interrupt */
- hisi_thermal_alarm_set(data->regs, sensor->thres_temp);
-
- hisi_thermal_reset_set(data->regs, HISI_TEMP_RESET);
-
- /* enable module */
- hisi_thermal_reset_enable(data->regs, 1);
- hisi_thermal_enable(data->regs, 1);
-
- hisi_thermal_alarm_clear(data->regs, 0);
- hisi_thermal_alarm_enable(data->regs, 1);
-
- usleep_range(3000, 5000);
-
- mutex_unlock(&data->thermal_lock);
-}
-
static void hisi_thermal_disable_sensor(struct hisi_thermal_data *data)
{
mutex_lock(&data->thermal_lock);
@@ -253,25 +218,10 @@ static int hisi_thermal_get_temp(void *_
struct hisi_thermal_sensor *sensor = _sensor;
struct hisi_thermal_data *data = sensor->thermal;
- *temp = hisi_thermal_get_sensor_temp(data, sensor);
+ *temp = hisi_thermal_get_temperature(data->regs);
- dev_dbg(&data->pdev->dev, "id=%d, irq=%d, temp=%d, thres=%d\n",
- sensor->id, data->irq_enabled, *temp, sensor->thres_temp);
- /*
- * Bind irq to sensor for two cases:
- * Reenable alarm IRQ if temperature below threshold;
- * if irq has been enabled, always set it;
- */
- if (data->irq_enabled) {
- hisi_thermal_enable_bind_irq_sensor(data);
- return 0;
- }
-
- if (*temp < sensor->thres_temp) {
- data->irq_enabled = true;
- hisi_thermal_enable_bind_irq_sensor(data);
- enable_irq(data->irq);
- }
+ dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n",
+ sensor->id, *temp, sensor->thres_temp);
return 0;
}
@@ -280,26 +230,27 @@ static const struct thermal_zone_of_devi
.get_temp = hisi_thermal_get_temp,
};
-static irqreturn_t hisi_thermal_alarm_irq(int irq, void *dev)
-{
- struct hisi_thermal_data *data = dev;
-
- disable_irq_nosync(irq);
- data->irq_enabled = false;
-
- return IRQ_WAKE_THREAD;
-}
-
static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
{
struct hisi_thermal_data *data = dev;
struct hisi_thermal_sensor *sensor = &data->sensors;
+ int temp;
- dev_crit(&data->pdev->dev, "THERMAL ALARM: T > %d\n",
- sensor->thres_temp);
+ hisi_thermal_alarm_clear(data->regs, 1);
- thermal_zone_device_update(data->sensors.tzd,
- THERMAL_EVENT_UNSPECIFIED);
+ temp = hisi_thermal_get_temperature(data->regs);
+
+ if (temp >= sensor->thres_temp) {
+ dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n",
+ temp, sensor->thres_temp);
+
+ thermal_zone_device_update(data->sensors.tzd,
+ THERMAL_EVENT_UNSPECIFIED);
+
+ } else if (temp < sensor->thres_temp) {
+ dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n",
+ temp, sensor->thres_temp);
+ }
return IRQ_HANDLED;
}
@@ -352,6 +303,40 @@ static void hisi_thermal_toggle_sensor(s
on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
}
+static int hisi_thermal_setup(struct hisi_thermal_data *data)
+{
+ struct hisi_thermal_sensor *sensor;
+
+ sensor = &data->sensors;
+
+ /* disable module firstly */
+ hisi_thermal_reset_enable(data->regs, 0);
+ hisi_thermal_enable(data->regs, 0);
+
+ /* select sensor id */
+ hisi_thermal_sensor_select(data->regs, sensor->id);
+
+ /* setting the hdak time */
+ hisi_thermal_hdak_set(data->regs, 0);
+
+ /* setting lag value between current temp and the threshold */
+ hisi_thermal_set_lag(data->regs, HISI_TEMP_LAG);
+
+ /* enable for interrupt */
+ hisi_thermal_alarm_set(data->regs, sensor->thres_temp);
+
+ hisi_thermal_reset_set(data->regs, HISI_TEMP_RESET);
+
+ /* enable module */
+ hisi_thermal_reset_enable(data->regs, 1);
+ hisi_thermal_enable(data->regs, 1);
+
+ hisi_thermal_alarm_clear(data->regs, 0);
+ hisi_thermal_alarm_enable(data->regs, 1);
+
+ return 0;
+}
+
static int hisi_thermal_probe(struct platform_device *pdev)
{
struct hisi_thermal_data *data;
@@ -394,9 +379,6 @@ static int hisi_thermal_probe(struct pla
return ret;
}
- hisi_thermal_enable_bind_irq_sensor(data);
- data->irq_enabled = true;
-
ret = hisi_thermal_register_sensor(pdev, data,
&data->sensors,
HISI_DEFAULT_SENSOR);
@@ -406,10 +388,15 @@ static int hisi_thermal_probe(struct pla
return ret;
}
- ret = devm_request_threaded_irq(&pdev->dev, data->irq,
- hisi_thermal_alarm_irq,
+ ret = hisi_thermal_setup(data);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to setup the sensor: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, data->irq, NULL,
hisi_thermal_alarm_irq_thread,
- 0, "hisi_thermal", data);
+ IRQF_ONESHOT, "hisi_thermal", data);
if (ret < 0) {
dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
return ret;
@@ -417,8 +404,6 @@ static int hisi_thermal_probe(struct pla
hisi_thermal_toggle_sensor(&data->sensors, true);
- enable_irq(data->irq);
-
return 0;
}
@@ -440,7 +425,6 @@ static int hisi_thermal_suspend(struct d
struct hisi_thermal_data *data = dev_get_drvdata(dev);
hisi_thermal_disable_sensor(data);
- data->irq_enabled = false;
clk_disable_unprepare(data->clk);
@@ -456,8 +440,7 @@ static int hisi_thermal_resume(struct de
if (ret)
return ret;
- data->irq_enabled = true;
- hisi_thermal_enable_bind_irq_sensor(data);
+ hisi_thermal_setup(data);
return 0;
}
next prev parent reply other threads:[~2018-12-06 14:43 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-06 14:38 [PATCH 4.14 00/55] 4.14.87-stable review Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 01/55] Kbuild: suppress packed-not-aligned warning for default setting only Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 02/55] disable stringop truncation warnings for now Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 03/55] test_hexdump: use memcpy instead of strncpy Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 04/55] kobject: Replace strncpy with memcpy Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 05/55] ALSA: intel_hdmi: Use strlcpy() instead of strncpy() Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 06/55] unifdef: use memcpy instead of strncpy Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 07/55] kernfs: Replace strncpy with memcpy Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 08/55] ip_tunnel: Fix name string concatenate in __ip_tunnel_create() Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 09/55] drm: gma500: fix logic error Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 10/55] scsi: bfa: convert to strlcpy/strlcat Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 11/55] staging: rts5208: fix gcc-8 logic error warning Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 12/55] kdb: use memmove instead of overlapping memcpy Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 13/55] iser: set sector for ambiguous mr status errors Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 14/55] uprobes: Fix handle_swbp() vs. unregister() + register() race once more Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 15/55] MIPS: ralink: Fix mt7620 nd_sd pinmux Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 16/55] mips: fix mips_get_syscall_arg o32 check Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 17/55] IB/mlx5: Avoid load failure due to unknown link width Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 18/55] drm/ast: Fix incorrect free on ioregs Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 19/55] drm: set is_master to 0 upon drm_new_set_master() failure Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 20/55] drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 21/55] drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut() Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 22/55] userfaultfd: use ENOENT instead of EFAULT if the atomic copy user fails Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 23/55] userfaultfd: shmem: allocate anonymous memory for MAP_PRIVATE shmem Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 24/55] userfaultfd: shmem: add i_size checks Greg Kroah-Hartman
2018-12-06 14:38 ` [PATCH 4.14 25/55] userfaultfd: shmem: UFFDIO_COPY: set the page dirty if VM_WRITE is not set Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 26/55] scsi: scsi_devinfo: cleanly zero-pad devinfo strings Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 27/55] userfaultfd: shmem/hugetlbfs: only allow to register VM_MAYWRITE vmas Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 28/55] ALSA: trident: Suppress gcc string warning Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 29/55] kgdboc: Fix restrict error Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 30/55] kgdboc: Fix warning with module build Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 31/55] svm: Add mutex_lock to protect apic_access_page_done on AMD systems Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 32/55] drm/msm: fix OF child-node lookup Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 33/55] Input: xpad - quirk all PDP Xbox One gamepads Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 34/55] Input: synaptics - add PNP ID for ThinkPad P50 to SMBus Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 35/55] Input: matrix_keypad - check for errors from of_get_named_gpio() Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 36/55] Input: cros_ec_keyb - fix button/switch capability reports Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 37/55] Input: elan_i2c - add ELAN0620 to the ACPI table Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 38/55] Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15ARR Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 39/55] Input: elan_i2c - add support for ELAN0621 touchpad Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 40/55] btrfs: tree-checker: Dont check max block group size as current max chunk size limit is unreliable Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 41/55] btrfs: Always try all copies when reading extent buffers Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 42/55] ARC: change defconfig defaults to ARCv2 Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 43/55] arc: [devboards] Add support of NFSv3 ACL Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 44/55] udf: Allow mounting volumes with incorrect identification strings Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 45/55] reset: make device_reset_optional() really optional Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 46/55] reset: remove remaining WARN_ON() in <linux/reset.h> Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 47/55] mm: cleancache: fix corruption on missed inode invalidation Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 48/55] thermal/drivers/hisi: Remove the multiple sensors support Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 49/55] thermal/drivers/hisi: Remove pointless lock Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 50/55] thermal/drivers/hisi: Encapsulate register writes into helpers Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 51/55] thermal/drivers/hisi: Fix configuration register setting Greg Kroah-Hartman
2018-12-06 14:39 ` Greg Kroah-Hartman [this message]
2018-12-06 14:39 ` [PATCH 4.14 53/55] mm: hide incomplete nr_indirectly_reclaimable in /proc/zoneinfo Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 54/55] net: qed: use correct strncpy() size Greg Kroah-Hartman
2018-12-06 14:39 ` [PATCH 4.14 55/55] tipc: use destination length for copy string Greg Kroah-Hartman
2018-12-06 20:12 ` [PATCH 4.14 00/55] 4.14.87-stable review kernelci.org bot
2018-12-06 22:09 ` shuah
2018-12-07 8:39 ` Naresh Kamboju
2018-12-07 9:33 ` Jon Hunter
2018-12-07 20:30 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181206143004.548910244@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=daniel.lezcano@linaro.org \
--cc=edubezval@gmail.com \
--cc=leo.yan@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rafael.tinoco@linaro.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).