From cbd8c5aae2a988bafd4586bea710eeddc30a82ce Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 6 Jul 2023 11:37:32 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Handle IRQ on all controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a single IRQ handler for each LVTS thermal domain, and it is supposed to check each of its underlying controllers for the origin of the interrupt and clear its status. However due to a typo, only the first controller was ever being handled, which resulted in the interrupt never being cleared when it happened on the other controllers. Add the missing index so interrupts are handled for all controllers. Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver") Reviewed-by: Matthias Brugger Reviewed-by: AngeloGioacchino Del Regno Tested-by: Chen-Yu Tsai Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230706153823.201943-2-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 054c965ae5e1..4ec09cb8f667 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -451,7 +451,7 @@ static irqreturn_t lvts_irq_handler(int irq, void *data) for (i = 0; i < lvts_td->num_lvts_ctrl; i++) { - aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl); + aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]); if (aux != IRQ_HANDLED) continue; -- cgit v1.2.3 From 64de162e34e4cb2982a1d96e492f018026a61c1d Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 6 Jul 2023 11:37:33 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Honor sensors in immediate mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each controller can be configured to operate on immediate or filtered mode. On filtered mode, the sensors are enabled by setting the corresponding bits in MONCTL0, while on immediate mode, by setting MSRCTL1. Previously, the code would set MSRCTL1 for all four sensors when configured to immediate mode, but given that the controller might not have all four sensors connected, this would cause interrupts to trigger for non-existent sensors. Fix this by handling the MSRCTL1 register analogously to the MONCTL0: only enable the sensors that were declared. Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver") Reviewed-by: AngeloGioacchino Del Regno Tested-by: Chen-Yu Tsai Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230706153823.201943-3-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 57 +++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 4ec09cb8f667..92f4784bb98c 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -896,24 +896,6 @@ static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl) LVTS_HW_FILTER << 3 | LVTS_HW_FILTER; writel(value, LVTS_MSRCTL0(lvts_ctrl->base)); - /* - * LVTS_MSRCTL1 : Measurement control - * - * Bits: - * - * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3 - * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2 - * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1 - * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0 - * - * That configuration will ignore the filtering and the delays - * introduced below in MONCTL1 and MONCTL2 - */ - if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) { - value = BIT(9) | BIT(6) | BIT(5) | BIT(4); - writel(value, LVTS_MSRCTL1(lvts_ctrl->base)); - } - /* * LVTS_MONCTL1 : Period unit and group interval configuration * @@ -979,6 +961,15 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl) struct thermal_zone_device *tz; u32 sensor_map = 0; int i; + /* + * Bitmaps to enable each sensor on immediate and filtered modes, as + * described in MSRCTL1 and MONCTL0 registers below, respectively. + */ + u32 sensor_imm_bitmap[] = { BIT(4), BIT(5), BIT(6), BIT(9) }; + u32 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) }; + + u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ? + sensor_imm_bitmap : sensor_filt_bitmap; for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) { @@ -1016,20 +1007,38 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl) * map, so we can enable the temperature monitoring in * the hardware thermal controller. */ - sensor_map |= BIT(i); + sensor_map |= sensor_bitmap[i]; } /* - * Bits: - * 9: Single point access flow - * 0-3: Enable sensing point 0-3 - * * The initialization of the thermal zones give us * which sensor point to enable. If any thermal zone * was not described in the device tree, it won't be * enabled here in the sensor map. */ - writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base)); + if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) { + /* + * LVTS_MSRCTL1 : Measurement control + * + * Bits: + * + * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3 + * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2 + * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1 + * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0 + * + * That configuration will ignore the filtering and the delays + * introduced in MONCTL1 and MONCTL2 + */ + writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base)); + } else { + /* + * Bits: + * 9: Single point access flow + * 0-3: Enable sensing point 0-3 + */ + writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base)); + } return 0; } -- cgit v1.2.3 From f79e996c7ed27bb196facbcd1c69ee33631d7051 Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 6 Jul 2023 11:37:34 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Use offset threshold for IRQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two kinds of temperature monitoring interrupts available: * High Offset, Low Offset * Hot, Hot to normal, Cold The code currently uses the hot/h2n/cold interrupts, however in a way that doesn't work: the cold threshold is left uninitialized, which prevents the other thresholds from ever triggering, and the h2n interrupt is used as the lower threshold, which prevents the hot interrupt from triggering again after the thresholds are updated by the thermal framework, since a hot interrupt can only trigger again after the hot to normal interrupt has been triggered. But better yet than addressing those issues, is to use the high/low offset interrupts instead. This way only two thresholds need to be managed, which have a simpler state machine, making them a better match to the thermal framework's high and low thresholds. Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230706153823.201943-4-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 92f4784bb98c..978316a45060 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -298,9 +298,9 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) u32 raw_high = lvts_temp_to_raw(high); /* - * Hot to normal temperature threshold + * Low offset temperature threshold * - * LVTS_H2NTHRE + * LVTS_OFFSETL * * Bits: * @@ -309,13 +309,13 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) if (low != -INT_MAX) { pr_debug("%s: Setting low limit temperature interrupt: %d\n", thermal_zone_device_type(tz), low); - writel(raw_low, LVTS_H2NTHRE(base)); + writel(raw_low, LVTS_OFFSETL(base)); } /* - * Hot temperature threshold + * High offset temperature threshold * - * LVTS_HTHRE + * LVTS_OFFSETH * * Bits: * @@ -323,7 +323,7 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) */ pr_debug("%s: Setting high limit temperature interrupt: %d\n", thermal_zone_device_type(tz), high); - writel(raw_high, LVTS_HTHRE(base)); + writel(raw_high, LVTS_OFFSETH(base)); return 0; } -- cgit v1.2.3 From 487bf099e85b724c824f5fafaf93c6749c4d2120 Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 6 Jul 2023 11:37:35 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Disable undesired interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out of the many interrupts supported by the hardware, the only ones of interest to the driver currently are: * The temperature went over the high offset threshold, for any of the sensors * The temperature went below the low offset threshold, for any of the sensors * The temperature went over the stage3 threshold These are the only thresholds configured by the driver through the OFFSETH, OFFSETL, and PROTTC registers, respectively. The current interrupt mask in LVTS_MONINT_CONF, enables many more interrupts, including data ready on sensors for both filtered and immediate mode. These are not only not handled by the driver, but they are also triggered too often, causing unneeded overhead. Disable these unnecessary interrupts. The meaning of each bit can be seen in the comment describing LVTS_MONINTST in the IRQ handler. Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Alexandre Mergnat Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230706153823.201943-5-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 978316a45060..72c848f9de4c 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -65,7 +65,7 @@ #define LVTS_HW_FILTER 0x2 #define LVTS_TSSEL_CONF 0x13121110 #define LVTS_CALSCALE_CONF 0x300 -#define LVTS_MONINT_CONF 0x9FBF7BDE +#define LVTS_MONINT_CONF 0x8300318C #define LVTS_INT_SENSOR0 0x0009001F #define LVTS_INT_SENSOR1 0x001203E0 -- cgit v1.2.3 From 77354eaef8218bc40d6b37e783b0b8dcca22a7d9 Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 6 Jul 2023 11:37:36 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Don't leave threshold zeroed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The thermal framework might leave the low threshold unset if there aren't any lower trip points. This leaves the register zeroed, which translates to a very high temperature for the low threshold. The interrupt for this threshold is then immediately triggered, and the state machine gets stuck, preventing any other temperature monitoring interrupts to ever trigger. (The same happens by not setting the Cold or Hot to Normal thresholds when using those) Set the unused threshold to a valid low value. This value was chosen so that for any valid golden temperature read from the efuse, when the value is converted to raw and back again to milliCelsius, the result doesn't underflow. Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230706153823.201943-6-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 72c848f9de4c..1ad93a778c9d 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -83,6 +83,8 @@ #define LVTS_HW_SHUTDOWN_MT8195 105000 +#define LVTS_MINIMUM_THRESHOLD 20000 + static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT; static int coeff_b = LVTS_COEFF_B; @@ -294,7 +296,7 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) { struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); void __iomem *base = lvts_sensor->base; - u32 raw_low = lvts_temp_to_raw(low); + u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD); u32 raw_high = lvts_temp_to_raw(high); /* @@ -306,11 +308,9 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) * * 14-0 : Raw temperature for threshold */ - if (low != -INT_MAX) { - pr_debug("%s: Setting low limit temperature interrupt: %d\n", - thermal_zone_device_type(tz), low); - writel(raw_low, LVTS_OFFSETL(base)); - } + pr_debug("%s: Setting low limit temperature interrupt: %d\n", + thermal_zone_device_type(tz), low); + writel(raw_low, LVTS_OFFSETL(base)); /* * High offset temperature threshold -- cgit v1.2.3 From 2bba1acf7a4cbe62abbb4c686e0414209ec5943b Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 6 Jul 2023 11:37:37 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Manage threshold between sensors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each LVTS thermal controller can have up to four sensors, each capable of triggering its own interrupt when its measured temperature crosses the configured threshold. The threshold for each sensor is handled separately by the thermal framework, since each one is registered with its own thermal zone and trips. However, the temperature thresholds are configured on the controller, and therefore are shared between all sensors on that controller. When the temperature measured by the sensors is different enough to cause the thermal framework to configure different thresholds for each one, interrupts start triggering on sensors outside the last threshold configured. To address the issue, track the thresholds required by each sensor and only actually set the highest one in the hardware, and disable interrupts for all sensors outside the current configured range. Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230706153823.201943-7-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 1ad93a778c9d..61c3de44c40b 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -67,6 +67,11 @@ #define LVTS_CALSCALE_CONF 0x300 #define LVTS_MONINT_CONF 0x8300318C +#define LVTS_MONINT_OFFSET_SENSOR0 0xC +#define LVTS_MONINT_OFFSET_SENSOR1 0x180 +#define LVTS_MONINT_OFFSET_SENSOR2 0x3000 +#define LVTS_MONINT_OFFSET_SENSOR3 0x3000000 + #define LVTS_INT_SENSOR0 0x0009001F #define LVTS_INT_SENSOR1 0x001203E0 #define LVTS_INT_SENSOR2 0x00247C00 @@ -112,6 +117,8 @@ struct lvts_sensor { void __iomem *base; int id; int dt_id; + int low_thresh; + int high_thresh; }; struct lvts_ctrl { @@ -121,6 +128,8 @@ struct lvts_ctrl { int num_lvts_sensor; int mode; void __iomem *base; + int low_thresh; + int high_thresh; }; struct lvts_domain { @@ -292,12 +301,66 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) return 0; } +static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl) +{ + u32 masks[] = { + LVTS_MONINT_OFFSET_SENSOR0, + LVTS_MONINT_OFFSET_SENSOR1, + LVTS_MONINT_OFFSET_SENSOR2, + LVTS_MONINT_OFFSET_SENSOR3, + }; + u32 value = 0; + int i; + + value = readl(LVTS_MONINT(lvts_ctrl->base)); + + for (i = 0; i < ARRAY_SIZE(masks); i++) { + if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh + && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) + value |= masks[i]; + else + value &= ~masks[i]; + } + + writel(value, LVTS_MONINT(lvts_ctrl->base)); +} + +static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high) +{ + int i; + + if (high > lvts_ctrl->high_thresh) + return true; + + for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) + if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh + && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) + return false; + + return true; +} + static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) { struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); + struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]); void __iomem *base = lvts_sensor->base; u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD); u32 raw_high = lvts_temp_to_raw(high); + bool should_update_thresh; + + lvts_sensor->low_thresh = low; + lvts_sensor->high_thresh = high; + + should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high); + if (should_update_thresh) { + lvts_ctrl->high_thresh = high; + lvts_ctrl->low_thresh = low; + } + lvts_update_irq_mask(lvts_ctrl); + + if (!should_update_thresh) + return 0; /* * Low offset temperature threshold @@ -521,6 +584,9 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl, */ lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ? imm_regs[i] : msr_regs[i]; + + lvts_sensor[i].low_thresh = INT_MIN; + lvts_sensor[i].high_thresh = INT_MIN; }; lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor; @@ -688,6 +754,9 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td, */ lvts_ctrl[i].hw_tshut_raw_temp = lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp); + + lvts_ctrl[i].low_thresh = INT_MIN; + lvts_ctrl[i].high_thresh = INT_MIN; } /* -- cgit v1.2.3 From 19ad9f29751ca385262c63f513f75610962c40a0 Mon Sep 17 00:00:00 2001 From: Minjie Du Date: Thu, 13 Jul 2023 12:24:12 +0800 Subject: thermal/drivers/mediatek/lvts: Fix parameter check in lvts_debugfs_init() The documentation says "If an error occurs, ERR_PTR(-ERROR) will be returned" but the current code checks against a NULL pointer returned. Fix this by checking if IS_ERR(). Signed-off-by: Minjie Du Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230713042413.2519-1-duminjie@vivo.com --- drivers/thermal/mediatek/lvts_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 61c3de44c40b..bc726ac0a672 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -201,7 +201,7 @@ static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td) int i; lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL); - if (!lvts_td->dom_dentry) + if (IS_ERR(lvts_td->dom_dentry)) return 0; for (i = 0; i < lvts_td->num_lvts_ctrl; i++) { -- cgit v1.2.3 From 4afcb58ea47e66c025d2b0a5f091dce5aaf95b0f Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Sat, 8 Jul 2023 13:26:46 +0200 Subject: thermal/drivers/imx8mm: Suppress log message on probe deferral nvmem_cell_read_u32() may return -EPROBE_DEFER if NVMEM supplier has not yet been probed. Future reprobe may succeed, so printing: i.mx8mm_thermal 30260000.tmu: Failed to read OCOTP nvmem cell (-517). to the log is confusing. Fix this by using dev_err_probe. This also elevates the message from warning to error, which is more correct: The log message is only ever printed in probe error path and probe aborts afterwards, so it really warrants an error-level message. Fixes: 403291648823 ("thermal/drivers/imx: Add support for loading calibration data from OCOTP") Signed-off-by: Ahmad Fatoum Reviewed-by: Marek Vasut Reviewed-by: Peng Fan Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230708112647.2897294-1-a.fatoum@pengutronix.de --- drivers/thermal/imx8mm_thermal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c index e89b11b3f2b9..14111ccf6e4c 100644 --- a/drivers/thermal/imx8mm_thermal.c +++ b/drivers/thermal/imx8mm_thermal.c @@ -178,10 +178,8 @@ static int imx8mm_tmu_probe_set_calib_v1(struct platform_device *pdev, int ret; ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0); - if (ret) { - dev_warn(dev, "Failed to read OCOTP nvmem cell (%d).\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to read OCOTP nvmem cell\n"); writel(FIELD_PREP(TASR_BUF_VREF_MASK, FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) | -- cgit v1.2.3 From 02cf5bcbd0a0283ecc13cceceeb43de45d79c85e Mon Sep 17 00:00:00 2001 From: Min-Hua Chen Date: Fri, 14 Jul 2023 00:04:14 +0800 Subject: thermal/drivers/tsens: Make tsens_xxxx_nvmem static This patch fixes the following sparse warnings: drivers/thermal/qcom/tsens-v1.c:24:40: sparse: warning: symbol 'tsens_qcs404_nvmem' was not declared. Should it be static? drivers/thermal/qcom/tsens-v0_1.c:26:40: sparse: warning: symbol 'tsens_8916_nvmem' was not declared. Should it be static? drivers/thermal/qcom/tsens-v0_1.c:42:40: sparse: warning: symbol 'tsens_8974_nvmem' was not declared. Should it be static? drivers/thermal/qcom/tsens-v0_1.c:64:40: sparse: warning: symbol 'tsens_8974_backup_nvmem' was not declared. Should it be static? No functional change intended. Signed-off-by: Min-Hua Chen Reviewed-by: Dmitry Baryshkov Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230713160415.149381-1-minhuadotchen@gmail.com --- drivers/thermal/qcom/tsens-v0_1.c | 6 +++--- drivers/thermal/qcom/tsens-v1.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index a941b4241b0a..87c09f62ee81 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -23,7 +23,7 @@ #define BIT_APPEND 0x3 -struct tsens_legacy_calibration_format tsens_8916_nvmem = { +static struct tsens_legacy_calibration_format tsens_8916_nvmem = { .base_len = 7, .base_shift = 3, .sp_len = 5, @@ -39,7 +39,7 @@ struct tsens_legacy_calibration_format tsens_8916_nvmem = { }, }; -struct tsens_legacy_calibration_format tsens_8974_nvmem = { +static struct tsens_legacy_calibration_format tsens_8974_nvmem = { .base_len = 8, .base_shift = 2, .sp_len = 6, @@ -61,7 +61,7 @@ struct tsens_legacy_calibration_format tsens_8974_nvmem = { }, }; -struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = { +static struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = { .base_len = 8, .base_shift = 2, .sp_len = 6, diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 51322430f1fe..dc1c4ae2d8b0 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -21,7 +21,7 @@ #define TM_HIGH_LOW_INT_STATUS_OFF 0x0088 #define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090 -struct tsens_legacy_calibration_format tsens_qcs404_nvmem = { +static struct tsens_legacy_calibration_format tsens_qcs404_nvmem = { .base_len = 8, .base_shift = 2, .sp_len = 6, -- cgit v1.2.3 From f664a6b5a9740ae5f4a8c36d01ba0752a1f4a0e0 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 26 Jun 2023 20:55:15 +0800 Subject: thermal/drivers/sun8i: Remove unneeded comments It's redundant, let's remove it. Signed-off-by: Yangtao Li Acked-by: Jernej Skrabec Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230626125515.18830-1-frank.li@vivo.com --- drivers/thermal/sun8i_thermal.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index cca16d632d9f..c38d5f1f212d 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -56,8 +56,6 @@ #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12) #define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x) -/* millidegree celsius */ - struct tsensor { struct ths_device *tmdev; struct thermal_zone_device *tzd; -- cgit v1.2.3 From c51592a95f360aabf2b8a5691c550e1749dc41eb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 19 Jul 2023 01:58:54 +0100 Subject: thermal/drivers/sun8i: Free calibration nvmem after reading it The sun8i thermal driver reads calibration data via the nvmem API at startup, updating the device configuration and not referencing the data again. Rather than explicitly freeing the nvmem data the driver relies on devm_ to release it, even though the data is never referenced again. The allocation is still tracked so it's not leaked but this is notable when looking at the code and is a little wasteful so let's instead explicitly free the nvmem after we're done with it. Signed-off-by: Mark Brown Acked-by: Jernej Skrabec Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230719-thermal-sun8i-free-nvmem-v1-1-f553d5afef79@kernel.org --- drivers/thermal/sun8i_thermal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index c38d5f1f212d..702d4d4faaed 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -284,7 +284,7 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) size_t callen; int ret = 0; - calcell = devm_nvmem_cell_get(dev, "calibration"); + calcell = nvmem_cell_get(dev, "calibration"); if (IS_ERR(calcell)) { if (PTR_ERR(calcell) == -EPROBE_DEFER) return -EPROBE_DEFER; @@ -314,6 +314,8 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) kfree(caldata); out: + if (!IS_ERR(calcell)) + nvmem_cell_put(calcell); return ret; } -- cgit v1.2.3 From e9b1de73b7ca31f487e4f4f063a5b70aeb707863 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 2 Aug 2023 17:45:27 +0800 Subject: thermal/drivers/mediatek: Clean up redundant dev_err_probe() Referring to platform_get_irq()'s definition, the return value has already been checked if ret < 0, and printed via dev_err_probe(). Calling dev_err_probe() one more time outside platform_get_irq() is obviously redundant. Removing dev_err_probe() outside platform_get_irq() to clean up above problem. Signed-off-by: Chen Jiahao Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230802094527.988842-1-chenjiahao16@huawei.com --- drivers/thermal/mediatek/lvts_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index bc726ac0a672..f4709ae842a2 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -1216,7 +1216,7 @@ static int lvts_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) - return dev_err_probe(dev, irq, "No irq resource\n"); + return irq; ret = lvts_domain_init(dev, lvts_td, lvts_data); if (ret) -- cgit v1.2.3 From c39300c47d9195928fc1145f789fb0f36e471779 Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Wed, 9 Aug 2023 18:14:39 +0800 Subject: thermal/drivers/db8500: Remove redundant of_match_ptr() The driver depends on CONFIG_OF, it is not necessary to use of_match_ptr() here. Signed-off-by: Ruan Jinjie Reviewed-by: Linus Walleij Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230809101439.2663042-1-ruanjinjie@huawei.com --- drivers/thermal/db8500_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c index fca5c2c93bf9..576f88b6a1b3 100644 --- a/drivers/thermal/db8500_thermal.c +++ b/drivers/thermal/db8500_thermal.c @@ -229,7 +229,7 @@ MODULE_DEVICE_TABLE(of, db8500_thermal_match); static struct platform_driver db8500_thermal_driver = { .driver = { .name = "db8500-thermal", - .of_match_table = of_match_ptr(db8500_thermal_match), + .of_match_table = db8500_thermal_match, }, .probe = db8500_thermal_probe, .suspend = db8500_thermal_suspend, -- cgit v1.2.3 From 1892f9f01cd0cf163d2a2ee182d60d61e9d95be0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Aug 2023 11:13:18 +0200 Subject: thermal/drivers/samsung: Fix Wvoid-pointer-to-enum-cast warning 'soc' is an enum, thus cast of pointer on 64-bit compile test with W=1 causes: exynos_tmu.c:890:14: error: cast to smaller integer type 'enum soc_type' from 'const void *' [-Werror,-Wvoid-pointer-to-enum-cast] Signed-off-by: Krzysztof Kozlowski Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230810091318.70261-1-krzysztof.kozlowski@linaro.org --- drivers/thermal/samsung/exynos_tmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 58f4d8f7a3fd..e5bc2c82010f 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -887,7 +887,7 @@ static int exynos_map_dt_data(struct platform_device *pdev) return -EADDRNOTAVAIL; } - data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); + data->soc = (uintptr_t)of_device_get_match_data(&pdev->dev); switch (data->soc) { case SOC_ARCH_EXYNOS4210: -- cgit v1.2.3 From 1c73c3be9cc83ad1340897fe45adf1d11c418678 Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Thu, 10 Aug 2023 14:13:30 +0300 Subject: thermal/drivers/broadcom/sr-thermal: Removed call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230810111330.3248-1-aboutphysycs@gmail.com --- drivers/thermal/broadcom/sr-thermal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/broadcom/sr-thermal.c b/drivers/thermal/broadcom/sr-thermal.c index 747915890022..9a29dfd4c7fe 100644 --- a/drivers/thermal/broadcom/sr-thermal.c +++ b/drivers/thermal/broadcom/sr-thermal.c @@ -91,7 +91,6 @@ static int sr_thermal_probe(struct platform_device *pdev) dev_dbg(dev, "thermal sensor %d registered\n", i); } - platform_set_drvdata(pdev, sr_thermal); return 0; } -- cgit v1.2.3 From e51c521692362d7c32a28fbce21f88f703013a12 Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Thu, 10 Aug 2023 14:20:15 +0300 Subject: thermal/drivers/k3_j72xx_bandgap: Removed unneeded call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230810112015.3578-1-aboutphysycs@gmail.com --- drivers/thermal/k3_j72xx_bandgap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c index a5a0fc9b9356..2fc799b07b90 100644 --- a/drivers/thermal/k3_j72xx_bandgap.c +++ b/drivers/thermal/k3_j72xx_bandgap.c @@ -502,8 +502,6 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) writel(K3_VTM_ANYMAXT_OUTRG_ALERT_EN, data[0].bgp->cfg2_base + K3_VTM_MISC_CTRL_OFFSET); - platform_set_drvdata(pdev, bgp); - print_look_up_table(dev, ref_table); /* * Now that the derived_table has the appropriate look up values -- cgit v1.2.3 From 3ee1f79426acb77ff131be025963fe223ad2ee02 Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Thu, 10 Aug 2023 14:23:44 +0300 Subject: thermal/drivers/k3_bandgap: Remove unneeded call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230810112344.3806-1-aboutphysycs@gmail.com --- drivers/thermal/k3_bandgap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/k3_bandgap.c b/drivers/thermal/k3_bandgap.c index 68f59b3735d3..4a918c1e92f9 100644 --- a/drivers/thermal/k3_bandgap.c +++ b/drivers/thermal/k3_bandgap.c @@ -225,7 +225,6 @@ static int k3_bandgap_probe(struct platform_device *pdev) devm_thermal_add_hwmon_sysfs(dev, data[id].tzd); } - platform_set_drvdata(pdev, bgp); return 0; -- cgit v1.2.3 From 185673ca71d3f7e9c7d62ee5084348e084352e56 Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 13 Jul 2023 11:42:37 -0400 Subject: thermal/drivers/mediatek/lvts_thermal: Make readings valid in filtered mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, when a controller is configured to use filtered mode, thermal readings are valid only about 30% of the time. Upon testing, it was noticed that lowering any of the interval settings resulted in an improved rate of valid data. The same was observed when decreasing the number of samples for each sensor (which also results in quicker measurements). Retrying the read with a timeout longer than the time it takes to resample (about 344us with these settings and 4 sensors) also improves the rate. Lower all timing settings to the minimum, configure the filtering to single sample, and poll the measurement register for at least one period to improve the data validity on filtered mode. With these changes in place, out of 100000 reads, a single one failed, ie 99.999% of the data was valid. Reviewed-by: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230713154743.611870-1-nfraprado@collabora.com --- drivers/thermal/mediatek/lvts_thermal.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index f4709ae842a2..effd9b00a424 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -58,11 +58,11 @@ #define LVTS_PROTTC(__base) (__base + 0x00CC) #define LVTS_CLKEN(__base) (__base + 0x00E4) -#define LVTS_PERIOD_UNIT ((118 * 1000) / (256 * 38)) -#define LVTS_GROUP_INTERVAL 1 -#define LVTS_FILTER_INTERVAL 1 -#define LVTS_SENSOR_INTERVAL 1 -#define LVTS_HW_FILTER 0x2 +#define LVTS_PERIOD_UNIT 0 +#define LVTS_GROUP_INTERVAL 0 +#define LVTS_FILTER_INTERVAL 0 +#define LVTS_SENSOR_INTERVAL 0 +#define LVTS_HW_FILTER 0x0 #define LVTS_TSSEL_CONF 0x13121110 #define LVTS_CALSCALE_CONF 0x300 #define LVTS_MONINT_CONF 0x8300318C @@ -86,6 +86,9 @@ #define LVTS_MSR_IMMEDIATE_MODE 0 #define LVTS_MSR_FILTERED_MODE 1 +#define LVTS_MSR_READ_TIMEOUT_US 400 +#define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2) + #define LVTS_HW_SHUTDOWN_MT8195 105000 #define LVTS_MINIMUM_THRESHOLD 20000 @@ -268,6 +271,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); void __iomem *msr = lvts_sensor->msr; u32 value; + int rc; /* * Measurement registers: @@ -280,7 +284,8 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) * 16 : Valid temperature * 15-0 : Raw temperature */ - value = readl(msr); + rc = readl_poll_timeout(msr, value, value & BIT(16), + LVTS_MSR_READ_WAIT_US, LVTS_MSR_READ_TIMEOUT_US); /* * As the thermal zone temperature will read before the @@ -293,7 +298,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) * functionning temperature and directly jump to a system * shutdown. */ - if (!(value & BIT(16))) + if (rc) return -EAGAIN; *temp = lvts_raw_to_temp(value & 0xFFFF); -- cgit v1.2.3 From fb6ce327d6ad382d46b30fa79cae763d5bc457ae Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Wed, 9 Aug 2023 18:48:13 +0300 Subject: thermal/drivers/broadcom/brcstb_thermal: Removed unneeded platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Reviewed-by: Florian Fainelli Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230809154813.16033-1-aboutphysycs@gmail.com --- drivers/thermal/broadcom/brcmstb_thermal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c index 0b73abdaa792..9674e5ffcfa2 100644 --- a/drivers/thermal/broadcom/brcmstb_thermal.c +++ b/drivers/thermal/broadcom/brcmstb_thermal.c @@ -334,7 +334,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) return PTR_ERR(priv->tmon_base); priv->dev = &pdev->dev; - platform_set_drvdata(pdev, priv); of_ops = priv->temp_params->of_ops; thermal = devm_thermal_of_zone_register(&pdev->dev, 0, priv, -- cgit v1.2.3 From f4636b5587842042d883d6ab646289baabba9c5a Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Fri, 11 Aug 2023 22:40:32 +0300 Subject: thermal/drivers/sun8i_thermal: Remove unneeded call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Jernej Skrabec Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230811194032.4240-1-aboutphysycs@gmail.com --- drivers/thermal/sun8i_thermal.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index 702d4d4faaed..f989b55a8aa8 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -489,8 +489,6 @@ static int sun8i_ths_probe(struct platform_device *pdev) if (!tmdev->chip) return -EINVAL; - platform_set_drvdata(pdev, tmdev); - ret = sun8i_ths_resource_init(tmdev); if (ret) return ret; -- cgit v1.2.3 From ec6a51927ed3596e16aae0ad9f5762ecaa2af656 Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Fri, 11 Aug 2023 22:28:47 +0300 Subject: thermal/drivers/mediatek/auxadc_thermal: Removed call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230811192847.3838-1-aboutphysycs@gmail.com --- drivers/thermal/mediatek/auxadc_thermal.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c index c537aed71017..843214d30bd8 100644 --- a/drivers/thermal/mediatek/auxadc_thermal.c +++ b/drivers/thermal/mediatek/auxadc_thermal.c @@ -1282,8 +1282,6 @@ static int mtk_thermal_probe(struct platform_device *pdev) mtk_thermal_init_bank(mt, i, apmixed_phys_base, auxadc_phys_base, ctrl_id); - platform_set_drvdata(pdev, mt); - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, &mtk_thermal_ops); if (IS_ERR(tzdev)) -- cgit v1.2.3 From 72449b3a21b9c5ffd6db2607d33d5e6b0cd85062 Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Fri, 11 Aug 2023 22:15:48 +0300 Subject: thermal/drivers/max77620_thermal: Removed unneeded call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230811191548.3340-1-aboutphysycs@gmail.com --- drivers/thermal/max77620_thermal.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c index 61c7622d9945..919b6ee208d8 100644 --- a/drivers/thermal/max77620_thermal.c +++ b/drivers/thermal/max77620_thermal.c @@ -139,8 +139,6 @@ static int max77620_thermal_probe(struct platform_device *pdev) return ret; } - platform_set_drvdata(pdev, mtherm); - return 0; } -- cgit v1.2.3 From 01c2180b7099aac7902472a2204562397592782f Mon Sep 17 00:00:00 2001 From: Andrei Coardos Date: Mon, 14 Aug 2023 21:09:21 +0300 Subject: thermal/drivers/generic-adc: Removed unneeded call to platform_set_drvdata() This function call was found to be unnecessary as there is no equivalent platform_get_drvdata() call to access the private data of the driver. Also, the private data is defined in this driver, so there is no risk of it being accessed outside of this driver file. Signed-off-by: Andrei Coardos Reviewed-by: Alexandru Ardelean Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230814180921.3336-1-aboutphysycs@gmail.com --- drivers/thermal/thermal-generic-adc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index f4f1a04f8c0f..1717e4a19dcb 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -142,7 +142,6 @@ static int gadc_thermal_probe(struct platform_device *pdev) return ret; gti->dev = &pdev->dev; - platform_set_drvdata(pdev, gti); gti->tz_dev = devm_thermal_of_zone_register(&pdev->dev, 0, gti, &gadc_thermal_ops); -- cgit v1.2.3 From e98153a8c60a91b54fe9193bb9d51080f948e7c1 Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Thu, 17 Aug 2023 09:49:00 +0800 Subject: thermal/drivers/ti-soc-thermal: Use helper function IS_ERR_OR_NULL() Use IS_ERR_OR_NULL() to detect an error pointer or a null pointer open-coding to simplify the code. Signed-off-by: Li Zetao Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230817014900.3094512-1-lizetao1@huawei.com --- drivers/thermal/ti-soc-thermal/ti-bandgap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c index a1c9a1530183..0c2eb9c6e58b 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c @@ -314,7 +314,7 @@ int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t) */ static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id) { - if (!bgp || IS_ERR(bgp)) { + if (IS_ERR_OR_NULL(bgp)) { pr_err("%s: invalid bandgap pointer\n", __func__); return -EINVAL; } -- cgit v1.2.3 From e7e3a7c35791fe7a70997883fb8ada5866a40f4d Mon Sep 17 00:00:00 2001 From: Yinbo Zhu Date: Thu, 17 Aug 2023 10:10:06 +0800 Subject: thermal/drivers/loongson-2: Add thermal management support This patch adds the support for Loongson-2 thermal sensor controller, which can support maximum four sensor selectors that corresponding to four sets of thermal control registers and one set of sampling register. The sensor selector can selector a speific thermal sensor as temperature input. The sampling register is used to obtain the temperature in real time, the control register GATE field is used to set the threshold of high or low temperature, when the input temperature is higher than the high temperature threshold or lower than the low temperature threshold, an interrupt will occur. Signed-off-by: zhanghongchen Signed-off-by: Yinbo Zhu Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230817021007.10350-1-zhuyinbo@loongson.cn --- MAINTAINERS | 7 ++ drivers/thermal/Kconfig | 12 +++ drivers/thermal/Makefile | 1 + drivers/thermal/loongson2_thermal.c | 169 ++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 drivers/thermal/loongson2_thermal.c diff --git a/MAINTAINERS b/MAINTAINERS index d516295978a4..5474397d1d18 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12285,6 +12285,13 @@ S: Maintained F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml F: drivers/pinctrl/pinctrl-loongson2.c +LOONGSON-2 SOC SERIES THERMAL DRIVER +M: zhanghongchen +M: Yinbo Zhu +L: linux-pm@vger.kernel.org +S: Maintained +F: drivers/thermal/loongson2_thermal.c + LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) M: Sathya Prakash M: Sreekanth Reddy diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 19a4b33cb564..c81a00fbca7d 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -510,4 +510,16 @@ config KHADAS_MCU_FAN_THERMAL If you say yes here you get support for the FAN controlled by the Microcontroller found on the Khadas VIM boards. +config LOONGSON2_THERMAL + tristate "Loongson-2 SoC series thermal driver" + depends on LOONGARCH || COMPILE_TEST + depends on OF + help + Support for Thermal driver found on Loongson-2 SoC series platforms. + The thermal driver realizes get_temp and set_trips function, which + are used to obtain the temperature of the current node and set the + temperature range to trigger the interrupt. When the input temperature + is higher than the high temperature threshold or lower than the low + temperature threshold, the interrupt will occur. + endif diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 058664bc3ec0..c934cab309ae 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -63,3 +63,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o +obj-$(CONFIG_LOONGSON2_THERMAL) += loongson2_thermal.o diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c new file mode 100644 index 000000000000..133098dc0854 --- /dev/null +++ b/drivers/thermal/loongson2_thermal.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Author: zhanghongchen + * Yinbo Zhu + * Copyright (C) 2022-2023 Loongson Technology Corporation Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "thermal_hwmon.h" + +#define LOONGSON2_MAX_SENSOR_SEL_NUM 3 + +#define LOONGSON2_THSENS_CTRL_HI_REG 0x0 +#define LOONGSON2_THSENS_CTRL_LOW_REG 0x8 +#define LOONGSON2_THSENS_STATUS_REG 0x10 +#define LOONGSON2_THSENS_OUT_REG 0x14 + +#define LOONGSON2_THSENS_INT_LO BIT(0) +#define LOONGSON2_THSENS_INT_HIGH BIT(1) +#define LOONGSON2_THSENS_OUT_MASK 0xFF + +struct loongson2_thermal_chip_data { + unsigned int thermal_sensor_sel; +}; + +struct loongson2_thermal_data { + void __iomem *regs; + const struct loongson2_thermal_chip_data *chip_data; +}; + +static int loongson2_thermal_set(struct loongson2_thermal_data *data, + int low, int high, bool enable) +{ + u64 reg_ctrl = 0; + int reg_off = data->chip_data->thermal_sensor_sel * 2; + + low = clamp(-40, low, high); + high = clamp(125, low, high); + + low += HECTO; + high += HECTO; + + reg_ctrl = low; + reg_ctrl |= enable ? 0x100 : 0; + writew(reg_ctrl, data->regs + LOONGSON2_THSENS_CTRL_LOW_REG + reg_off); + + reg_ctrl = high; + reg_ctrl |= enable ? 0x100 : 0; + writew(reg_ctrl, data->regs + LOONGSON2_THSENS_CTRL_HI_REG + reg_off); + + return 0; +} + +static int loongson2_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +{ + u32 reg_val; + struct loongson2_thermal_data *data = thermal_zone_device_priv(tz); + + reg_val = readl(data->regs + LOONGSON2_THSENS_OUT_REG); + *temp = ((reg_val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO; + + return 0; +} + +static irqreturn_t loongson2_thermal_irq_thread(int irq, void *dev) +{ + struct thermal_zone_device *tzd = dev; + struct loongson2_thermal_data *data = thermal_zone_device_priv(tzd); + + writeb(LOONGSON2_THSENS_INT_LO | LOONGSON2_THSENS_INT_HIGH, data->regs + + LOONGSON2_THSENS_STATUS_REG); + + thermal_zone_device_update(tzd, THERMAL_EVENT_UNSPECIFIED); + + return IRQ_HANDLED; +} + +static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) +{ + struct loongson2_thermal_data *data = thermal_zone_device_priv(tz); + + return loongson2_thermal_set(data, low/MILLI, high/MILLI, true); +} + +static const struct thermal_zone_device_ops loongson2_of_thermal_ops = { + .get_temp = loongson2_thermal_get_temp, + .set_trips = loongson2_thermal_set_trips, +}; + +static int loongson2_thermal_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct loongson2_thermal_data *data; + struct thermal_zone_device *tzd; + int ret, irq, i; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->chip_data = device_get_match_data(dev); + + data->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->regs)) + return PTR_ERR(data->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + writeb(LOONGSON2_THSENS_INT_LO | LOONGSON2_THSENS_INT_HIGH, data->regs + + LOONGSON2_THSENS_STATUS_REG); + + loongson2_thermal_set(data, 0, 0, false); + + for (i = 0; i <= LOONGSON2_MAX_SENSOR_SEL_NUM; i++) { + tzd = devm_thermal_of_zone_register(dev, i, data, + &loongson2_of_thermal_ops); + + if (!IS_ERR(tzd)) + break; + + if (PTR_ERR(tzd) != ENODEV) + continue; + + return dev_err_probe(dev, PTR_ERR(tzd), "failed to register"); + } + + ret = devm_request_threaded_irq(dev, irq, NULL, loongson2_thermal_irq_thread, + IRQF_ONESHOT, "loongson2_thermal", tzd); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to request alarm irq\n"); + + devm_thermal_add_hwmon_sysfs(dev, tzd); + + return 0; +} + +static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = { + .thermal_sensor_sel = 0, +}; + +static const struct of_device_id of_loongson2_thermal_match[] = { + { + .compatible = "loongson,ls2k1000-thermal", + .data = &loongson2_thermal_ls2k1000_data, + }, + { /* end */ } +}; +MODULE_DEVICE_TABLE(of, of_loongson2_thermal_match); + +static struct platform_driver loongson2_thermal_driver = { + .driver = { + .name = "loongson2_thermal", + .of_match_table = of_loongson2_thermal_match, + }, + .probe = loongson2_thermal_probe, +}; +module_platform_driver(loongson2_thermal_driver); + +MODULE_DESCRIPTION("Loongson2 thermal driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 72684d99a854e3f78568a895ebf5365f646aa869 Mon Sep 17 00:00:00 2001 From: Yinbo Zhu Date: Thu, 17 Aug 2023 10:10:07 +0800 Subject: thermal: dt-bindings: add loongson-2 thermal Add the Loongson-2 thermal binding with DT schema format using json-schema. Signed-off-by: Yinbo Zhu Reviewed-by: Krzysztof Kozlowski Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230817021007.10350-2-zhuyinbo@loongson.cn --- .../bindings/thermal/loongson,ls2k-thermal.yaml | 44 ++++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml diff --git a/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml b/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml new file mode 100644 index 000000000000..7538469997f9 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/loongson,ls2k-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Thermal sensors on Loongson-2 SoCs + +maintainers: + - zhanghongchen + - Yinbo Zhu + +properties: + compatible: + oneOf: + - enum: + - loongson,ls2k1000-thermal + - items: + - enum: + - loongson,ls2k2000-thermal + - const: loongson,ls2k1000-thermal + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + thermal: thermal-sensor@1fe01500 { + compatible = "loongson,ls2k1000-thermal"; + reg = <0x1fe01500 0x30>; + interrupt-parent = <&liointc0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 5474397d1d18..7e2afad35106 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12290,6 +12290,7 @@ M: zhanghongchen M: Yinbo Zhu L: linux-pm@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml F: drivers/thermal/loongson2_thermal.c LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) -- cgit v1.2.3 From 1ef5a9f61457b921158ef03f3a2b3e789b41be9f Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 29 Nov 2022 17:39:14 +0200 Subject: thermal/drivers/tegra-bpmp: Check if BPMP supports trip points Check if BPMP supports thermal trip points, and if not, do not expose the .set_trips callback to the thermal core framework. This can happen in virtualized environments where asynchronous communication with VM BPMP drivers is not available. Signed-off-by: Mikko Perttunen Acked-by: Thierry Reding Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221129153914.2699041-1-cyndis@kapsi.fi --- drivers/thermal/tegra/tegra-bpmp-thermal.c | 52 +++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/tegra/tegra-bpmp-thermal.c b/drivers/thermal/tegra/tegra-bpmp-thermal.c index a2879d624945..4ffc3bb3bf35 100644 --- a/drivers/thermal/tegra/tegra-bpmp-thermal.c +++ b/drivers/thermal/tegra/tegra-bpmp-thermal.c @@ -167,19 +167,69 @@ static int tegra_bpmp_thermal_get_num_zones(struct tegra_bpmp *bpmp, return 0; } +static int tegra_bpmp_thermal_trips_supported(struct tegra_bpmp *bpmp, bool *supported) +{ + struct mrq_thermal_host_to_bpmp_request req; + union mrq_thermal_bpmp_to_host_response reply; + struct tegra_bpmp_message msg; + int err; + + memset(&req, 0, sizeof(req)); + req.type = CMD_THERMAL_QUERY_ABI; + req.query_abi.type = CMD_THERMAL_SET_TRIP; + + memset(&msg, 0, sizeof(msg)); + msg.mrq = MRQ_THERMAL; + msg.tx.data = &req; + msg.tx.size = sizeof(req); + msg.rx.data = &reply; + msg.rx.size = sizeof(reply); + + err = tegra_bpmp_transfer(bpmp, &msg); + if (err) + return err; + + if (msg.rx.ret == 0) { + *supported = true; + return 0; + } else if (msg.rx.ret == -BPMP_ENODEV) { + *supported = false; + return 0; + } else { + return -EINVAL; + } +} + static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops = { .get_temp = tegra_bpmp_thermal_get_temp, .set_trips = tegra_bpmp_thermal_set_trips, }; +static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops_notrips = { + .get_temp = tegra_bpmp_thermal_get_temp, +}; + static int tegra_bpmp_thermal_probe(struct platform_device *pdev) { struct tegra_bpmp *bpmp = dev_get_drvdata(pdev->dev.parent); + const struct thermal_zone_device_ops *thermal_ops; struct tegra_bpmp_thermal *tegra; struct thermal_zone_device *tzd; unsigned int i, max_num_zones; + bool supported; int err; + err = tegra_bpmp_thermal_trips_supported(bpmp, &supported); + if (err) { + dev_err(&pdev->dev, "failed to determine if trip points are supported\n"); + return err; + } + + if (supported) + thermal_ops = &tegra_bpmp_of_thermal_ops; + else + thermal_ops = &tegra_bpmp_of_thermal_ops_notrips; + tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); if (!tegra) return -ENOMEM; @@ -222,7 +272,7 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev) } tzd = devm_thermal_of_zone_register( - &pdev->dev, i, zone, &tegra_bpmp_of_thermal_ops); + &pdev->dev, i, zone, thermal_ops); if (IS_ERR(tzd)) { if (PTR_ERR(tzd) == -EPROBE_DEFER) return -EPROBE_DEFER; -- cgit v1.2.3 From 35d8dbbb25add265a880ab0dc48a229f06b08325 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 29 Aug 2023 20:46:31 +0200 Subject: thermal: core: Drop unused .get_trip_*() callbacks After recent changes in the ACPI thermal driver and in the Intel DTS IOSF thermal driver, all thermal zone drivers are expected to use trip tables for initialization and none of them should implement .get_trip_type(), .get_trip_temp() or .get_trip_hyst() callbacks, so drop these callbacks entirely from the core. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 2 +- drivers/thermal/thermal_trip.c | 24 +++--------------------- include/linux/thermal.h | 4 ---- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index a59700593d32..0bdde1ab5d8b 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1266,7 +1266,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t return ERR_PTR(-EINVAL); } - if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp) && !trips) + if (num_trips > 0 && !trips) return ERR_PTR(-EINVAL); if (!thermal_class) diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 53115cfdfd42..024e2e365a26 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -101,29 +101,11 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip) { - int ret; - - if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip) + if (!tz || !tz->trips || trip_id < 0 || trip_id >= tz->num_trips || !trip) return -EINVAL; - if (tz->trips) { - *trip = tz->trips[trip_id]; - return 0; - } - - if (tz->ops->get_trip_hyst) { - ret = tz->ops->get_trip_hyst(tz, trip_id, &trip->hysteresis); - if (ret) - return ret; - } else { - trip->hysteresis = 0; - } - - ret = tz->ops->get_trip_temp(tz, trip_id, &trip->temperature); - if (ret) - return ret; - - return tz->ops->get_trip_type(tz, trip_id, &trip->type); + *trip = tz->trips[trip_id]; + return 0; } EXPORT_SYMBOL_GPL(__thermal_zone_get_trip); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index b449a46766f5..e6bd3b7c9eda 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -62,11 +62,7 @@ struct thermal_zone_device_ops { int (*set_trips) (struct thermal_zone_device *, int, int); int (*change_mode) (struct thermal_zone_device *, enum thermal_device_mode); - int (*get_trip_type) (struct thermal_zone_device *, int, - enum thermal_trip_type *); - int (*get_trip_temp) (struct thermal_zone_device *, int, int *); int (*set_trip_temp) (struct thermal_zone_device *, int, int); - int (*get_trip_hyst) (struct thermal_zone_device *, int, int *); int (*set_trip_hyst) (struct thermal_zone_device *, int, int); int (*get_crit_temp) (struct thermal_zone_device *, int *); int (*set_emul_temp) (struct thermal_zone_device *, int); -- cgit v1.2.3 From 8289d810ea85755a9d22f75785806cb34eecd5e5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 22 Aug 2023 13:40:06 +0200 Subject: thermal: core: Rework .get_trend() thermal zone callback Passing a struct thermal_trip pointer instead of a trip index to the .get_trend() thermal zone callback allows one of its 2 implementations, the thermal_get_trend() function in the ACPI thermal driver, to be simplified quite a bit, and the other implementation of it in the ti-soc-thermal driver does not even use the relevant callback argument. For this reason, change the .get_trend() thermal zone callback definition and adjust the related code accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 41 ++++++++++------------ drivers/thermal/thermal_core.h | 2 +- drivers/thermal/thermal_helpers.c | 3 +- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 3 +- include/linux/thermal.h | 30 ++++++++-------- 5 files changed, 38 insertions(+), 41 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 419590f41ed5..f14e68266ccd 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -492,26 +492,22 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) } static int thermal_get_trend(struct thermal_zone_device *thermal, - int trip_index, enum thermal_trend *trend) + struct thermal_trip *trip, + enum thermal_trend *trend) { struct acpi_thermal *tz = thermal_zone_device_priv(thermal); struct acpi_thermal_trip *acpi_trip; - int t, i; + int t; - if (!tz || trip_index < 0) + if (!tz || !trip) return -EINVAL; - if (tz->trips.critical.valid) - trip_index--; - - if (tz->trips.hot.valid) - trip_index--; - - if (trip_index < 0) + acpi_trip = trip->priv; + if (!acpi_trip || !acpi_trip->valid) return -EINVAL; - acpi_trip = &tz->trips.passive.trip; - if (acpi_trip->valid && !trip_index--) { + switch (trip->type) { + case THERMAL_TRIP_PASSIVE: t = tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature) + tz->trips.passive.tc2 * (tz->temperature - @@ -524,19 +520,18 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, *trend = THERMAL_TREND_STABLE; return 0; - } - - t = acpi_thermal_temp(tz, tz->temperature); - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - acpi_trip = &tz->trips.active[i].trip; - if (acpi_trip->valid && !trip_index--) { - if (t > acpi_thermal_temp(tz, acpi_trip->temperature)) { - *trend = THERMAL_TREND_RAISING; - return 0; - } + case THERMAL_TRIP_ACTIVE: + t = acpi_thermal_temp(tz, tz->temperature); + if (t <= trip->temperature) break; - } + + *trend = THERMAL_TREND_RAISING; + + return 0; + + default: + break; } return -EINVAL; diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 04513f9fbfa1..de884bea28b6 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -70,7 +70,7 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) void thermal_cdev_update(struct thermal_cooling_device *); void __thermal_cdev_update(struct thermal_cooling_device *cdev); -int get_tz_trend(struct thermal_zone_device *tz, int trip); +int get_tz_trend(struct thermal_zone_device *tz, int trip_index); struct thermal_instance * get_thermal_instance(struct thermal_zone_device *tz, diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index cfba0965a22d..4d66372c9629 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -22,8 +22,9 @@ #include "thermal_core.h" #include "thermal_trace.h" -int get_tz_trend(struct thermal_zone_device *tz, int trip) +int get_tz_trend(struct thermal_zone_device *tz, int trip_index) { + struct thermal_trip *trip = tz->trips ? &tz->trips[trip_index] : NULL; enum thermal_trend trend; if (tz->emul_temperature || !tz->ops->get_trend || diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index d414a4b7a94a..6ba2613627e1 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -109,7 +109,8 @@ static inline int __ti_thermal_get_temp(struct thermal_zone_device *tz, int *tem return ret; } -static int __ti_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) +static int __ti_thermal_get_trend(struct thermal_zone_device *tz, + struct thermal_trip *trip, enum thermal_trend *trend) { struct ti_thermal_data *data = thermal_zone_device_priv(tz); struct ti_bandgap *bgp; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index e6bd3b7c9eda..eb17495c8acc 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -53,6 +53,20 @@ enum thermal_notify_event { THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */ }; +/** + * struct thermal_trip - representation of a point in temperature domain + * @temperature: temperature value in miliCelsius + * @hysteresis: relative hysteresis in miliCelsius + * @type: trip point type + * @priv: pointer to driver data associated with this trip + */ +struct thermal_trip { + int temperature; + int hysteresis; + enum thermal_trip_type type; + void *priv; +}; + struct thermal_zone_device_ops { int (*bind) (struct thermal_zone_device *, struct thermal_cooling_device *); @@ -66,26 +80,12 @@ struct thermal_zone_device_ops { int (*set_trip_hyst) (struct thermal_zone_device *, int, int); int (*get_crit_temp) (struct thermal_zone_device *, int *); int (*set_emul_temp) (struct thermal_zone_device *, int); - int (*get_trend) (struct thermal_zone_device *, int, + int (*get_trend) (struct thermal_zone_device *, struct thermal_trip *, enum thermal_trend *); void (*hot)(struct thermal_zone_device *); void (*critical)(struct thermal_zone_device *); }; -/** - * struct thermal_trip - representation of a point in temperature domain - * @temperature: temperature value in miliCelsius - * @hysteresis: relative hysteresis in miliCelsius - * @type: trip point type - * @priv: pointer to driver data associated with this trip - */ -struct thermal_trip { - int temperature; - int hysteresis; - enum thermal_trip_type type; - void *priv; -}; - struct thermal_cooling_device_ops { int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); -- cgit v1.2.3