From 4ab17ed1318609da5c36cb7e427a1d24e52a7d6f Mon Sep 17 00:00:00 2001 From: Michael Kao Date: Wed, 7 Oct 2020 10:43:32 +0800 Subject: thermal: core: Add upper and lower limits to power_actor_set_power The upper and lower limits of thermal throttle state in the DT do not apply to the Intelligent Power Allocation (IPA) governor. Add the clamping for cooling device upper and lower limits in the power_actor_set_power() used by IPA. Signed-off-by: Michael Kao Reviewed-by: Lukasz Luba Tested-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201007024332.30322-1-michael.kao@mediatek.com --- drivers/thermal/thermal_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index c6d74bc1c90b..2ea3633b5d66 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -672,7 +672,7 @@ int power_actor_set_power(struct thermal_cooling_device *cdev, if (ret) return ret; - instance->target = state; + instance->target = clamp_val(state, instance->lower, instance->upper); mutex_lock(&cdev->lock); cdev->updated = false; mutex_unlock(&cdev->lock); -- cgit v1.2.3 From 8132df3a06a41823aa370dbb4ff08f48fa07f6df Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 15 Oct 2020 12:24:39 +0100 Subject: thermal: power_allocator: Respect upper and lower bounds for cooling device The thermal cooling device specified in DT might be instantiated for a thermal zone trip point with a limited set of OPPs to operate on. This configuration should be supported by Intelligent Power Allocation (IPA), since it is a standard for other governors. Change the code and allow IPA to get power value of lower and upper bound set for a given cooling device. Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201015112441.4056-3-lukasz.luba@arm.com --- drivers/thermal/gov_power_allocator.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index ab0be26f0816..eb8c9afadf19 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -96,7 +96,10 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz) if (instance->trip != params->trip_max_desired_temperature) continue; - if (power_actor_get_min_power(cdev, &min_power)) + if (!cdev_is_power_actor(cdev)) + continue; + + if (cdev->ops->state2power(cdev, instance->upper, &min_power)) continue; sustainable_power += min_power; @@ -398,7 +401,8 @@ static int allocate_power(struct thermal_zone_device *tz, weighted_req_power[i] = frac_to_int(weight * req_power[i]); - if (power_actor_get_max_power(cdev, &max_power[i])) + if (cdev->ops->state2power(cdev, instance->lower, + &max_power[i])) continue; total_req_power += req_power[i]; -- cgit v1.2.3 From 87d2380260524e55e090e14012c1b07c1f6d4096 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 15 Oct 2020 12:24:40 +0100 Subject: thermal: core: Remove unused functions in power actor section Since the Intelligent Power Allocation (IPA) uses different way to get minimum and maximum power for a given cooling device, the helper functions are not needed. There is no other code which uses them, so remove the helper functions. Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201015112441.4056-4-lukasz.luba@arm.com --- drivers/thermal/thermal_core.c | 47 ------------------------------------------ drivers/thermal/thermal_core.h | 4 ---- 2 files changed, 51 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 2ea3633b5d66..d5540bfeee5e 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -600,53 +600,6 @@ static void thermal_zone_device_check(struct work_struct *work) * how to estimate their devices power consumption. */ -/** - * power_actor_get_max_power() - get the maximum power that a cdev can consume - * @cdev: pointer to &thermal_cooling_device - * @max_power: pointer in which to store the maximum power - * - * Calculate the maximum power consumption in milliwats that the - * cooling device can currently consume and store it in @max_power. - * - * Return: 0 on success, -EINVAL if @cdev doesn't support the - * power_actor API or -E* on other error. - */ -int power_actor_get_max_power(struct thermal_cooling_device *cdev, - u32 *max_power) -{ - if (!cdev_is_power_actor(cdev)) - return -EINVAL; - - return cdev->ops->state2power(cdev, 0, max_power); -} - -/** - * power_actor_get_min_power() - get the mainimum power that a cdev can consume - * @cdev: pointer to &thermal_cooling_device - * @min_power: pointer in which to store the minimum power - * - * Calculate the minimum power consumption in milliwatts that the - * cooling device can currently consume and store it in @min_power. - * - * Return: 0 on success, -EINVAL if @cdev doesn't support the - * power_actor API or -E* on other error. - */ -int power_actor_get_min_power(struct thermal_cooling_device *cdev, - u32 *min_power) -{ - unsigned long max_state; - int ret; - - if (!cdev_is_power_actor(cdev)) - return -EINVAL; - - ret = cdev->ops->get_max_state(cdev, &max_state); - if (ret) - return ret; - - return cdev->ops->state2power(cdev, max_state, min_power); -} - /** * power_actor_set_power() - limit the maximum power a cooling device consumes * @cdev: pointer to &thermal_cooling_device diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 681209db42a8..416cdb1358e3 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -65,10 +65,6 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) cdev->ops->power2state; } -int power_actor_get_max_power(struct thermal_cooling_device *cdev, - u32 *max_power); -int power_actor_get_min_power(struct thermal_cooling_device *cdev, - u32 *min_power); int power_actor_set_power(struct thermal_cooling_device *cdev, struct thermal_instance *ti, u32 power); /** -- cgit v1.2.3 From 345a8af7ea63ac75a9000159d6298769d3d50f91 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 15 Oct 2020 12:24:41 +0100 Subject: thermal: core: Move power_actor_set_power into IPA Since the power actor section has one function power_actor_set_power() move it into Intelligent Power Allocation (IPA). There is no other user of that helper function. It would also allow to remove the check of cdev_is_power_actor() because the code which calls it in IPA already does the needed check. Make the function static since only IPA use it. Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201015112441.4056-5-lukasz.luba@arm.com --- drivers/thermal/gov_power_allocator.c | 32 +++++++++++++++++++++++++++ drivers/thermal/thermal_core.c | 41 ----------------------------------- drivers/thermal/thermal_core.h | 2 -- 3 files changed, 32 insertions(+), 43 deletions(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index eb8c9afadf19..b29e21c56a4f 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -254,6 +254,38 @@ static u32 pid_controller(struct thermal_zone_device *tz, return power_range; } +/** + * power_actor_set_power() - limit the maximum power a cooling device consumes + * @cdev: pointer to &thermal_cooling_device + * @instance: thermal instance to update + * @power: the power in milliwatts + * + * Set the cooling device to consume at most @power milliwatts. The limit is + * expected to be a cap at the maximum power consumption. + * + * Return: 0 on success, -EINVAL if the cooling device does not + * implement the power actor API or -E* for other failures. + */ +static int +power_actor_set_power(struct thermal_cooling_device *cdev, + struct thermal_instance *instance, u32 power) +{ + unsigned long state; + int ret; + + ret = cdev->ops->power2state(cdev, power, &state); + if (ret) + return ret; + + instance->target = clamp_val(state, instance->lower, instance->upper); + mutex_lock(&cdev->lock); + cdev->updated = false; + mutex_unlock(&cdev->lock); + thermal_cdev_update(cdev); + + return 0; +} + /** * divvy_up_power() - divvy the allocated power between the actors * @req_power: each actor's requested power diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d5540bfeee5e..96349ba59725 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -593,47 +593,6 @@ static void thermal_zone_device_check(struct work_struct *work) thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); } -/* - * Power actor section: interface to power actors to estimate power - * - * Set of functions used to interact to cooling devices that know - * how to estimate their devices power consumption. - */ - -/** - * power_actor_set_power() - limit the maximum power a cooling device consumes - * @cdev: pointer to &thermal_cooling_device - * @instance: thermal instance to update - * @power: the power in milliwatts - * - * Set the cooling device to consume at most @power milliwatts. The limit is - * expected to be a cap at the maximum power consumption. - * - * Return: 0 on success, -EINVAL if the cooling device does not - * implement the power actor API or -E* for other failures. - */ -int power_actor_set_power(struct thermal_cooling_device *cdev, - struct thermal_instance *instance, u32 power) -{ - unsigned long state; - int ret; - - if (!cdev_is_power_actor(cdev)) - return -EINVAL; - - ret = cdev->ops->power2state(cdev, power, &state); - if (ret) - return ret; - - instance->target = clamp_val(state, instance->lower, instance->upper); - mutex_lock(&cdev->lock); - cdev->updated = false; - mutex_unlock(&cdev->lock); - thermal_cdev_update(cdev); - - return 0; -} - void thermal_zone_device_rebind_exception(struct thermal_zone_device *tz, const char *cdev_type, size_t size) { diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 416cdb1358e3..8df600fa7b79 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -65,8 +65,6 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) cdev->ops->power2state; } -int power_actor_set_power(struct thermal_cooling_device *cdev, - struct thermal_instance *ti, u32 power); /** * struct thermal_trip - representation of a point in temperature domain * @np: pointer to struct device_node that this trip point was created from -- cgit v1.2.3 From 37b2539e63d6570c9ee51b1d48bdecb334df367d Mon Sep 17 00:00:00 2001 From: Bernard Zhao Date: Mon, 26 Oct 2020 18:37:42 -0700 Subject: drivers/thermal/core: Optimize trip points check The trip points are checked one by one with multiple condition branches where one condition is enough to disable the trip point. Merge all these conditions in a single 'OR' statement. Signed-off-by: Bernard Zhao Suggested-by: Daniel Lezcano Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201027013743.62392-1-bernard@vivo.com [dlezcano] Changed patch description --- drivers/thermal/thermal_core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 96349ba59725..90e38cc199f4 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1358,12 +1358,9 @@ thermal_zone_device_register(const char *type, int trips, int mask, goto release_device; for (count = 0; count < trips; count++) { - if (tz->ops->get_trip_type(tz, count, &trip_type)) - set_bit(count, &tz->trips_disabled); - if (tz->ops->get_trip_temp(tz, count, &trip_temp)) - set_bit(count, &tz->trips_disabled); - /* Check for bogus trip points */ - if (trip_temp == 0) + if (tz->ops->get_trip_type(tz, count, &trip_type) || + tz->ops->get_trip_temp(tz, count, &trip_temp) || + !trip_temp) set_bit(count, &tz->trips_disabled); } -- cgit v1.2.3 From 4eb7d0cd590d99b6010b5b87a88804cda09a85da Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 27 Oct 2020 09:06:30 +0800 Subject: thermal/drivers/rcar: Replace spin_lock_irqsave by spin_lock in hard IRQ On RT or even on mainline with 'threadirqs' on the command line all interrupts which are not explicitly requested with IRQF_NO_THREAD run their handlers in thread context. The same applies to soft interrupts. That means they are subject to the normal scheduler rules and no other code is going to acquire that lock from hard interrupt context either, so the irqsave() here is pointless in all cases. Signed-off-by: Tian Tao Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/1603760790-37748-1-git-send-email-tiantao6@hisilicon.com --- drivers/thermal/rcar_thermal.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 5c2a13bf249c..6ae757d66f46 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -409,16 +409,15 @@ static irqreturn_t rcar_thermal_irq(int irq, void *data) { struct rcar_thermal_common *common = data; struct rcar_thermal_priv *priv; - unsigned long flags; u32 status, mask; - spin_lock_irqsave(&common->lock, flags); + spin_lock(&common->lock); mask = rcar_thermal_common_read(common, INTMSK); status = rcar_thermal_common_read(common, STR); rcar_thermal_common_write(common, STR, 0x000F0F0F & mask); - spin_unlock_irqrestore(&common->lock, flags); + spin_unlock(&common->lock); status = status & ~mask; -- cgit v1.2.3 From 07df39d03c34bd7baf4c26e41a5dd92ec56e9081 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Wed, 21 Oct 2020 18:42:29 +0200 Subject: dt-bindings: thermal: mediatek: make resets property optional MT8516 Thermal IP does not support reset. Make the resets property optional in order to be able to support MT8516 SoC. Signed-off-by: Fabien Parent Acked-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201021164231.3029956-1-fparent@baylibre.com --- Documentation/devicetree/bindings/thermal/mediatek-thermal.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt index 1e249c42fae0..2d20f6b0dca0 100644 --- a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt @@ -20,12 +20,12 @@ Required properties: clocks are: "therm": Main clock needed for register access "auxadc": The AUXADC clock -- resets: Reference to the reset controller controlling the thermal controller. - mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses - mediatek,apmixedsys: A phandle to the APMIXEDSYS controller. - #thermal-sensor-cells : Should be 0. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description. Optional properties: +- resets: Reference to the reset controller controlling the thermal controller. - nvmem-cells: A phandle to the calibration data provided by a nvmem device. If unspecified default values shall be used. - nvmem-cell-names: Should be "calibration-data" -- cgit v1.2.3 From c707f973df1706020f4a4669b5f1932e90c0f29c Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Wed, 21 Oct 2020 18:42:30 +0200 Subject: dt-bindings: thermal: mediatek: add documentation for MT8516 SoC Add binding documentation for the MediaTek MT8516 SoC. The SoC thermal IP is similar to MT2701. Signed-off-by: Fabien Parent Acked-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201021164231.3029956-2-fparent@baylibre.com --- Documentation/devicetree/bindings/thermal/mediatek-thermal.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt index 2d20f6b0dca0..5c7e7bdd029a 100644 --- a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt @@ -14,6 +14,7 @@ Required properties: - "mediatek,mt2712-thermal" : For MT2712 family of SoCs - "mediatek,mt7622-thermal" : For MT7622 SoC - "mediatek,mt8183-thermal" : For MT8183 family of SoCs + - "mediatek,mt8516-thermal", "mediatek,mt2701-thermal : For MT8516 family of SoCs - reg: Address range of the thermal controller - interrupts: IRQ for the thermal controller - clocks, clock-names: Clocks needed for the thermal controller. required -- cgit v1.2.3 From 703456ba76e9449b5ade6597c04a90ee3421cd94 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Wed, 21 Oct 2020 18:42:31 +0200 Subject: thermal: mtk_thermal: make device_reset optional MT8516 does not support thermal reset. Use device_reset_optional instead of device_reset. Signed-off-by: Fabien Parent Reviewed-by: Matthias Brugger Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201021164231.3029956-3-fparent@baylibre.com --- drivers/thermal/mtk_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 0bd7aa564bc2..149c6d7fd5a0 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -1052,7 +1052,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -EINVAL; } - ret = device_reset(&pdev->dev); + ret = device_reset_optional(&pdev->dev); if (ret) return ret; -- cgit v1.2.3 From ef63b043ac8645d2540d7b50dd3e09c53db3d504 Mon Sep 17 00:00:00 2001 From: Sumeet Pawnikar Date: Fri, 6 Nov 2020 22:36:33 +0530 Subject: thermal: intel: pch: fix S0ix failure due to PCH temperature above threshold When system tries to enter S0ix suspend state, just after active load scenarios, it fails due to PCH current temperature is higher than set threshold. This patch introduces delay loop mechanism that allows PCH temperature to go down below threshold during suspend so it won't fail to enter S0ix. Add delay loop timeout and count as module parameters for user to tune it, if required based on system design. This change notifies the different warning messages like when PCH temperature above the threshold and executing delay loop. Also, notify the messages when it success or failure for S0ix entry. Previously out of 1000 runs around 3 to 5 times it might fail to enter S0ix just after heavy workload. With this change, S0ix failures reduced as PCH cools down below threshold. Signed-off-by: Sumeet Pawnikar Reviewed-by: Zhang Rui Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201106170633.20838-1-sumeet.r.pawnikar@intel.com --- drivers/thermal/intel/intel_pch_thermal.c | 76 ++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c index 3b813ebb6ca1..0a9e4458bc3a 100644 --- a/drivers/thermal/intel/intel_pch_thermal.c +++ b/drivers/thermal/intel/intel_pch_thermal.c @@ -7,14 +7,16 @@ * Tushar Dave */ +#include +#include #include -#include #include #include -#include +#include +#include #include +#include #include -#include /* Intel PCH thermal Device IDs */ #define PCH_THERMAL_DID_HSW_1 0x9C24 /* Haswell PCH */ @@ -35,6 +37,7 @@ #define WPT_TSREL 0x0A /* Thermal Sensor Report Enable and Lock */ #define WPT_TSMIC 0x0C /* Thermal Sensor SMI Control */ #define WPT_CTT 0x0010 /* Catastrophic Trip Point */ +#define WPT_TSPM 0x001C /* Thermal Sensor Power Management */ #define WPT_TAHV 0x0014 /* Thermal Alert High Value */ #define WPT_TALV 0x0018 /* Thermal Alert Low Value */ #define WPT_TL 0x00000040 /* Throttle Value */ @@ -55,6 +58,22 @@ #define WPT_TL_T1L 0x1ff00000 /* T1 Level */ #define WPT_TL_TTEN 0x20000000 /* TT Enable */ +/* Resolution of 1/2 degree C and an offset of -50C */ +#define PCH_TEMP_OFFSET (-50) +#define GET_WPT_TEMP(x) ((x) * MILLIDEGREE_PER_DEGREE / 2 + WPT_TEMP_OFFSET) +#define WPT_TEMP_OFFSET (PCH_TEMP_OFFSET * MILLIDEGREE_PER_DEGREE) +#define GET_PCH_TEMP(x) (((x) / 2) + PCH_TEMP_OFFSET) + +/* Amount of time for each cooling delay, 100ms by default for now */ +static unsigned int delay_timeout = 100; +module_param(delay_timeout, int, 0644); +MODULE_PARM_DESC(delay_timeout, "amount of time delay for each iteration."); + +/* Number of iterations for cooling delay, 10 counts by default for now */ +static unsigned int delay_cnt = 10; +module_param(delay_cnt, int, 0644); +MODULE_PARM_DESC(delay_cnt, "total number of iterations for time delay."); + static char driver_name[] = "Intel PCH thermal driver"; struct pch_thermal_device { @@ -183,13 +202,58 @@ static int pch_wpt_get_temp(struct pch_thermal_device *ptd, int *temp) static int pch_wpt_suspend(struct pch_thermal_device *ptd) { u8 tsel; + u8 pch_delay_cnt = 1; + u16 pch_thr_temp, pch_cur_temp; - if (ptd->bios_enabled) + /* Shutdown the thermal sensor if it is not enabled by BIOS */ + if (!ptd->bios_enabled) { + tsel = readb(ptd->hw_base + WPT_TSEL); + writeb(tsel & 0xFE, ptd->hw_base + WPT_TSEL); + return 0; + } + + /* Do not check temperature if it is not a S0ix capable platform */ + if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) return 0; - tsel = readb(ptd->hw_base + WPT_TSEL); + /* Do not check temperature if it is not s2idle */ + if (pm_suspend_via_firmware()) + return 0; + + /* Get the PCH temperature threshold value */ + pch_thr_temp = GET_PCH_TEMP(WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TSPM)); + + /* Get the PCH current temperature value */ + pch_cur_temp = GET_PCH_TEMP(WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP)); - writeb(tsel & 0xFE, ptd->hw_base + WPT_TSEL); + /* + * If current PCH temperature is higher than configured PCH threshold + * value, run some delay loop with sleep to let the current temperature + * go down below the threshold value which helps to allow system enter + * lower power S0ix suspend state. Even after delay loop if PCH current + * temperature stays above threshold, notify the warning message + * which helps to indentify the reason why S0ix entry was rejected. + */ + while (pch_delay_cnt <= delay_cnt) { + if (pch_cur_temp <= pch_thr_temp) + break; + + dev_warn(&ptd->pdev->dev, + "CPU-PCH current temp [%dC] higher than the threshold temp [%dC], sleep %d times for %d ms duration\n", + pch_cur_temp, pch_thr_temp, pch_delay_cnt, delay_timeout); + msleep(delay_timeout); + /* Read the PCH current temperature for next cycle. */ + pch_cur_temp = GET_PCH_TEMP(WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP)); + pch_delay_cnt++; + } + + if (pch_cur_temp > pch_thr_temp) + dev_warn(&ptd->pdev->dev, + "CPU-PCH is hot [%dC] even after delay, continue to suspend. S0ix might fail\n", + pch_cur_temp); + else + dev_info(&ptd->pdev->dev, + "CPU-PCH is cool [%dC], continue to suspend\n", pch_cur_temp); return 0; } -- cgit v1.2.3 From e01aac535353e013f9a5c9675232458906b895da Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 9 Nov 2020 19:46:24 +0800 Subject: thermal: sun8i: Use bitmap API instead of open code The bitmap_* API is the standard way to access data in the bitfield. So convert irq_ack to return an unsigned long, and make things to use bitmap API. Signed-off-by: Yangtao Li Acked-by: Maxime Ripard Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201109114624.23035-1-frank@allwinnertech.com --- drivers/thermal/sun8i_thermal.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index f8b13071a6f4..8c80bd06dd9f 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -8,6 +8,7 @@ * Based on the work of Josef Gajdusek */ +#include #include #include #include @@ -74,7 +75,7 @@ struct ths_thermal_chip { int (*calibrate)(struct ths_device *tmdev, u16 *caldata, int callen); int (*init)(struct ths_device *tmdev); - int (*irq_ack)(struct ths_device *tmdev); + unsigned long (*irq_ack)(struct ths_device *tmdev); int (*calc_temp)(struct ths_device *tmdev, int id, int reg); }; @@ -146,9 +147,10 @@ static const struct regmap_config config = { .max_register = 0xfc, }; -static int sun8i_h3_irq_ack(struct ths_device *tmdev) +static unsigned long sun8i_h3_irq_ack(struct ths_device *tmdev) { - int i, state, ret = 0; + unsigned long irq_bitmap = 0; + int i, state; regmap_read(tmdev->regmap, SUN8I_THS_IS, &state); @@ -156,16 +158,17 @@ static int sun8i_h3_irq_ack(struct ths_device *tmdev) if (state & SUN8I_THS_DATA_IRQ_STS(i)) { regmap_write(tmdev->regmap, SUN8I_THS_IS, SUN8I_THS_DATA_IRQ_STS(i)); - ret |= BIT(i); + bitmap_set(&irq_bitmap, i, 1); } } - return ret; + return irq_bitmap; } -static int sun50i_h6_irq_ack(struct ths_device *tmdev) +static unsigned long sun50i_h6_irq_ack(struct ths_device *tmdev) { - int i, state, ret = 0; + unsigned long irq_bitmap = 0; + int i, state; regmap_read(tmdev->regmap, SUN50I_H6_THS_DIS, &state); @@ -173,24 +176,22 @@ static int sun50i_h6_irq_ack(struct ths_device *tmdev) if (state & SUN50I_H6_THS_DATA_IRQ_STS(i)) { regmap_write(tmdev->regmap, SUN50I_H6_THS_DIS, SUN50I_H6_THS_DATA_IRQ_STS(i)); - ret |= BIT(i); + bitmap_set(&irq_bitmap, i, 1); } } - return ret; + return irq_bitmap; } static irqreturn_t sun8i_irq_thread(int irq, void *data) { struct ths_device *tmdev = data; - int i, state; - - state = tmdev->chip->irq_ack(tmdev); + unsigned long irq_bitmap = tmdev->chip->irq_ack(tmdev); + int i; - for (i = 0; i < tmdev->chip->sensor_num; i++) { - if (state & BIT(i)) - thermal_zone_device_update(tmdev->sensor[i].tzd, - THERMAL_EVENT_UNSPECIFIED); + for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) { + thermal_zone_device_update(tmdev->sensor[i].tzd, + THERMAL_EVENT_UNSPECIFIED); } return IRQ_HANDLED; -- cgit v1.2.3 From 030a48b0f6ce393d78b8d33debb1e2043b8cc156 Mon Sep 17 00:00:00 2001 From: Bernard Zhao Date: Sun, 1 Nov 2020 18:31:21 -0800 Subject: thermal/drivers/hwmon: Cleanup coding style a bit Function thermal_add_hwmon_sysfs, hwmon will be NULL when new_hwmon_device = 0, so there is no need to check, kfree will handle NULL point. Signed-off-by: Bernard Zhao Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201102023121.3312-1-bernard@vivo.com --- drivers/thermal/thermal_hwmon.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index 8b92e00ff236..ad03262cca56 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -206,8 +206,7 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) if (new_hwmon_device) hwmon_device_unregister(hwmon->device); free_mem: - if (new_hwmon_device) - kfree(hwmon); + kfree(hwmon); return result; } -- cgit v1.2.3 From 236761f19a4f373354f1dcf399b57753f1f4b871 Mon Sep 17 00:00:00 2001 From: Zhuguangqing Date: Fri, 6 Nov 2020 17:22:43 +0800 Subject: thermal/drivers/cpufreq_cooling: Update cpufreq_state only if state has changed If state has not changed successfully and we updated cpufreq_state, next time when the new state is equal to cpufreq_state (not changed successfully last time), we will return directly and miss a freq_qos_update_request() that should have been. Fixes: 5130802ddbb1 ("thermal: cpu_cooling: Switch to QoS requests for freq limits") Cc: v5.4+ # v5.4+ Signed-off-by: Zhuguangqing Acked-by: Viresh Kumar Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201106092243.15574-1-zhuguangqing83@gmail.com --- drivers/thermal/cpufreq_cooling.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index cc2959f22f01..612f063c1cfc 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -438,13 +438,11 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, if (cpufreq_cdev->cpufreq_state == state) return 0; - cpufreq_cdev->cpufreq_state = state; - frequency = get_state_freq(cpufreq_cdev, state); ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency); - if (ret > 0) { + cpufreq_cdev->cpufreq_state = state; cpus = cpufreq_cdev->policy->cpus; max_capacity = arch_scale_cpu_capacity(cpumask_first(cpus)); capacity = frequency * max_capacity; -- cgit v1.2.3 From 7cfa9770f485c03c877db4a66bbfda96df367b98 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 28 Oct 2020 16:35:41 +0100 Subject: dt-bindings: thermal: rcar-thermal: Improve schema validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Factor out common required properties, - "interrupts", "clocks", and "power-domains" are required on R-Mobile APE6, too, - Invert logic to simplify descriptions. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Reviewed-by: Amit Kucheria Reviewed-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201028153541.1736279-1-geert+renesas@glider.be --- .../devicetree/bindings/thermal/rcar-thermal.yaml | 48 +++++++++++++--------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml b/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml index 7e9557ac0e4a..927de79ab4b5 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml @@ -62,25 +62,35 @@ properties: "#thermal-sensor-cells": const: 0 -if: - properties: - compatible: - contains: - enum: - - renesas,thermal-r8a73a4 # R-Mobile APE6 - - renesas,thermal-r8a7779 # R-Car H1 -then: - required: - - compatible - - reg -else: - required: - - compatible - - reg - - interrupts - - clocks - - power-domains - - resets +required: + - compatible + - reg + +allOf: + - if: + not: + properties: + compatible: + contains: + enum: + - renesas,thermal-r8a73a4 # R-Mobile APE6 + - renesas,thermal-r8a7779 # R-Car H1 + then: + required: + - resets + - '#thermal-sensor-cells' + + - if: + not: + properties: + compatible: + contains: + const: renesas,thermal-r8a7779 # R-Car H1 + then: + required: + - interrupts + - clocks + - power-domains additionalProperties: false -- cgit v1.2.3 From ce7c01557465e920f5bccc5878b8dec165eeb80b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Nov 2020 16:13:37 +0530 Subject: docs: thermal: time_in_state is displayed in msec and not usertime The sysfs stats for cooling devices shows the time_in_state in msec, remove the unwanted usertime comment. Signed-off-by: Viresh Kumar Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/d5461bdf9ab6b6fee7f28f538582edbb426aa077.1605004905.git.viresh.kumar@linaro.org --- Documentation/driver-api/thermal/sysfs-api.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst index b40b1f839148..e7520cb439ac 100644 --- a/Documentation/driver-api/thermal/sysfs-api.rst +++ b/Documentation/driver-api/thermal/sysfs-api.rst @@ -654,8 +654,7 @@ stats/time_in_state_ms: The amount of time spent by the cooling device in various cooling states. The output will have "