From e042e95bcab34b2265b0aaeb497030ea13c6c251 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Mon, 22 Feb 2021 14:11:05 +0800 Subject: [PATCH 01/55] thermal: amlogic: Omit superfluous error message in amlogic_thermal_probe() The function devm_platform_ioremap_resource has already contains error message, so remove the redundant dev_err here. Signed-off-by: Tang Bin Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210222061105.6008-1-tangbin@cmss.chinamobile.com --- drivers/thermal/amlogic_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c index dffe3ba8c7c4..e61b91d14ad1 100644 --- a/drivers/thermal/amlogic_thermal.c +++ b/drivers/thermal/amlogic_thermal.c @@ -254,10 +254,8 @@ static int amlogic_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) { - dev_err(dev, "failed to get io address\n"); + if (IS_ERR(base)) return PTR_ERR(base); - } pdata->regmap = devm_regmap_init_mmio(dev, base, pdata->data->regmap_config); From 6606800192008bd2929c55614697645f53e07427 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 5 Mar 2021 07:23:20 +0530 Subject: [PATCH 02/55] thermal: Fix a typo in the file soctherm.c s/calibaration/calibration/ Signed-off-by: Bhaskar Chowdhury Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210305015320.7614-1-unixbhaskar@gmail.com --- drivers/thermal/tegra/soctherm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 66e0639da4bf..8b8fbd49679b 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -2195,7 +2195,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) if (err) return err; - /* calculate tsensor calibaration data */ + /* calculate tsensor calibration data */ for (i = 0; i < soc->num_tsensors; ++i) { err = tegra_calc_tsensor_calib(&soc->tsensors[i], &shared_calib, From 76d6329534ae3b2f344aa72cc978ef4cfd69c0c8 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 5 Mar 2021 07:13:48 +0530 Subject: [PATCH 03/55] thermal: Fix couple of spellos in the file sun8i_thermal.c s/calibartion/calibration/ s/undocummented/undocumented/ Signed-off-by: Bhaskar Chowdhury Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210305014348.17412-1-unixbhaskar@gmail.com --- drivers/thermal/sun8i_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index 8c80bd06dd9f..d9cd23cbb671 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -300,7 +300,7 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) * or 0x8xx, so they won't be away from the default value * for a lot. * - * So here we do not return error if the calibartion data is + * So here we do not return error if the calibration data is * not available, except the probe needs deferring. */ goto out; @@ -418,7 +418,7 @@ static int sun8i_h3_thermal_init(struct ths_device *tmdev) } /* - * Without this undocummented value, the returned temperatures would + * Without this undocumented value, the returned temperatures would * be higher than real ones by about 20C. */ #define SUN50I_H6_CTRL0_UNK 0x0000002f From 7fd49ca05be35a85c424a3ca8df931bd70c34535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Tue, 9 Mar 2021 17:24:19 +0100 Subject: [PATCH 04/55] thermal: rcar_gen3_thermal: Add support for up to five TSC nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for up to five TSC nodes. The new THCODE values are taken from the example in the datasheet. Signed-off-by: Niklas Söderlund Acked-by: Geert Uytterhoeven Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210309162419.2621359-1-niklas.soderlund+renesas@ragnatech.se --- drivers/thermal/rcar_gen3_thermal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c index 75c69fe6e955..e1e412348076 100644 --- a/drivers/thermal/rcar_gen3_thermal.c +++ b/drivers/thermal/rcar_gen3_thermal.c @@ -60,7 +60,7 @@ #define MCELSIUS(temp) ((temp) * 1000) #define GEN3_FUSE_MASK 0xFFF -#define TSC_MAX_NUM 4 +#define TSC_MAX_NUM 5 /* default THCODE values if FUSEs are missing */ static const int thcodes[TSC_MAX_NUM][3] = { @@ -68,6 +68,7 @@ static const int thcodes[TSC_MAX_NUM][3] = { { 3393, 2795, 2216 }, { 3389, 2805, 2237 }, { 3415, 2694, 2195 }, + { 3356, 2724, 2244 }, }; /* Structure for thermal temperature calculation */ From 7440e912b0fe755d80b958a65859ebabb5338cf8 Mon Sep 17 00:00:00 2001 From: Zhang Yunkai Date: Sat, 6 Mar 2021 04:34:15 -0800 Subject: [PATCH 05/55] thermal:ti-soc-thermal: Remove duplicate include in ti-bandgap 'of_device.h' included in 'ti-bandgap.c' is duplicated. It is also included in the 25th line. Signed-off-by: Zhang Yunkai Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210306123415.219441-1-zhang.yunkai@zte.com.cn --- drivers/thermal/ti-soc-thermal/ti-bandgap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c index 8a3646e26ddd..d81af89166d2 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "ti-bandgap.h" From 45c7eaeb29d67224db4ba935deb575586a1fda09 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Wed, 10 Mar 2021 04:24:23 -0800 Subject: [PATCH 06/55] thermal: thermal_of: Fix error return code of thermal_of_populate_bind_params() When kcalloc() returns NULL to __tcbp or of_count_phandle_with_args() returns zero or -ENOENT to count, no error return code of thermal_of_populate_bind_params() is assigned. To fix these bugs, ret is assigned with -ENOMEM and -ENOENT in these cases, respectively. Fixes: a92bab8919e3 ("of: thermal: Allow multiple devices to share cooling map") Reported-by: TOTE Robot Signed-off-by: Jia-Ju Bai Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210310122423.3266-1-baijiaju1990@gmail.com --- drivers/thermal/thermal_of.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 69ef12f852b7..5b76f9a1280d 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -704,14 +704,17 @@ static int thermal_of_populate_bind_params(struct device_node *np, count = of_count_phandle_with_args(np, "cooling-device", "#cooling-cells"); - if (!count) { + if (count <= 0) { pr_err("Add a cooling_device property with at least one device\n"); + ret = -ENOENT; goto end; } __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL); - if (!__tcbp) + if (!__tcbp) { + ret = -ENOMEM; goto end; + } for (i = 0; i < count; i++) { ret = of_parse_phandle_with_args(np, "cooling-device", From 9468e7b031876935230182628f8d5f216c071784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Wed, 10 Mar 2021 12:07:16 +0100 Subject: [PATCH 07/55] dt-bindings: thermal: rcar-gen3-thermal: Support five TSC nodes on r8a779a0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adding support for V3U (r8a779a0) it was incorrectly recorded it supports four nodes, while in fact it supports five. The fifth node is named TSC0 and breaks the existing naming schema starting at 1. Work around this by separately defining the reg property for V3U and others. Restore the maximum number of nodes to three for other compatibles as it was before erroneously increasing it for V3U. Fixes: d7fdfb6541f3be88 ("dt-bindings: thermal: rcar-gen3-thermal: Add r8a779a0 support") Signed-off-by: Niklas Söderlund Reviewed-by: Geert Uytterhoeven Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210310110716.3297544-1-niklas.soderlund+renesas@ragnatech.se --- .../bindings/thermal/rcar-gen3-thermal.yaml | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml index b33a76eeac4e..f963204e0b16 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml @@ -28,14 +28,7 @@ properties: - renesas,r8a77980-thermal # R-Car V3H - renesas,r8a779a0-thermal # R-Car V3U - reg: - minItems: 2 - maxItems: 4 - items: - - description: TSC1 registers - - description: TSC2 registers - - description: TSC3 registers - - description: TSC4 registers + reg: true interrupts: items: @@ -71,8 +64,25 @@ if: enum: - renesas,r8a779a0-thermal then: + properties: + reg: + minItems: 2 + maxItems: 3 + items: + - description: TSC1 registers + - description: TSC2 registers + - description: TSC3 registers required: - interrupts +else: + properties: + reg: + items: + - description: TSC0 registers + - description: TSC1 registers + - description: TSC2 registers + - description: TSC3 registers + - description: TSC4 registers additionalProperties: false @@ -111,3 +121,20 @@ examples: }; }; }; + - | + #include + #include + #include + + tsc_r8a779a0: thermal@e6190000 { + compatible = "renesas,r8a779a0-thermal"; + reg = <0xe6190000 0x200>, + <0xe6198000 0x200>, + <0xe61a0000 0x200>, + <0xe61a8000 0x200>, + <0xe61b0000 0x200>; + clocks = <&cpg CPG_MOD 919>; + power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; + resets = <&cpg 919>; + #thermal-sensor-cells = <1>; + }; From 312e3f8aefb5dc9c2f052ba0ee35a2fd6baa5bcd Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 11 Mar 2021 09:30:54 +0000 Subject: [PATCH 08/55] thermal: Fix spelling mistake "disabed" -> "disabled" There is a spelling mistake in a comment, fix it. Signed-off-by: Colin Ian King Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210311093054.5338-1-colin.king@canonical.com --- include/uapi/linux/thermal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/thermal.h b/include/uapi/linux/thermal.h index c105054cbb57..9aa2fedfa309 100644 --- a/include/uapi/linux/thermal.h +++ b/include/uapi/linux/thermal.h @@ -60,7 +60,7 @@ enum thermal_genl_event { THERMAL_GENL_EVENT_UNSPEC, THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */ THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */ - THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabed */ + THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabled */ THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */ THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */ THERMAL_GENL_EVENT_TZ_TRIP_DOWN, /* Trip point crossed the way down */ From 58483761810087e5ffdf36e84ac1bf26df909097 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 14 Mar 2021 12:13:29 +0100 Subject: [PATCH 09/55] thermal/drivers/core: Use a char pointer for the cooling device name We want to have any kind of name for the cooling devices as we do no longer want to rely on auto-numbering. Let's replace the cooling device's fixed array by a char pointer to be allocated dynamically when registering the cooling device, so we don't limit the length of the name. Rework the error path at the same time as we have to rollback the allocations in case of error. Tested with a dummy device having the name: "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch" A village on the island of Anglesey (Wales), known to have the longest name in Europe. Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba Tested-by: Ido Schimmel Link: https://lore.kernel.org/r/20210314111333.16551-1-daniel.lezcano@linaro.org --- .../ethernet/mellanox/mlxsw/core_thermal.c | 2 +- drivers/thermal/thermal_core.c | 38 +++++++++++-------- include/linux/thermal.h | 2 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c index bf85ce9835d7..7447c2a73cbd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c @@ -141,7 +141,7 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal, /* Allow mlxsw thermal zone binding to an external cooling device */ for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) { if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i], - sizeof(cdev->type))) + strlen(cdev->type))) return 0; } diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 996c038f83a4..c8d4010940ef 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -960,10 +960,7 @@ __thermal_cooling_device_register(struct device_node *np, { struct thermal_cooling_device *cdev; struct thermal_zone_device *pos = NULL; - int result; - - if (type && strlen(type) >= THERMAL_NAME_LENGTH) - return ERR_PTR(-EINVAL); + int ret; if (!ops || !ops->get_max_state || !ops->get_cur_state || !ops->set_cur_state) @@ -973,14 +970,17 @@ __thermal_cooling_device_register(struct device_node *np, if (!cdev) return ERR_PTR(-ENOMEM); - result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL); - if (result < 0) { - kfree(cdev); - return ERR_PTR(result); + ret = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL); + if (ret < 0) + goto out_kfree_cdev; + cdev->id = ret; + + cdev->type = kstrdup(type ? type : "", GFP_KERNEL); + if (!cdev->type) { + ret = -ENOMEM; + goto out_ida_remove; } - cdev->id = result; - strlcpy(cdev->type, type ? : "", sizeof(cdev->type)); mutex_init(&cdev->lock); INIT_LIST_HEAD(&cdev->thermal_instances); cdev->np = np; @@ -990,12 +990,9 @@ __thermal_cooling_device_register(struct device_node *np, cdev->devdata = devdata; thermal_cooling_device_setup_sysfs(cdev); dev_set_name(&cdev->device, "cooling_device%d", cdev->id); - result = device_register(&cdev->device); - if (result) { - ida_simple_remove(&thermal_cdev_ida, cdev->id); - put_device(&cdev->device); - return ERR_PTR(result); - } + ret = device_register(&cdev->device); + if (ret) + goto out_kfree_type; /* Add 'this' new cdev to the global cdev list */ mutex_lock(&thermal_list_lock); @@ -1013,6 +1010,14 @@ __thermal_cooling_device_register(struct device_node *np, mutex_unlock(&thermal_list_lock); return cdev; + +out_kfree_type: + kfree(cdev->type); + put_device(&cdev->device); +out_ida_remove: + ida_simple_remove(&thermal_cdev_ida, cdev->id); +out_kfree_cdev: + return ERR_PTR(ret); } /** @@ -1171,6 +1176,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) ida_simple_remove(&thermal_cdev_ida, cdev->id); device_del(&cdev->device); thermal_cooling_device_destroy_sysfs(cdev); + kfree(cdev->type); put_device(&cdev->device); } EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 6ac7bb1d2b1f..169502164364 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -91,7 +91,7 @@ struct thermal_cooling_device_ops { struct thermal_cooling_device { int id; - char type[THERMAL_NAME_LENGTH]; + char *type; struct device device; struct device_node *np; void *devdata; From ef37d1f9acb57b7a5993e93ae582ba5f4108919e Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 14 Mar 2021 12:13:30 +0100 Subject: [PATCH 10/55] thermal/drivers/cpufreq_cooling: Use device name instead of auto-numbering Currently the naming of a cooling device is just a cooling technique followed by a number. When there are multiple cooling devices using the same technique, it is impossible to clearly identify the related device as this one is just a number. For instance: thermal-cpufreq-0 thermal-cpufreq-1 etc ... The 'thermal' prefix is redundant with the subsystem namespace. This patch removes the 'thermal' prefix and changes the number by the device name. So the naming above becomes: cpufreq-cpu0 cpufreq-cpu4 etc ... Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar Reviewed-by: Lukasz Luba Link: https://lore.kernel.org/r/20210314111333.16551-2-daniel.lezcano@linaro.org --- drivers/thermal/cpufreq_cooling.c | 34 +++++++++++-------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 10af3341e5ea..3f5f1dce1320 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -13,10 +13,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -50,8 +50,6 @@ struct time_in_idle { /** * struct cpufreq_cooling_device - data for cooling device with cpufreq - * @id: unique integer value corresponding to each cpufreq_cooling_device - * registered. * @last_load: load measured by the latest call to cpufreq_get_requested_power() * @cpufreq_state: integer value representing the current state of cpufreq * cooling devices. @@ -69,7 +67,6 @@ struct time_in_idle { * cpufreq_cooling_device. */ struct cpufreq_cooling_device { - int id; u32 last_load; unsigned int cpufreq_state; unsigned int max_level; @@ -82,7 +79,6 @@ struct cpufreq_cooling_device { struct freq_qos_request qos_req; }; -static DEFINE_IDA(cpufreq_ida); static DEFINE_MUTEX(cooling_list_lock); static LIST_HEAD(cpufreq_cdev_list); @@ -528,11 +524,11 @@ __cpufreq_cooling_register(struct device_node *np, { struct thermal_cooling_device *cdev; struct cpufreq_cooling_device *cpufreq_cdev; - char dev_name[THERMAL_NAME_LENGTH]; unsigned int i; struct device *dev; int ret; struct thermal_cooling_device_ops *cooling_ops; + char *name; dev = get_cpu_device(policy->cpu); if (unlikely(!dev)) { @@ -567,16 +563,6 @@ __cpufreq_cooling_register(struct device_node *np, /* max_level is an index, not a counter */ cpufreq_cdev->max_level = i - 1; - ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL); - if (ret < 0) { - cdev = ERR_PTR(ret); - goto free_idle_time; - } - cpufreq_cdev->id = ret; - - snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", - cpufreq_cdev->id); - cooling_ops = &cpufreq_cooling_ops; #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR @@ -591,7 +577,7 @@ __cpufreq_cooling_register(struct device_node *np, pr_err("%s: unsorted frequency tables are not supported\n", __func__); cdev = ERR_PTR(-EINVAL); - goto remove_ida; + goto free_idle_time; } ret = freq_qos_add_request(&policy->constraints, @@ -601,11 +587,18 @@ __cpufreq_cooling_register(struct device_node *np, pr_err("%s: Failed to add freq constraint (%d)\n", __func__, ret); cdev = ERR_PTR(ret); - goto remove_ida; + goto free_idle_time; } - cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev, + cdev = ERR_PTR(-ENOMEM); + name = kasprintf(GFP_KERNEL, "cpufreq-%s", dev_name(dev)); + if (!name) + goto remove_qos_req; + + cdev = thermal_of_cooling_device_register(np, name, cpufreq_cdev, cooling_ops); + kfree(name); + if (IS_ERR(cdev)) goto remove_qos_req; @@ -617,8 +610,6 @@ __cpufreq_cooling_register(struct device_node *np, remove_qos_req: freq_qos_remove_request(&cpufreq_cdev->qos_req); -remove_ida: - ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); free_idle_time: free_idle_time(cpufreq_cdev); free_cdev: @@ -712,7 +703,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) thermal_cooling_device_unregister(cdev); freq_qos_remove_request(&cpufreq_cdev->qos_req); - ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); free_idle_time(cpufreq_cdev); kfree(cpufreq_cdev); } From f8d354e821b268c23a6cd548b7154e55c3954496 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 14 Mar 2021 12:13:31 +0100 Subject: [PATCH 11/55] thermal/drivers/devfreq_cooling: Use device name instead of auto-numbering Currently the naming of a cooling device is just a cooling technique followed by a number. When there are multiple cooling devices using the same technique, it is impossible to clearly identify the related device as this one is just a number. For instance: thermal-devfreq-0 thermal-devfreq-1 etc ... The 'thermal' prefix is redundant with the subsystem namespace. This patch removes the 'thermal' prefix and changes the number by the device name. So the naming above becomes: devfreq-5000000.gpu devfreq-1d84000.ufshc etc ... Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba Link: https://lore.kernel.org/r/20210314111333.16551-3-daniel.lezcano@linaro.org --- drivers/thermal/devfreq_cooling.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index fed3121ff2a1..fb250ac16f50 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -25,11 +24,8 @@ #define HZ_PER_KHZ 1000 #define SCALE_ERROR_MITIGATION 100 -static DEFINE_IDA(devfreq_ida); - /** * struct devfreq_cooling_device - Devfreq cooling device - * @id: unique integer value corresponding to each * devfreq_cooling_device registered. * @cdev: Pointer to associated thermal cooling device. * @devfreq: Pointer to associated devfreq device. @@ -51,7 +47,6 @@ static DEFINE_IDA(devfreq_ida); * @em_pd: Energy Model for the associated Devfreq device */ struct devfreq_cooling_device { - int id; struct thermal_cooling_device *cdev; struct devfreq *devfreq; unsigned long cooling_state; @@ -363,7 +358,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, struct thermal_cooling_device *cdev; struct device *dev = df->dev.parent; struct devfreq_cooling_device *dfc; - char dev_name[THERMAL_NAME_LENGTH]; + char *name; int err, num_opps; dfc = kzalloc(sizeof(*dfc), GFP_KERNEL); @@ -407,30 +402,27 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, if (err < 0) goto free_table; - err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL); - if (err < 0) + cdev = ERR_PTR(-ENOMEM); + name = kasprintf(GFP_KERNEL, "devfreq-%s", dev_name(dev)); + if (!name) goto remove_qos_req; - dfc->id = err; - - snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id); - - cdev = thermal_of_cooling_device_register(np, dev_name, dfc, + cdev = thermal_of_cooling_device_register(np, name, dfc, &devfreq_cooling_ops); + kfree(name); + if (IS_ERR(cdev)) { err = PTR_ERR(cdev); dev_err(dev, "Failed to register devfreq cooling device (%d)\n", err); - goto release_ida; + goto remove_qos_req; } dfc->cdev = cdev; return cdev; -release_ida: - ida_simple_remove(&devfreq_ida, dfc->id); remove_qos_req: dev_pm_qos_remove_request(&dfc->req_max_freq); free_table: @@ -527,7 +519,6 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) dev = dfc->devfreq->dev.parent; thermal_cooling_device_unregister(dfc->cdev); - ida_simple_remove(&devfreq_ida, dfc->id); dev_pm_qos_remove_request(&dfc->req_max_freq); em_dev_unregister_perf_domain(dev); From 6fd1b186d900acf4cef9d3c23ec2839022a46345 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 14 Mar 2021 12:13:32 +0100 Subject: [PATCH 12/55] thermal/drivers/cpuidle_cooling: Use device name instead of auto-numbering Currently the naming of a cooling device is just a cooling technique followed by a number. When there are multiple cooling devices using the same technique, it is impossible to clearly identify the related device as this one is just a number. For instance: thermal-idle-0 thermal-idle-1 thermal-idle-2 thermal-idle-3 etc ... The 'thermal' prefix is redundant with the subsystem namespace. This patch removes the 'thermal prefix and changes the number by the device name. So the naming above becomes: idle-cpu0 idle-cpu1 idle-cpu2 idle-cpu3 etc ... Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba Acked-by: Viresh Kumar Link: https://lore.kernel.org/r/20210314111333.16551-4-daniel.lezcano@linaro.org --- drivers/thermal/cpuidle_cooling.c | 33 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c index 7ecab4b16b29..f32976163bad 100644 --- a/drivers/thermal/cpuidle_cooling.c +++ b/drivers/thermal/cpuidle_cooling.c @@ -9,9 +9,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -26,8 +26,6 @@ struct cpuidle_cooling_device { unsigned long state; }; -static DEFINE_IDA(cpuidle_ida); - /** * cpuidle_cooling_runtime - Running time computation * @idle_duration_us: CPU idle time to inject in microseconds @@ -174,10 +172,11 @@ static int __cpuidle_cooling_register(struct device_node *np, struct idle_inject_device *ii_dev; struct cpuidle_cooling_device *idle_cdev; struct thermal_cooling_device *cdev; + struct device *dev; unsigned int idle_duration_us = TICK_USEC; unsigned int latency_us = UINT_MAX; - char dev_name[THERMAL_NAME_LENGTH]; - int id, ret; + char *name; + int ret; idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL); if (!idle_cdev) { @@ -185,16 +184,10 @@ static int __cpuidle_cooling_register(struct device_node *np, goto out; } - id = ida_simple_get(&cpuidle_ida, 0, 0, GFP_KERNEL); - if (id < 0) { - ret = id; - goto out_kfree; - } - ii_dev = idle_inject_register(drv->cpumask); if (!ii_dev) { ret = -EINVAL; - goto out_id; + goto out_kfree; } of_property_read_u32(np, "duration-us", &idle_duration_us); @@ -205,24 +198,30 @@ static int __cpuidle_cooling_register(struct device_node *np, idle_cdev->ii_dev = ii_dev; - snprintf(dev_name, sizeof(dev_name), "thermal-idle-%d", id); + dev = get_cpu_device(cpumask_first(drv->cpumask)); - cdev = thermal_of_cooling_device_register(np, dev_name, idle_cdev, + name = kasprintf(GFP_KERNEL, "idle-%s", dev_name(dev)); + if (!name) { + ret = -ENOMEM; + goto out_unregister; + } + + cdev = thermal_of_cooling_device_register(np, name, idle_cdev, &cpuidle_cooling_ops); + kfree(name); + if (IS_ERR(cdev)) { ret = PTR_ERR(cdev); goto out_unregister; } pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n", - dev_name, idle_duration_us, latency_us); + name, idle_duration_us, latency_us); return 0; out_unregister: idle_inject_unregister(ii_dev); -out_id: - ida_simple_remove(&cpuidle_ida, id); out_kfree: kfree(idle_cdev); out: From 87602aeb8ad5bb1b2e23285a9d1322ac033f86c9 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 14 Mar 2021 12:13:33 +0100 Subject: [PATCH 13/55] thermal/drivers/cpufreq_cooling: Remove unused list There is a list with the purpose of grouping the cpufreq cooling device together as described in the comments but actually it is unused, the code evolved since 2012 and the list was no longer needed. Delete the remaining unused list related code. Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba Link: https://lore.kernel.org/r/20210314111333.16551-5-daniel.lezcano@linaro.org --- drivers/thermal/cpufreq_cooling.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 3f5f1dce1320..f3d308427665 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -59,7 +59,6 @@ struct time_in_idle { * @cdev: thermal_cooling_device pointer to keep track of the * registered cooling device. * @policy: cpufreq policy. - * @node: list_head to link all cpufreq_cooling_device together. * @idle_time: idle time stats * @qos_req: PM QoS contraint to apply * @@ -72,16 +71,12 @@ struct cpufreq_cooling_device { unsigned int max_level; struct em_perf_domain *em; struct cpufreq_policy *policy; - struct list_head node; #ifndef CONFIG_SMP struct time_in_idle *idle_time; #endif struct freq_qos_request qos_req; }; -static DEFINE_MUTEX(cooling_list_lock); -static LIST_HEAD(cpufreq_cdev_list); - #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR /** * get_level: Find the level for a particular frequency @@ -602,10 +597,6 @@ __cpufreq_cooling_register(struct device_node *np, if (IS_ERR(cdev)) goto remove_qos_req; - mutex_lock(&cooling_list_lock); - list_add(&cpufreq_cdev->node, &cpufreq_cdev_list); - mutex_unlock(&cooling_list_lock); - return cdev; remove_qos_req: @@ -697,10 +688,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) cpufreq_cdev = cdev->devdata; - mutex_lock(&cooling_list_lock); - list_del(&cpufreq_cdev->node); - mutex_unlock(&cooling_list_lock); - thermal_cooling_device_unregister(cdev); freq_qos_remove_request(&cpufreq_cdev->qos_req); free_idle_time(cpufreq_cdev); From 6e3e14c9385c3cfb35f9da4f495acdd21f9bc25b Mon Sep 17 00:00:00 2001 From: "jeson.gao" Date: Mon, 15 Mar 2021 16:25:37 +0800 Subject: [PATCH 14/55] thermal/core/power_allocator: Using round the division when re-divvying up power The division is used directly in re-divvying up power, the decimal part will be discarded, devices will get less than the extra_actor_power - 1. if using round the division to make the calculation more accurate. For example: actor0 received more than its max_power, it has the extra_power 759 actor1 received less than its max_power, it require extra_actor_power 395 actor2 received less than its max_power, it require extra_actor_power 365 actor1 and actor2 require the total capped_extra_power 760 using division in re-divvying up power actor1 would actually get the extra_actor_power 394 actor2 would actually get the extra_actor_power 364 if using round the division in re-divvying up power actor1 would actually get the extra_actor_power 394 actor2 would actually get the extra_actor_power 365 Signed-off-by: Jeson Gao Reviewed-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/1615796737-4688-1-git-send-email-gao.yunxiao6@gmail.com --- drivers/thermal/gov_power_allocator.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 92acae53df49..2802a0e13c88 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -374,9 +374,11 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors, */ extra_power = min(extra_power, capped_extra_power); if (capped_extra_power > 0) - for (i = 0; i < num_actors; i++) - granted_power[i] += (extra_actor_power[i] * - extra_power) / capped_extra_power; + for (i = 0; i < num_actors; i++) { + u64 extra_range = (u64)extra_actor_power[i] * extra_power; + granted_power[i] += DIV_ROUND_CLOSEST_ULL(extra_range, + capped_extra_power); + } } static int allocate_power(struct thermal_zone_device *tz, From 007d81a4519f04fa5ced5e9e28bf70cd753c398d Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 25 Feb 2021 22:31:19 +0100 Subject: [PATCH 15/55] thermal/drivers/qcom/tsens_v1: Enable sensor 3 on MSM8976 The sensor *is* in fact used and does report temperature. Signed-off-by: Konrad Dybcio Acked-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210225213119.116550-1-konrad.dybcio@somainline.org --- drivers/thermal/qcom/tsens-v1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 3c19a3800c6d..573e261ccca7 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -380,11 +380,11 @@ static const struct tsens_ops ops_8976 = { .get_temp = get_temp_tsens_valid, }; -/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */ +/* Valid for both MSM8956 and MSM8976. */ struct tsens_plat_data data_8976 = { .num_sensors = 11, .ops = &ops_8976, - .hw_ids = (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10}, + .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, }; From ef6e01af398acff63eb33c58e72839e50a3e1c4b Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Fri, 19 Mar 2021 11:37:11 -0400 Subject: [PATCH 16/55] MAINTAINERS: Add co-maintainer for Qualcomm tsens thermal drivers Add myself as the maintainer for Qualcomm tsens drivers so that I can help Daniel by taking care of/reviewing changes to these drivers. Signed-off-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210319153711.2836652-1-thara.gopinath@linaro.org --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index d92f85ca831d..f919aa861165 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14891,6 +14891,7 @@ F: include/linux/if_rmnet.h QUALCOMM TSENS THERMAL DRIVER M: Amit Kucheria +M: Thara Gopinath L: linux-pm@vger.kernel.org L: linux-arm-msm@vger.kernel.org S: Maintained From d44616c6cc3e35eea03ecfe9040edfa2b486a059 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 19 Mar 2021 21:22:57 +0100 Subject: [PATCH 17/55] thermal/core: Fix memory leak in the error path Fix the following error: smatch warnings: drivers/thermal/thermal_core.c:1020 __thermal_cooling_device_register() warn: possible memory leak of 'cdev' by freeing the cdev when exiting the function in the error path. Fixes: 584837618100 ("thermal/drivers/core: Use a char pointer for the cooling device name") Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210319202257.890848-1-daniel.lezcano@linaro.org --- drivers/thermal/thermal_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index c8d4010940ef..3566fd291399 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1017,6 +1017,7 @@ __thermal_cooling_device_register(struct device_node *np, out_ida_remove: ida_simple_remove(&thermal_cdev_ida, cdev->id); out_kfree_cdev: + kfree(cdev); return ERR_PTR(ret); } From 9aa80ab2c0ba67ce3281aee604b543293f71390d Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 19 Mar 2021 21:24:23 +0100 Subject: [PATCH 18/55] thermal/drivers/devfreq_cooling: Fix wrong return on error path The following error is reported by kbuild: smatch warnings: drivers/thermal/devfreq_cooling.c:433 of_devfreq_cooling_register_power() warn: passing zero to 'ERR_PTR' Fix the error code by the setting the 'err' variable instead of 'cdev'. Fixes: f8d354e821b2 ("thermal/drivers/devfreq_cooling: Use device name instead of auto-numbering") Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210319202424.890968-1-daniel.lezcano@linaro.org --- drivers/thermal/devfreq_cooling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index fb250ac16f50..3a788ac4f525 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -402,7 +402,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, if (err < 0) goto free_table; - cdev = ERR_PTR(-ENOMEM); + err = -ENOMEM; name = kasprintf(GFP_KERNEL, "devfreq-%s", dev_name(dev)); if (!name) goto remove_qos_req; From 6cc7b38c0ca3187abd07af849ec179b42337bcf6 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 19 Mar 2021 21:25:22 +0100 Subject: [PATCH 19/55] thermal/drivers/cpuidle_cooling: Fix use after error When the function successfully finishes it logs an information about the registration of the cooling device and use its name to build the message. Unfortunately it was freed right before: drivers/thermal/cpuidle_cooling.c:218 __cpuidle_cooling_register() warn: 'name' was already freed. Fix this by freeing after the message happened. Fixes: 6fd1b186d900 ("thermal/drivers/cpuidle_cooling: Use device name instead of auto-numbering") Reported-by: Dan Carpenter Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar Link: https://lore.kernel.org/r/20210319202522.891061-1-daniel.lezcano@linaro.org --- drivers/thermal/cpuidle_cooling.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c index f32976163bad..4f41102e8b16 100644 --- a/drivers/thermal/cpuidle_cooling.c +++ b/drivers/thermal/cpuidle_cooling.c @@ -208,18 +208,20 @@ static int __cpuidle_cooling_register(struct device_node *np, cdev = thermal_of_cooling_device_register(np, name, idle_cdev, &cpuidle_cooling_ops); - kfree(name); - if (IS_ERR(cdev)) { ret = PTR_ERR(cdev); - goto out_unregister; + goto out_kfree_name; } pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n", name, idle_duration_us, latency_us); + kfree(name); + return 0; +out_kfree_name: + kfree(name); out_unregister: idle_inject_unregister(ii_dev); out_kfree: From 957781612e44f9525a8c7ed52086ab4caaa301f6 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 19 Mar 2021 23:08:01 +0100 Subject: [PATCH 20/55] dt-bindings: tsens: qcom: Document MDM9607 compatible Add the compatible for MDM9607. Signed-off-by: Konrad Dybcio Signed-off-by: Daniel Lezcano Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210319220802.198215-1-konrad.dybcio@somainline.org --- Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index 95462e071ab4..8ad9dc139c23 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -22,6 +22,7 @@ properties: - description: v0.1 of TSENS items: - enum: + - qcom,mdm9607-tsens - qcom,msm8916-tsens - qcom,msm8939-tsens - qcom,msm8974-tsens @@ -94,6 +95,7 @@ allOf: compatible: contains: enum: + - qcom,mdm9607-tsens - qcom,msm8916-tsens - qcom,msm8974-tsens - qcom,msm8976-tsens From 4481b39f9390e82c73fb03193b4a5e7e242d22a4 Mon Sep 17 00:00:00 2001 From: Hao Fang Date: Tue, 30 Mar 2021 14:45:33 +0800 Subject: [PATCH 21/55] thermal/drivers/hisi: Use the correct HiSilicon copyright s/Hisilicon/HiSilicon/g. It should use capital S, according to https://www.hisilicon.com/en/terms-of-use. Signed-off-by: Hao Fang Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/1617086733-2705-1-git-send-email-fanghao11@huawei.com --- drivers/thermal/hisi_thermal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index ee05950afd2f..d902db9f267f 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -1,7 +1,7 @@ /* - * Hisilicon thermal sensor driver + * HiSilicon thermal sensor driver * - * Copyright (c) 2014-2015 Hisilicon Limited. + * Copyright (c) 2014-2015 HiSilicon Limited. * Copyright (c) 2014-2015 Linaro Limited. * * Xinwei Kong @@ -672,5 +672,5 @@ module_platform_driver(hisi_thermal_driver); MODULE_AUTHOR("Xinwei Kong "); MODULE_AUTHOR("Leo Yan "); -MODULE_DESCRIPTION("Hisilicon thermal driver"); +MODULE_DESCRIPTION("HiSilicon thermal driver"); MODULE_LICENSE("GPL v2"); From 34ab17cc6c2c1ac93d7e5d53bb972df9a968f085 Mon Sep 17 00:00:00 2001 From: brian-sy yang Date: Tue, 29 Dec 2020 13:08:31 +0800 Subject: [PATCH 22/55] thermal/drivers/cpufreq_cooling: Fix slab OOB issue Slab OOB issue is scanned by KASAN in cpu_power_to_freq(). If power is limited below the power of OPP0 in EM table, it will cause slab out-of-bound issue with negative array index. Return the lowest frequency if limited power cannot found a suitable OPP in EM table to fix this issue. Backtrace: [] die+0x104/0x5ac [] bug_handler+0x64/0xd0 [] brk_handler+0x160/0x258 [] do_debug_exception+0x248/0x3f0 [] el1_dbg+0x14/0xbc [] __kasan_report+0x1dc/0x1e0 [] kasan_report+0x10/0x20 [] __asan_report_load8_noabort+0x18/0x28 [] cpufreq_power2state+0x180/0x43c [] power_actor_set_power+0x114/0x1d4 [] allocate_power+0xaec/0xde0 [] power_allocator_throttle+0x3ec/0x5a4 [] handle_thermal_trip+0x160/0x294 [] thermal_zone_device_check+0xe4/0x154 [] process_one_work+0x5e4/0xe28 [] worker_thread+0xa4c/0xfac [] kthread+0x33c/0x358 [] ret_from_fork+0xc/0x18 Fixes: 371a3bc79c11b ("thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power") Signed-off-by: brian-sy yang Signed-off-by: Michael Kao Reviewed-by: Lukasz Luba Cc: stable@vger.kernel.org #v5.7 Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20201229050831.19493-1-michael.kao@mediatek.com --- drivers/thermal/cpufreq_cooling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index f3d308427665..eeb4e4b76c0b 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -116,7 +116,7 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev, { int i; - for (i = cpufreq_cdev->max_level; i >= 0; i--) { + for (i = cpufreq_cdev->max_level; i > 0; i--) { if (power >= cpufreq_cdev->em->table[i].power) break; } From aa92b3310c55b21153ca1514719ff8d5dfe74bd7 Mon Sep 17 00:00:00 2001 From: David Collins Date: Wed, 29 Jul 2020 09:52:52 -0700 Subject: [PATCH 23/55] thermal/drivers/qcom-spmi-temp-alarm: Add support for GEN2 rev 1 PMIC peripherals Add support for TEMP_ALARM GEN2 PMIC peripherals with digital major revision 1. This revision utilizes a different temperature threshold mapping than earlier revisions. Signed-off-by: David Collins Signed-off-by: Guru Das Srinagesh Reviewed-by: Stephen Boyd Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/69c90a004b3f5b7ae282f5ec5ca2920a48f23e02.1596040416.git.gurus@codeaurora.org --- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 91 ++++++++++++++------- 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 6dc879fea9c8..7419e196dbb0 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -17,6 +17,7 @@ #include "../thermal_core.h" +#define QPNP_TM_REG_DIG_MAJOR 0x01 #define QPNP_TM_REG_TYPE 0x04 #define QPNP_TM_REG_SUBTYPE 0x05 #define QPNP_TM_REG_STATUS 0x08 @@ -38,26 +39,30 @@ #define ALARM_CTRL_FORCE_ENABLE BIT(7) -/* - * Trip point values based on threshold control - * 0 = {105 C, 125 C, 145 C} - * 1 = {110 C, 130 C, 150 C} - * 2 = {115 C, 135 C, 155 C} - * 3 = {120 C, 140 C, 160 C} -*/ -#define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */ -#define TEMP_STAGE_HYSTERESIS 2000 +#define THRESH_COUNT 4 +#define STAGE_COUNT 3 -#define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */ -#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ +/* Over-temperature trip point values in mC */ +static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = { + { 105000, 125000, 145000 }, + { 110000, 130000, 150000 }, + { 115000, 135000, 155000 }, + { 120000, 140000, 160000 }, +}; + +static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = { + { 90000, 110000, 140000 }, + { 95000, 115000, 145000 }, + { 100000, 120000, 150000 }, + { 105000, 125000, 155000 }, +}; + +#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ #define THRESH_MIN 0 #define THRESH_MAX 3 -/* Stage 2 Threshold Min: 125 C */ -#define STAGE2_THRESHOLD_MIN 125000 -/* Stage 2 Threshold Max: 140 C */ -#define STAGE2_THRESHOLD_MAX 140000 +#define TEMP_STAGE_HYSTERESIS 2000 /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ #define DEFAULT_TEMP 37000 @@ -77,6 +82,7 @@ struct qpnp_tm_chip { bool initialized; struct iio_channel *adc; + const long (*temp_map)[THRESH_COUNT][STAGE_COUNT]; }; /* This array maps from GEN2 alarm state to GEN1 alarm stage */ @@ -100,6 +106,23 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) return regmap_write(chip->map, chip->base + addr, data); } +/** + * qpnp_tm_decode_temp() - return temperature in mC corresponding to the + * specified over-temperature stage + * @chip: Pointer to the qpnp_tm chip + * @stage: Over-temperature stage + * + * Return: temperature in mC + */ +static long qpnp_tm_decode_temp(struct qpnp_tm_chip *chip, unsigned int stage) +{ + if (!chip->temp_map || chip->thresh >= THRESH_COUNT || stage == 0 || + stage > STAGE_COUNT) + return 0; + + return (*chip->temp_map)[chip->thresh][stage - 1]; +} + /** * qpnp_tm_get_temp_stage() - return over-temperature stage * @chip: Pointer to the qpnp_tm chip @@ -149,14 +172,12 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) if (stage_new > stage_old) { /* increasing stage, use lower bound */ - chip->temp = (stage_new - 1) * TEMP_STAGE_STEP + - chip->thresh * TEMP_THRESH_STEP + - TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; + chip->temp = qpnp_tm_decode_temp(chip, stage_new) + + TEMP_STAGE_HYSTERESIS; } else if (stage_new < stage_old) { /* decreasing stage, use upper bound */ - chip->temp = stage_new * TEMP_STAGE_STEP + - chip->thresh * TEMP_THRESH_STEP - - TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; + chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1) + - TEMP_STAGE_HYSTERESIS; } chip->stage = stage; @@ -199,26 +220,28 @@ static int qpnp_tm_get_temp(void *data, int *temp) static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, int temp) { - u8 reg; + long stage2_threshold_min = (*chip->temp_map)[THRESH_MIN][1]; + long stage2_threshold_max = (*chip->temp_map)[THRESH_MAX][1]; bool disable_s2_shutdown = false; + u8 reg; WARN_ON(!mutex_is_locked(&chip->lock)); /* * Default: S2 and S3 shutdown enabled, thresholds at - * 105C/125C/145C, monitoring at 25Hz + * lowest threshold set, monitoring at 25Hz */ reg = SHUTDOWN_CTRL1_RATE_25HZ; if (temp == THERMAL_TEMP_INVALID || - temp < STAGE2_THRESHOLD_MIN) { + temp < stage2_threshold_min) { chip->thresh = THRESH_MIN; goto skip; } - if (temp <= STAGE2_THRESHOLD_MAX) { + if (temp <= stage2_threshold_max) { chip->thresh = THRESH_MAX - - ((STAGE2_THRESHOLD_MAX - temp) / + ((stage2_threshold_max - temp) / TEMP_THRESH_STEP); disable_s2_shutdown = true; } else { @@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) ? chip->stage : alarm_state_map[chip->stage]; if (stage) - chip->temp = chip->thresh * TEMP_THRESH_STEP + - (stage - 1) * TEMP_STAGE_STEP + - TEMP_THRESH_MIN; + chip->temp = qpnp_tm_decode_temp(chip, stage); crit_temp = qpnp_tm_get_critical_trip_temp(chip); ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); @@ -350,7 +371,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) { struct qpnp_tm_chip *chip; struct device_node *node; - u8 type, subtype; + u8 type, subtype, dig_major; u32 res; int ret, irq; @@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev) return ret; } + ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major); + if (ret < 0) { + dev_err(&pdev->dev, "could not read dig_major\n"); + return ret; + } + if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1 && subtype != QPNP_TM_SUBTYPE_GEN2)) { dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", @@ -408,6 +435,10 @@ static int qpnp_tm_probe(struct platform_device *pdev) } chip->subtype = subtype; + if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1) + chip->temp_map = &temp_map_gen2_v1; + else + chip->temp_map = &temp_map_gen1; /* * Register the sensor before initializing the hardware to be able to From 5b5f1121d60bca8305951930d7aa2123fb213cb0 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Wed, 17 Feb 2021 11:59:08 +0000 Subject: [PATCH 24/55] MAINTAINERS: update thermal CPU cooling section Update maintainers responsible for CPU cooling on Arm side. Signed-off-by: Lukasz Luba Acked-by: Viresh Kumar Acked-by: Javi Merino Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210217115908.22547-1-lukasz.luba@arm.com --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f919aa861165..6926711e9cf8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17771,7 +17771,7 @@ THERMAL/CPU_COOLING M: Amit Daniel Kachhap M: Daniel Lezcano M: Viresh Kumar -M: Javi Merino +R: Lukasz Luba L: linux-pm@vger.kernel.org S: Supported F: Documentation/driver-api/thermal/cpu-cooling-api.rst From f4136863e8899fa0554343201b78b9e197c78a78 Mon Sep 17 00:00:00 2001 From: Guangqing Zhu Date: Sun, 4 Apr 2021 20:54:31 +0800 Subject: [PATCH 25/55] thermal/drivers/tsens: Fix missing put_device error Fixes coccicheck error: drivers/thermal/qcom/tsens.c:759:4-10: ERROR: missing put_device; call of_find_device_by_node on line 715, but without a corresponding object release within this function. Fixes: a7ff82976122 ("drivers: thermal: tsens: Merge tsens-common.c into tsens.c") Signed-off-by: Guangqing Zhu Reviewed-by: Bjorn Andersson Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210404125431.12208-1-zhuguangqing83@gmail.com --- drivers/thermal/qcom/tsens.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index d8ce3a687b80..3c4c0516e58a 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -755,8 +755,10 @@ int __init init_common(struct tsens_priv *priv) for (i = VER_MAJOR; i <= VER_STEP; i++) { priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[i]); - if (IS_ERR(priv->rf[i])) - return PTR_ERR(priv->rf[i]); + if (IS_ERR(priv->rf[i])) { + ret = PTR_ERR(priv->rf[i]); + goto err_put_device; + } } ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor); if (ret) From c0612265295bc7bbbc7189ab811192fe77be8196 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Wed, 24 Mar 2021 13:43:08 +0100 Subject: [PATCH 26/55] dt-bindings: thermal: qcom-tsens: Add compatible for sm8350 Add tsens bindings for sm8350. Signed-off-by: Robert Foss Reviewed-by: Vinod Koul Acked-by: Rob Herring Reviewed-by: Bjorn Andersson Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210324124308.1265626-1-robert.foss@linaro.org --- Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index 8ad9dc139c23..fbd03cd3eb9b 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -44,6 +44,7 @@ properties: - qcom,sdm845-tsens - qcom,sm8150-tsens - qcom,sm8250-tsens + - qcom,sm8350-tsens - const: qcom,tsens-v2 reg: From a2149ab815fce21d0d83082818116519e44f87be Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 19 Mar 2021 23:08:02 +0100 Subject: [PATCH 27/55] thermal/drivers/qcom/tsens-v0_1: Add support for MDM9607 MDM9607 TSENS IP is very similar to the one of MSM8916, with minor adjustments to various tuning values. Signed-off-by: Konrad Dybcio Acked-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210319220802.198215-2-konrad.dybcio@somainline.org --- drivers/thermal/qcom/tsens-v0_1.c | 98 ++++++++++++++++++++++++++++++- drivers/thermal/qcom/tsens.c | 3 + drivers/thermal/qcom/tsens.h | 2 +- 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 4ffa2e2c0145..f136cb350238 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -190,6 +190,39 @@ #define BIT_APPEND 0x3 +/* eeprom layout data for mdm9607 */ +#define MDM9607_BASE0_MASK 0x000000ff +#define MDM9607_BASE1_MASK 0x000ff000 +#define MDM9607_BASE0_SHIFT 0 +#define MDM9607_BASE1_SHIFT 12 + +#define MDM9607_S0_P1_MASK 0x00003f00 +#define MDM9607_S1_P1_MASK 0x03f00000 +#define MDM9607_S2_P1_MASK 0x0000003f +#define MDM9607_S3_P1_MASK 0x0003f000 +#define MDM9607_S4_P1_MASK 0x0000003f + +#define MDM9607_S0_P2_MASK 0x000fc000 +#define MDM9607_S1_P2_MASK 0xfc000000 +#define MDM9607_S2_P2_MASK 0x00000fc0 +#define MDM9607_S3_P2_MASK 0x00fc0000 +#define MDM9607_S4_P2_MASK 0x00000fc0 + +#define MDM9607_S0_P1_SHIFT 8 +#define MDM9607_S1_P1_SHIFT 20 +#define MDM9607_S2_P1_SHIFT 0 +#define MDM9607_S3_P1_SHIFT 12 +#define MDM9607_S4_P1_SHIFT 0 + +#define MDM9607_S0_P2_SHIFT 14 +#define MDM9607_S1_P2_SHIFT 26 +#define MDM9607_S2_P2_SHIFT 6 +#define MDM9607_S3_P2_SHIFT 18 +#define MDM9607_S4_P2_SHIFT 6 + +#define MDM9607_CAL_SEL_MASK 0x00700000 +#define MDM9607_CAL_SEL_SHIFT 20 + static int calibrate_8916(struct tsens_priv *priv) { int base0 = 0, base1 = 0, i; @@ -452,7 +485,56 @@ static int calibrate_8974(struct tsens_priv *priv) return 0; } -/* v0.1: 8916, 8939, 8974 */ +static int calibrate_9607(struct tsens_priv *priv) +{ + int base, i; + u32 p1[5], p2[5]; + int mode = 0; + u32 *qfprom_cdata; + + qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); + if (IS_ERR(qfprom_cdata)) + return PTR_ERR(qfprom_cdata); + + mode = (qfprom_cdata[2] & MDM9607_CAL_SEL_MASK) >> MDM9607_CAL_SEL_SHIFT; + dev_dbg(priv->dev, "calibration mode is %d\n", mode); + + switch (mode) { + case TWO_PT_CALIB: + base = (qfprom_cdata[2] & MDM9607_BASE1_MASK) >> MDM9607_BASE1_SHIFT; + p2[0] = (qfprom_cdata[0] & MDM9607_S0_P2_MASK) >> MDM9607_S0_P2_SHIFT; + p2[1] = (qfprom_cdata[0] & MDM9607_S1_P2_MASK) >> MDM9607_S1_P2_SHIFT; + p2[2] = (qfprom_cdata[1] & MDM9607_S2_P2_MASK) >> MDM9607_S2_P2_SHIFT; + p2[3] = (qfprom_cdata[1] & MDM9607_S3_P2_MASK) >> MDM9607_S3_P2_SHIFT; + p2[4] = (qfprom_cdata[2] & MDM9607_S4_P2_MASK) >> MDM9607_S4_P2_SHIFT; + for (i = 0; i < priv->num_sensors; i++) + p2[i] = ((base + p2[i]) << 2); + fallthrough; + case ONE_PT_CALIB2: + base = (qfprom_cdata[0] & MDM9607_BASE0_MASK); + p1[0] = (qfprom_cdata[0] & MDM9607_S0_P1_MASK) >> MDM9607_S0_P1_SHIFT; + p1[1] = (qfprom_cdata[0] & MDM9607_S1_P1_MASK) >> MDM9607_S1_P1_SHIFT; + p1[2] = (qfprom_cdata[1] & MDM9607_S2_P1_MASK) >> MDM9607_S2_P1_SHIFT; + p1[3] = (qfprom_cdata[1] & MDM9607_S3_P1_MASK) >> MDM9607_S3_P1_SHIFT; + p1[4] = (qfprom_cdata[2] & MDM9607_S4_P1_MASK) >> MDM9607_S4_P1_SHIFT; + for (i = 0; i < priv->num_sensors; i++) + p1[i] = ((base + p1[i]) << 2); + break; + default: + for (i = 0; i < priv->num_sensors; i++) { + p1[i] = 500; + p2[i] = 780; + } + break; + } + + compute_intercept_slope(priv, p1, p2, mode); + kfree(qfprom_cdata); + + return 0; +} + +/* v0.1: 8916, 8939, 8974, 9607 */ static struct tsens_features tsens_v0_1_feat = { .ver_major = VER_0_1, @@ -540,3 +622,17 @@ struct tsens_plat_data data_8974 = { .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields, }; + +static const struct tsens_ops ops_9607 = { + .init = init_common, + .calibrate = calibrate_9607, + .get_temp = get_temp_common, +}; + +struct tsens_plat_data data_9607 = { + .num_sensors = 5, + .ops = &ops_9607, + .hw_ids = (unsigned int []){ 0, 1, 2, 3, 4 }, + .feat = &tsens_v0_1_feat, + .fields = tsens_v0_1_regfields, +}; diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 3c4c0516e58a..a5da6a74a465 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -897,6 +897,9 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume); static const struct of_device_id tsens_table[] = { { + .compatible = "qcom,mdm9607-tsens", + .data = &data_9607, + }, { .compatible = "qcom,msm8916-tsens", .data = &data_8916, }, { diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index f40b625f897e..cba64c33b4f9 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -585,7 +585,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp); extern struct tsens_plat_data data_8960; /* TSENS v0.1 targets */ -extern struct tsens_plat_data data_8916, data_8939, data_8974; +extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607; /* TSENS v1 targets */ extern struct tsens_plat_data data_tsens_v1, data_8976; From 8cd7ab2a1a393f37f2e2f4b3ff595d98c245b854 Mon Sep 17 00:00:00 2001 From: Ruiqi Gong Date: Thu, 8 Apr 2021 06:01:44 -0400 Subject: [PATCH 28/55] thermal/drivers/thermal_mmio: Remove redundant dev_err call in thermal_mmio_probe() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Reported-by: Hulk Robot Signed-off-by: Ruiqi Gong Acked-by: Talel Shenhar Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210408100144.7494-1-gongruiqi1@huawei.com --- drivers/thermal/thermal_mmio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/thermal/thermal_mmio.c b/drivers/thermal/thermal_mmio.c index d0bdf1ea3331..ded1dd0d4ef7 100644 --- a/drivers/thermal/thermal_mmio.c +++ b/drivers/thermal/thermal_mmio.c @@ -54,11 +54,8 @@ static int thermal_mmio_probe(struct platform_device *pdev) resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource); - if (IS_ERR(sensor->mmio_base)) { - dev_err(&pdev->dev, "failed to ioremap memory (%ld)\n", - PTR_ERR(sensor->mmio_base)); + if (IS_ERR(sensor->mmio_base)) return PTR_ERR(sensor->mmio_base); - } sensor_init_func = device_get_match_data(&pdev->dev); if (sensor_init_func) { From d1ab7c3a33d27e7b63fd6207d88852561072ae36 Mon Sep 17 00:00:00 2001 From: Ruiqi Gong Date: Thu, 8 Apr 2021 06:03:29 -0400 Subject: [PATCH 29/55] thermal/drivers/bcm2835: Remove redundant dev_err call in bcm2835_thermal_probe() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Reported-by: Hulk Robot Signed-off-by: Ruiqi Gong Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210408100329.7585-1-gongruiqi1@huawei.com --- drivers/thermal/broadcom/bcm2835_thermal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 3199977f1e73..c8e4344d5a3d 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -184,7 +184,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) data->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(data->regs)) { err = PTR_ERR(data->regs); - dev_err(&pdev->dev, "Could not get registers: %d\n", err); return err; } From 2eb87d75f980bcc7c2bd370661f8fcc4ec273ea5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 12 Apr 2021 20:59:01 +0800 Subject: [PATCH 30/55] thermal/drivers/intel: Introduce tcc cooling driver On Intel processors, the core frequency can be reduced below OS request, when the current temperature reaches the TCC (Thermal Control Circuit) activation temperature. The default TCC activation temperature is specified by MSR_IA32_TEMPERATURE_TARGET. However, it can be adjusted by specifying an offset in degrees C, using the TCC Offset bits in the same MSR register. This patch introduces a cooling devices driver that utilizes the TCC Offset feature. The bigger the current cooling state is, the lower the effective TCC activation temperature is, so that the processors can be throttled earlier before system critical overheats. Note that, on different platforms, the behavior might be different on how fast the setting takes effect, and how much the CPU frequency is reduced. This patch has been tested on a KabyLake mobile platform from me, and also on a CometLake platform from Doug. Signed-off-by: Zhang Rui Tested by: Doug Smythies Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210412125901.12549-1-rui.zhang@intel.com --- drivers/thermal/intel/Kconfig | 11 ++ drivers/thermal/intel/Makefile | 1 + drivers/thermal/intel/intel_tcc_cooling.c | 129 ++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 drivers/thermal/intel/intel_tcc_cooling.c diff --git a/drivers/thermal/intel/Kconfig b/drivers/thermal/intel/Kconfig index ce4f59213c7a..e4299ca3423c 100644 --- a/drivers/thermal/intel/Kconfig +++ b/drivers/thermal/intel/Kconfig @@ -79,3 +79,14 @@ config INTEL_PCH_THERMAL Enable this to support thermal reporting on certain intel PCHs. Thermal reporting device will provide temperature reading, programmable trip points and other information. + +config INTEL_TCC_COOLING + tristate "Intel TCC offset cooling Driver" + depends on X86 + help + Enable this to support system cooling by adjusting the effective TCC + activation temperature via the TCC Offset register, which is widely + supported on modern Intel platforms. + Note that, on different platforms, the behavior might be different + on how fast the setting takes effect, and how much the CPU frequency + is reduced. diff --git a/drivers/thermal/intel/Makefile b/drivers/thermal/intel/Makefile index ff2ad30ef397..5ff2afa388f7 100644 --- a/drivers/thermal/intel/Makefile +++ b/drivers/thermal/intel/Makefile @@ -10,4 +10,5 @@ obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL) += intel_quark_dts_thermal.o obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o +obj-$(CONFIG_INTEL_TCC_COOLING) += intel_tcc_cooling.o obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c new file mode 100644 index 000000000000..8ec10d55d421 --- /dev/null +++ b/drivers/thermal/intel/intel_tcc_cooling.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cooling device driver that activates the processor throttling by + * programming the TCC Offset register. + * Copyright (c) 2021, Intel Corporation. + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include + +#define TCC_SHIFT 24 +#define TCC_MASK (0x3fULL<<24) +#define TCC_PROGRAMMABLE BIT(30) + +static struct thermal_cooling_device *tcc_cdev; + +static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long + *state) +{ + *state = TCC_MASK >> TCC_SHIFT; + return 0; +} + +static int tcc_offset_update(int tcc) +{ + u64 val; + int err; + + err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); + if (err) + return err; + + val &= ~TCC_MASK; + val |= tcc << TCC_SHIFT; + + err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val); + if (err) + return err; + + return 0; +} + +static int tcc_get_cur_state(struct thermal_cooling_device *cdev, unsigned long + *state) +{ + u64 val; + int err; + + err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); + if (err) + return err; + + *state = (val & TCC_MASK) >> TCC_SHIFT; + return 0; +} + +static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long + state) +{ + return tcc_offset_update(state); +} + +static const struct thermal_cooling_device_ops tcc_cooling_ops = { + .get_max_state = tcc_get_max_state, + .get_cur_state = tcc_get_cur_state, + .set_cur_state = tcc_set_cur_state, +}; + +static const struct x86_cpu_id tcc_ids[] __initconst = { + X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, NULL), + {} +}; + +MODULE_DEVICE_TABLE(x86cpu, tcc_ids); + +static int __init tcc_cooling_init(void) +{ + int ret; + u64 val; + const struct x86_cpu_id *id; + + int err; + + id = x86_match_cpu(tcc_ids); + if (!id) + return -ENODEV; + + err = rdmsrl_safe(MSR_PLATFORM_INFO, &val); + if (err) + return err; + + if (!(val & TCC_PROGRAMMABLE)) + return -ENODEV; + + pr_info("Programmable TCC Offset detected\n"); + + tcc_cdev = + thermal_cooling_device_register("TCC Offset", NULL, + &tcc_cooling_ops); + if (IS_ERR(tcc_cdev)) { + ret = PTR_ERR(tcc_cdev); + return ret; + } + return 0; +} + +module_init(tcc_cooling_init) + +static void __exit tcc_cooling_exit(void) +{ + thermal_cooling_device_unregister(tcc_cdev); +} + +module_exit(tcc_cooling_exit) + +MODULE_DESCRIPTION("TCC offset cooling device Driver"); +MODULE_AUTHOR("Zhang Rui "); +MODULE_LICENSE("GPL v2"); From beaa41029fdea9d3e01af3a1a800538542d30869 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Fri, 9 Apr 2021 15:52:24 +0800 Subject: [PATCH 31/55] thermal/drivers/hisi: Remove redundant dev_err call in hisi_thermal_probe() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Reported-by: Hulk Robot Signed-off-by: Ye Bin Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210409075224.2109503-1-yebin10@huawei.com --- drivers/thermal/hisi_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index d902db9f267f..9a21ac0ceb11 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -572,10 +572,8 @@ static int hisi_thermal_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(data->regs)) { - dev_err(dev, "failed to get io address\n"); + if (IS_ERR(data->regs)) return PTR_ERR(data->regs); - } ret = data->ops->probe(data); if (ret) From fc88f7ad763a8ef2a20f8904bd241930b7696f86 Mon Sep 17 00:00:00 2001 From: dingsenjie Date: Wed, 14 Apr 2021 14:39:43 +0800 Subject: [PATCH 32/55] thermal/drivers/tegra: Use devm_platform_ioremap_resource_byname Use the devm_platform_ioremap_resource_byname() helper instead of calling platform_get_resource_byname() and devm_ioremap_resource() separately. Signed-off-by: dingsenjie Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210414063943.96244-1-dingsenjie@163.com --- drivers/thermal/tegra/soctherm.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 8b8fbd49679b..8e303e9d1dc0 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -2118,7 +2118,6 @@ static int tegra_soctherm_probe(struct platform_device *pdev) struct tegra_soctherm *tegra; struct thermal_zone_device *z; struct tsensor_shared_calib shared_calib; - struct resource *res; struct tegra_soctherm_soc *soc; unsigned int i; int err; @@ -2140,26 +2139,20 @@ static int tegra_soctherm_probe(struct platform_device *pdev) tegra->soc = soc; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "soctherm-reg"); - tegra->regs = devm_ioremap_resource(&pdev->dev, res); + tegra->regs = devm_platform_ioremap_resource_byname(pdev, "soctherm-reg"); if (IS_ERR(tegra->regs)) { dev_err(&pdev->dev, "can't get soctherm registers"); return PTR_ERR(tegra->regs); } if (!tegra->soc->use_ccroc) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "car-reg"); - tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res); + tegra->clk_regs = devm_platform_ioremap_resource_byname(pdev, "car-reg"); if (IS_ERR(tegra->clk_regs)) { dev_err(&pdev->dev, "can't get car clk registers"); return PTR_ERR(tegra->clk_regs); } } else { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "ccroc-reg"); - tegra->ccroc_regs = devm_ioremap_resource(&pdev->dev, res); + tegra->ccroc_regs = devm_platform_ioremap_resource_byname(pdev, "ccroc-reg"); if (IS_ERR(tegra->ccroc_regs)) { dev_err(&pdev->dev, "can't get ccroc registers"); return PTR_ERR(tegra->ccroc_regs); From 5a4a8235fee69b5a31cf1c56a9fa14b0d21a930c Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Tue, 6 Apr 2021 17:19:12 +0800 Subject: [PATCH 33/55] thermal/drivers/ti-soc-thermal/ti-bandgap: Rearrange all the included header files alphabetically For the sake of lisibility, reorder the header files alphabetically. Signed-off-by: Zhen Lei Reviewed-by: Keerthy Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210406091912.2583-2-thunder.leizhen@huawei.com --- drivers/thermal/ti-soc-thermal/ti-bandgap.c | 38 ++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c index d81af89166d2..008fbed5a118 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c @@ -9,29 +9,29 @@ * Eduardo Valentin */ -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "ti-bandgap.h" From bd5d553653e4151030ad2a94ef39a46b40c75a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 15 Apr 2021 13:21:21 +0200 Subject: [PATCH 34/55] dt-bindings: thermal: thermal-sensor: require "#thermal-sensor-cells" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This property is required for every thermal sensor as it's used when using phandles. Signed-off-by: Rafał Miłecki Acked-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210415112121.4999-1-zajec5@gmail.com --- Documentation/devicetree/bindings/thermal/thermal-sensor.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml b/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml index 9f747921e851..4bd345c71eb8 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml @@ -36,6 +36,9 @@ properties: containing several internal sensors. enum: [0, 1] +required: + - "#thermal-sensor-cells" + additionalProperties: true examples: From d473327f8f53418691cb2944a45da3e9ea51f9bf Mon Sep 17 00:00:00 2001 From: Lin Ruizhe Date: Wed, 21 Apr 2021 16:42:56 +0800 Subject: [PATCH 35/55] thermal/drivers/ti-soc-thermal/bandgap Remove unused variable 'val' The function ti_bandgap_restore_ctxt() restores the context at resume time. It checks if the sensor has a counter, reads the register but does nothing with the value. The block was probably omitted by the commit b87ea759a4cc. Remove the unused variable as well as the block using it as we can consider it as dead code. Reported-by: Hulk Robot Fixes: b87ea759a4cc ("staging: omap-thermal: fix context restore function") Signed-off-by: Lin Ruizhe Reviewed-by: Tony Lindgren Tested-by: Tony Lindgren Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210421084256.57591-1-linruizhe@huawei.com --- drivers/thermal/ti-soc-thermal/ti-bandgap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c index 008fbed5a118..ebe7cb70bfb6 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c @@ -1142,14 +1142,10 @@ static int ti_bandgap_restore_ctxt(struct ti_bandgap *bgp) for (i = 0; i < bgp->conf->sensor_count; i++) { struct temp_sensor_registers *tsr; struct temp_sensor_regval *rval; - u32 val = 0; rval = &bgp->regval[i]; tsr = bgp->conf->sensors[i].registers; - if (TI_BANDGAP_HAS(bgp, COUNTER)) - val = ti_bandgap_readl(bgp, tsr->bgap_counter); - if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG)) ti_bandgap_writel(bgp, rval->tshut_threshold, tsr->tshut_threshold); From 08e9fdfbb2248e93bbfaeb9cde284776085466cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 20 Apr 2021 23:01:04 +0200 Subject: [PATCH 36/55] dt-bindings: thermal: brcm,ns-thermal: Convert to the json-schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps validating DTS files. Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420210104.10555-1-zajec5@gmail.com --- .../bindings/thermal/brcm,ns-thermal.txt | 37 ------------ .../bindings/thermal/brcm,ns-thermal.yaml | 60 +++++++++++++++++++ 2 files changed, 60 insertions(+), 37 deletions(-) delete mode 100644 Documentation/devicetree/bindings/thermal/brcm,ns-thermal.txt create mode 100644 Documentation/devicetree/bindings/thermal/brcm,ns-thermal.yaml diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal.txt b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal.txt deleted file mode 100644 index 68e047170039..000000000000 --- a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal.txt +++ /dev/null @@ -1,37 +0,0 @@ -* Broadcom Northstar Thermal - -This binding describes thermal sensor that is part of Northstar's DMU (Device -Management Unit). - -Required properties: -- compatible : Must be "brcm,ns-thermal" -- reg : iomem address range of PVTMON registers -- #thermal-sensor-cells : Should be <0> - -Example: - -thermal: thermal@1800c2c0 { - compatible = "brcm,ns-thermal"; - reg = <0x1800c2c0 0x10>; - #thermal-sensor-cells = <0>; -}; - -thermal-zones { - cpu_thermal: cpu-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - coefficients = <(-556) 418000>; - thermal-sensors = <&thermal>; - - trips { - cpu-crit { - temperature = <125000>; - hysteresis = <0>; - type = "critical"; - }; - }; - - cooling-maps { - }; - }; -}; diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal.yaml b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal.yaml new file mode 100644 index 000000000000..fdeb333e010d --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/brcm,ns-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom Northstar Thermal + +maintainers: + - Rafał Miłecki + +description: + Thermal sensor that is part of Northstar's DMU (Device Management Unit). + +allOf: + - $ref: thermal-sensor.yaml# + +properties: + compatible: + const: brcm,ns-thermal + + reg: + description: PVTMON registers range + maxItems: 1 + + "#thermal-sensor-cells": + const: 0 + +unevaluatedProperties: false + +required: + - reg + +examples: + - | + thermal: thermal@1800c2c0 { + compatible = "brcm,ns-thermal"; + reg = <0x1800c2c0 0x10>; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + coefficients = <(-556) 418000>; + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; From 93effd83b6927c0252bb1e35aa3e116d3e2527bb Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Thu, 21 Jan 2021 21:34:04 -0500 Subject: [PATCH 37/55] iwlwifi: mvm: tt: Replace thermal_notify_framework thermal_notify_framework just updates for a single trip point where as thermal_zone_device_update does other bookkeeping like updating the temperature of the thermal zone and setting the next trip point etc. Replace thermal_notify_framework with thermal_zone_device_update as the later is more thorough. Acked-by: Kalle Valo Signed-off-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210122023406.3500424-2-thara.gopinath@linaro.org --- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 2a7339b12b13..398390c59344 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -146,8 +146,8 @@ void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) if (mvm->tz_device.tzone) { struct iwl_mvm_thermal_device *tz_dev = &mvm->tz_device; - thermal_notify_framework(tz_dev->tzone, - tz_dev->fw_trips_index[ths_crossed]); + thermal_zone_device_update(tz_dev->tzone, + THERMAL_TRIP_VIOLATED); } #endif /* CONFIG_THERMAL */ } From d60d6e7adfc3814f6de03c978ff1daab21478f87 Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Thu, 21 Jan 2021 21:34:05 -0500 Subject: [PATCH 38/55] thermal/core: Remove thermal_notify_framework thermal_notify_framework just updates for a single trip point where as thermal_zone_device_update does other bookkeeping like updating the temperature of the thermal zone and setting the next trip point. The only driver that was using thermal_notify_framework was updated in the previous patch to use thermal_zone_device_update instead. Since there are no users for thermal_notify_framework remove it. Signed-off-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210122023406.3500424-3-thara.gopinath@linaro.org --- drivers/thermal/thermal_core.c | 18 ------------------ include/linux/thermal.h | 5 ----- 2 files changed, 23 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 3566fd291399..d20b25f40d19 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -561,24 +561,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, } EXPORT_SYMBOL_GPL(thermal_zone_device_update); -/** - * thermal_notify_framework - Sensor drivers use this API to notify framework - * @tz: thermal zone device - * @trip: indicates which trip point has been crossed - * - * This function handles the trip events from sensor drivers. It starts - * throttling the cooling devices according to the policy configured. - * For CRITICAL and HOT trip points, this notifies the respective drivers, - * and does actual throttling for other trip points i.e ACTIVE and PASSIVE. - * The throttling policy is based on the configured platform data; if no - * platform data is provided, this uses the step_wise throttling policy. - */ -void thermal_notify_framework(struct thermal_zone_device *tz, int trip) -{ - handle_thermal_trip(tz, trip); -} -EXPORT_SYMBOL_GPL(thermal_notify_framework); - static void thermal_zone_device_check(struct work_struct *work) { struct thermal_zone_device *tz = container_of(work, struct diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 169502164364..d296f3b88fb9 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -390,7 +390,6 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); int thermal_zone_get_slope(struct thermal_zone_device *tz); int thermal_zone_get_offset(struct thermal_zone_device *tz); -void thermal_notify_framework(struct thermal_zone_device *, int); int thermal_zone_device_enable(struct thermal_zone_device *tz); int thermal_zone_device_disable(struct thermal_zone_device *tz); void thermal_zone_device_critical(struct thermal_zone_device *tz); @@ -436,10 +435,6 @@ static inline int thermal_zone_get_offset( struct thermal_zone_device *tz) { return -ENODEV; } -static inline void thermal_notify_framework(struct thermal_zone_device *tz, - int trip) -{ } - static inline int thermal_zone_device_enable(struct thermal_zone_device *tz) { return -ENODEV; } From a5655d90cf508598b5f5bbccd911924cf8dc9060 Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Thu, 21 Jan 2021 21:34:06 -0500 Subject: [PATCH 39/55] Documentation: driver-api: thermal: Remove thermal_notify_framework from documentation Since thermal_notify_framework is no longer supported/implemented remove the entry from sysfs-api.rst. Signed-off-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210122023406.3500424-4-thara.gopinath@linaro.org --- Documentation/driver-api/thermal/sysfs-api.rst | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst index 29fdd817ddb0..4b638c14bc16 100644 --- a/Documentation/driver-api/thermal/sysfs-api.rst +++ b/Documentation/driver-api/thermal/sysfs-api.rst @@ -730,17 +730,7 @@ This function returns the thermal_instance corresponding to a given {thermal_zone, cooling_device, trip_point} combination. Returns NULL if such an instance does not exist. -4.3. thermal_notify_framework ------------------------------ - -This function handles the trip events from sensor drivers. It starts -throttling the cooling devices according to the policy configured. -For CRITICAL and HOT trip points, this notifies the respective drivers, -and does actual throttling for other trip points i.e ACTIVE and PASSIVE. -The throttling policy is based on the configured platform data; if no -platform data is provided, this uses the step_wise throttling policy. - -4.4. thermal_cdev_update +4.3. thermal_cdev_update ------------------------ This function serves as an arbitrator to set the state of a cooling From 9d51769b2e75bb33c56c8f9ee933eca2d92b375b Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:35 +0200 Subject: [PATCH 40/55] thermal/drivers/tsens: Don't hardcode sensor slope Function compute_intercept_slope hardcode the sensor slope to SLOPE_DEFAULT. Change this and use the default value only if a slope is not defined. This is needed for tsens VER_0 that has a hardcoded slope table. Signed-off-by: Ansuel Smith Reviewed-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-2-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index a5da6a74a465..d6f802100641 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -85,7 +85,8 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1, "%s: sensor%d - data_point1:%#x data_point2:%#x\n", __func__, i, p1[i], p2[i]); - priv->sensor[i].slope = SLOPE_DEFAULT; + if (!priv->sensor[i].slope) + priv->sensor[i].slope = SLOPE_DEFAULT; if (mode == TWO_PT_CALIB) { /* * slope (m) = adc_code2 - adc_code1 (y2 - y1)/ From a0ed1411278db902a043e584c8ed320fe34346b6 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:36 +0200 Subject: [PATCH 41/55] thermal/drivers/tsens: Convert msm8960 to reg_field Convert msm9860 driver to reg_field to use the init_common function. Signed-off-by: Ansuel Smith Acked-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-3-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens-8960.c | 73 ++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c index 2a28a5af209e..0d0c2647da86 100644 --- a/drivers/thermal/qcom/tsens-8960.c +++ b/drivers/thermal/qcom/tsens-8960.c @@ -51,11 +51,22 @@ #define MIN_LIMIT_TH 0x0 #define MAX_LIMIT_TH 0xff -#define S0_STATUS_ADDR 0x3628 #define INT_STATUS_ADDR 0x363c #define TRDY_MASK BIT(7) #define TIMEOUT_US 100 +#define S0_STATUS_OFF 0x3628 +#define S1_STATUS_OFF 0x362c +#define S2_STATUS_OFF 0x3630 +#define S3_STATUS_OFF 0x3634 +#define S4_STATUS_OFF 0x3638 +#define S5_STATUS_OFF 0x3664 /* Sensors 5-10 found on apq8064/msm8960 */ +#define S6_STATUS_OFF 0x3668 +#define S7_STATUS_OFF 0x366c +#define S8_STATUS_OFF 0x3670 +#define S9_STATUS_OFF 0x3674 +#define S10_STATUS_OFF 0x3678 + static int suspend_8960(struct tsens_priv *priv) { int ret; @@ -179,7 +190,7 @@ static int init_8960(struct tsens_priv *priv) */ for (i = 0; i < priv->num_sensors; i++) { if (i >= 5) - priv->sensor[i].status = S0_STATUS_ADDR + 40; + priv->sensor[i].status = S0_STATUS_OFF + 40; priv->sensor[i].status += i * 4; } @@ -269,6 +280,63 @@ static int get_temp_8960(const struct tsens_sensor *s, int *temp) return -ETIMEDOUT; } +static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = { + /* ----- SROT ------ */ + /* No VERSION information */ + + /* CNTL */ + [TSENS_EN] = REG_FIELD(CNTL_ADDR, 0, 0), + [TSENS_SW_RST] = REG_FIELD(CNTL_ADDR, 1, 1), + /* 8960 has 5 sensors, 8660 has 11, we only handle 5 */ + [SENSOR_EN] = REG_FIELD(CNTL_ADDR, 3, 7), + + /* ----- TM ------ */ + /* INTERRUPT ENABLE */ + /* NO INTERRUPT ENABLE */ + + /* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */ + [LOW_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 0, 7), + [UP_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 8, 15), + /* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield + * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp + * MIN_THRESH_0 -> CRIT_THRESH_1 + * MAX_THRESH_0 -> CRIT_THRESH_0 + */ + [CRIT_THRESH_1] = REG_FIELD(THRESHOLD_ADDR, 16, 23), + [CRIT_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 24, 31), + + /* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */ + /* 1 == clear, 0 == normal operation */ + [LOW_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 9, 9), + [UP_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 10, 10), + + /* NO CRITICAL INTERRUPT SUPPORT on 8960 */ + + /* Sn_STATUS */ + [LAST_TEMP_0] = REG_FIELD(S0_STATUS_OFF, 0, 7), + [LAST_TEMP_1] = REG_FIELD(S1_STATUS_OFF, 0, 7), + [LAST_TEMP_2] = REG_FIELD(S2_STATUS_OFF, 0, 7), + [LAST_TEMP_3] = REG_FIELD(S3_STATUS_OFF, 0, 7), + [LAST_TEMP_4] = REG_FIELD(S4_STATUS_OFF, 0, 7), + [LAST_TEMP_5] = REG_FIELD(S5_STATUS_OFF, 0, 7), + [LAST_TEMP_6] = REG_FIELD(S6_STATUS_OFF, 0, 7), + [LAST_TEMP_7] = REG_FIELD(S7_STATUS_OFF, 0, 7), + [LAST_TEMP_8] = REG_FIELD(S8_STATUS_OFF, 0, 7), + [LAST_TEMP_9] = REG_FIELD(S9_STATUS_OFF, 0, 7), + [LAST_TEMP_10] = REG_FIELD(S10_STATUS_OFF, 0, 7), + + /* No VALID field on 8960 */ + /* TSENS_INT_STATUS bits: 1 == threshold violated */ + [MIN_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 0, 0), + [LOWER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 1, 1), + [UPPER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 2, 2), + /* No CRITICAL field on 8960 */ + [MAX_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 3, 3), + + /* TRDY: 1=ready, 0=in progress */ + [TRDY] = REG_FIELD(INT_STATUS_ADDR, 7, 7), +}; + static const struct tsens_ops ops_8960 = { .init = init_8960, .calibrate = calibrate_8960, @@ -282,4 +350,5 @@ static const struct tsens_ops ops_8960 = { struct tsens_plat_data data_8960 = { .num_sensors = 11, .ops = &ops_8960, + .fields = tsens_8960_regfields, }; From 53e2a20e4c41683b695145436b34aa4a14bbcd8c Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:37 +0200 Subject: [PATCH 42/55] thermal/drivers/tsens: Add VER_0 tsens version VER_0 is used to describe device based on tsens version before v0.1. These device are devices based on msm8960 for example apq8064 or ipq806x. Add support for VER_0 in tsens.c and set the right tsens feat in tsens-8960.c file. Signed-off-by: Ansuel Smith Reviewed-by: Thara Gopinath Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-4-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens-8960.c | 9 ++ drivers/thermal/qcom/tsens.c | 152 ++++++++++++++++++++++++------ drivers/thermal/qcom/tsens.h | 4 +- 3 files changed, 134 insertions(+), 31 deletions(-) diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c index 0d0c2647da86..0dd15e812208 100644 --- a/drivers/thermal/qcom/tsens-8960.c +++ b/drivers/thermal/qcom/tsens-8960.c @@ -347,8 +347,17 @@ static const struct tsens_ops ops_8960 = { .resume = resume_8960, }; +static struct tsens_features tsens_8960_feat = { + .ver_major = VER_0, + .crit_int = 0, + .adc = 1, + .srot_split = 0, + .max_sensors = 11, +}; + struct tsens_plat_data data_8960 = { .num_sensors = 11, .ops = &ops_8960, + .feat = &tsens_8960_feat, .fields = tsens_8960_regfields, }; diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index d6f802100641..83e01cb370f9 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -516,6 +517,15 @@ static irqreturn_t tsens_irq_thread(int irq, void *data) dev_dbg(priv->dev, "[%u] %s: no violation: %d\n", hw_id, __func__, temp); } + + if (tsens_version(priv) < VER_0_1) { + /* Constraint: There is only 1 interrupt control register for all + * 11 temperature sensor. So monitoring more than 1 sensor based + * on interrupts will yield inconsistent result. To overcome this + * issue we will monitor only sensor 0 which is the master sensor. + */ + break; + } } return IRQ_HANDLED; @@ -531,6 +541,13 @@ static int tsens_set_trips(void *_sensor, int low, int high) int high_val, low_val, cl_high, cl_low; u32 hw_id = s->hw_id; + if (tsens_version(priv) < VER_0_1) { + /* Pre v0.1 IP had a single register for each type of interrupt + * and thresholds + */ + hw_id = 0; + } + dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n", hw_id, __func__, low, high); @@ -585,18 +602,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp) u32 valid; int ret; - ret = regmap_field_read(priv->rf[valid_idx], &valid); - if (ret) - return ret; - while (!valid) { - /* Valid bit is 0 for 6 AHB clock cycles. - * At 19.2MHz, 1 AHB clock is ~60ns. - * We should enter this loop very, very rarely. - */ - ndelay(400); + /* VER_0 doesn't have VALID bit */ + if (tsens_version(priv) >= VER_0_1) { ret = regmap_field_read(priv->rf[valid_idx], &valid); if (ret) return ret; + while (!valid) { + /* Valid bit is 0 for 6 AHB clock cycles. + * At 19.2MHz, 1 AHB clock is ~60ns. + * We should enter this loop very, very rarely. + */ + ndelay(400); + ret = regmap_field_read(priv->rf[valid_idx], &valid); + if (ret) + return ret; + } } /* Valid bit is set, OK to read the temperature */ @@ -609,15 +629,29 @@ int get_temp_common(const struct tsens_sensor *s, int *temp) { struct tsens_priv *priv = s->priv; int hw_id = s->hw_id; - int last_temp = 0, ret; + int last_temp = 0, ret, trdy; + unsigned long timeout; - ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp); - if (ret) - return ret; + timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); + do { + if (tsens_version(priv) == VER_0) { + ret = regmap_field_read(priv->rf[TRDY], &trdy); + if (ret) + return ret; + if (!trdy) + continue; + } - *temp = code_to_degc(last_temp, s) * 1000; + ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp); + if (ret) + return ret; - return 0; + *temp = code_to_degc(last_temp, s) * 1000; + + return 0; + } while (time_before(jiffies, timeout)); + + return -ETIMEDOUT; } #ifdef CONFIG_DEBUG_FS @@ -739,18 +773,33 @@ int __init init_common(struct tsens_priv *priv) priv->tm_offset = 0x1000; } - res = platform_get_resource(op, IORESOURCE_MEM, 0); - tm_base = devm_ioremap_resource(dev, res); - if (IS_ERR(tm_base)) { - ret = PTR_ERR(tm_base); + if (tsens_version(priv) >= VER_0_1) { + res = platform_get_resource(op, IORESOURCE_MEM, 0); + tm_base = devm_ioremap_resource(dev, res); + if (IS_ERR(tm_base)) { + ret = PTR_ERR(tm_base); + goto err_put_device; + } + + priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config); + } else { /* VER_0 share the same gcc regs using a syscon */ + struct device *parent = priv->dev->parent; + + if (parent) + priv->tm_map = syscon_node_to_regmap(parent->of_node); + } + + if (IS_ERR_OR_NULL(priv->tm_map)) { + if (!priv->tm_map) + ret = -ENODEV; + else + ret = PTR_ERR(priv->tm_map); goto err_put_device; } - priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config); - if (IS_ERR(priv->tm_map)) { - ret = PTR_ERR(priv->tm_map); - goto err_put_device; - } + /* VER_0 have only tm_map */ + if (!priv->srot_map) + priv->srot_map = priv->tm_map; if (tsens_version(priv) > VER_0_1) { for (i = VER_MAJOR; i <= VER_STEP; i++) { @@ -772,6 +821,10 @@ int __init init_common(struct tsens_priv *priv) ret = PTR_ERR(priv->rf[TSENS_EN]); goto err_put_device; } + /* in VER_0 TSENS need to be explicitly enabled */ + if (tsens_version(priv) == VER_0) + regmap_field_write(priv->rf[TSENS_EN], 1); + ret = regmap_field_read(priv->rf[TSENS_EN], &enabled); if (ret) goto err_put_device; @@ -794,6 +847,19 @@ int __init init_common(struct tsens_priv *priv) goto err_put_device; } + priv->rf[TSENS_SW_RST] = + devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]); + if (IS_ERR(priv->rf[TSENS_SW_RST])) { + ret = PTR_ERR(priv->rf[TSENS_SW_RST]); + goto err_put_device; + } + + priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]); + if (IS_ERR(priv->rf[TRDY])) { + ret = PTR_ERR(priv->rf[TRDY]); + goto err_put_device; + } + /* This loop might need changes if enum regfield_ids is reordered */ for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) { for (i = 0; i < priv->feat->max_sensors; i++) { @@ -809,7 +875,7 @@ int __init init_common(struct tsens_priv *priv) } } - if (priv->feat->crit_int) { + if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) { /* Loop might need changes if enum regfield_ids is reordered */ for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) { for (i = 0; i < priv->feat->max_sensors; i++) { @@ -847,7 +913,11 @@ int __init init_common(struct tsens_priv *priv) } spin_lock_init(&priv->ul_lock); - tsens_enable_irq(priv); + + /* VER_0 interrupt doesn't need to be enabled */ + if (tsens_version(priv) >= VER_0_1) + tsens_enable_irq(priv); + tsens_debug_init(op); err_put_device: @@ -949,10 +1019,19 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname, if (irq == -ENXIO) ret = 0; } else { - ret = devm_request_threaded_irq(&pdev->dev, irq, - NULL, thread_fn, - IRQF_ONESHOT, - dev_name(&pdev->dev), priv); + /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */ + if (tsens_version(priv) == VER_0) + ret = devm_request_threaded_irq(&pdev->dev, irq, + thread_fn, NULL, + IRQF_TRIGGER_RISING, + dev_name(&pdev->dev), + priv); + else + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + thread_fn, IRQF_ONESHOT, + dev_name(&pdev->dev), + priv); + if (ret) dev_err(&pdev->dev, "%s: failed to get irq\n", __func__); @@ -981,6 +1060,19 @@ static int tsens_register(struct tsens_priv *priv) priv->ops->enable(priv, i); } + /* VER_0 require to set MIN and MAX THRESH + * These 2 regs are set using the: + * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C + * - CRIT_THRESH_1 for MIN THRESH hardcoded to 0°C + */ + if (tsens_version(priv) < VER_0_1) { + regmap_field_write(priv->rf[CRIT_THRESH_0], + tsens_mC_to_hw(priv->sensor, 120000)); + + regmap_field_write(priv->rf[CRIT_THRESH_1], + tsens_mC_to_hw(priv->sensor, 0)); + } + ret = tsens_register_irq(priv, "uplow", tsens_irq_thread); if (ret < 0) return ret; diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index cba64c33b4f9..1471a2c00f15 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -13,6 +13,7 @@ #define CAL_DEGC_PT2 120 #define SLOPE_FACTOR 1000 #define SLOPE_DEFAULT 3200 +#define TIMEOUT_US 100 #define THRESHOLD_MAX_ADC_CODE 0x3ff #define THRESHOLD_MIN_ADC_CODE 0x0 @@ -25,7 +26,8 @@ struct tsens_priv; /* IP version numbers in ascending order */ enum tsens_ver { - VER_0_1 = 0, + VER_0 = 0, + VER_0_1, VER_1_X, VER_2_X, }; From fdda131f8fbadee2dfc21f0787d11547b42a961e Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:38 +0200 Subject: [PATCH 43/55] thermal/drivers/tsens: Use init_common for msm8960 Use init_common and drop custom init for msm8960. Signed-off-by: Ansuel Smith Reviewed-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-5-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens-8960.c | 52 +------------------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c index 0dd15e812208..83746ee3fc88 100644 --- a/drivers/thermal/qcom/tsens-8960.c +++ b/drivers/thermal/qcom/tsens-8960.c @@ -173,56 +173,6 @@ static void disable_8960(struct tsens_priv *priv) regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); } -static int init_8960(struct tsens_priv *priv) -{ - int ret, i; - u32 reg_cntl; - - priv->tm_map = dev_get_regmap(priv->dev, NULL); - if (!priv->tm_map) - return -ENODEV; - - /* - * The status registers for each sensor are discontiguous - * because some SoCs have 5 sensors while others have more - * but the control registers stay in the same place, i.e - * directly after the first 5 status registers. - */ - for (i = 0; i < priv->num_sensors; i++) { - if (i >= 5) - priv->sensor[i].status = S0_STATUS_OFF + 40; - priv->sensor[i].status += i * 4; - } - - reg_cntl = SW_RST; - ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl); - if (ret) - return ret; - - if (priv->num_sensors > 1) { - reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); - reg_cntl &= ~SW_RST; - ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR, - CONFIG_MASK, CONFIG); - } else { - reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16); - reg_cntl &= ~CONFIG_MASK_8660; - reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660; - } - - reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT; - ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); - if (ret) - return ret; - - reg_cntl |= EN; - ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); - if (ret) - return ret; - - return 0; -} - static int calibrate_8960(struct tsens_priv *priv) { int i; @@ -338,7 +288,7 @@ static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = { }; static const struct tsens_ops ops_8960 = { - .init = init_8960, + .init = init_common, .calibrate = calibrate_8960, .get_temp = get_temp_8960, .enable = enable_8960, From 3d08f029fdbbd29c8b363ef4c8c4bfe3b8f79ad0 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:39 +0200 Subject: [PATCH 44/55] thermal/drivers/tsens: Fix bug in sensor enable for msm8960 Device based on tsens VER_0 contains a hardware bug that results in some problem with sensor enablement. Sensor id 6-11 can't be enabled selectively and all of them must be enabled in one step. Signed-off-by: Ansuel Smith Acked-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-6-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens-8960.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c index 83746ee3fc88..a96d37c2b674 100644 --- a/drivers/thermal/qcom/tsens-8960.c +++ b/drivers/thermal/qcom/tsens-8960.c @@ -27,9 +27,9 @@ #define EN BIT(0) #define SW_RST BIT(1) #define SENSOR0_EN BIT(3) +#define MEASURE_PERIOD BIT(18) #define SLP_CLK_ENA BIT(26) #define SLP_CLK_ENA_8660 BIT(24) -#define MEASURE_PERIOD 1 #define SENSOR0_SHIFT 3 /* INT_STATUS_ADDR bitmasks */ @@ -126,17 +126,34 @@ static int resume_8960(struct tsens_priv *priv) static int enable_8960(struct tsens_priv *priv, int id) { int ret; - u32 reg, mask; + u32 reg, mask = BIT(id); ret = regmap_read(priv->tm_map, CNTL_ADDR, ®); if (ret) return ret; - mask = BIT(id + SENSOR0_SHIFT); + /* HARDWARE BUG: + * On platforms with more than 6 sensors, all remaining sensors + * must be enabled together, otherwise undefined results are expected. + * (Sensor 6-7 disabled, Sensor 3 disabled...) In the original driver, + * all the sensors are enabled in one step hence this bug is not + * triggered. + */ + if (id > 5) + mask = GENMASK(10, 6); + + mask <<= SENSOR0_SHIFT; + + /* Sensors already enabled. Skip. */ + if ((reg & mask) == mask) + return 0; + ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST); if (ret) return ret; + reg |= MEASURE_PERIOD; + if (priv->num_sensors > 1) reg |= mask | SLP_CLK_ENA | EN; else From dfc1193d4dbd6c3cb68c944413146c940bde290a Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:40 +0200 Subject: [PATCH 45/55] thermal/drivers/tsens: Replace custom 8960 apis with generic apis Rework calibrate function to use common function. Derive the offset from a missing hardcoded slope table and the data from the nvmem calib efuses. Drop custom get_temp function and use generic api. Signed-off-by: Ansuel Smith Acked-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-7-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens-8960.c | 56 +++++++++---------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c index a96d37c2b674..58112f0dfe77 100644 --- a/drivers/thermal/qcom/tsens-8960.c +++ b/drivers/thermal/qcom/tsens-8960.c @@ -67,6 +67,13 @@ #define S9_STATUS_OFF 0x3674 #define S10_STATUS_OFF 0x3678 +/* Original slope - 350 to compensate mC to C inaccuracy */ +static u32 tsens_msm8960_slope[] = { + 826, 826, 804, 826, + 761, 782, 782, 849, + 782, 849, 782 + }; + static int suspend_8960(struct tsens_priv *priv) { int ret; @@ -194,9 +201,7 @@ static int calibrate_8960(struct tsens_priv *priv) { int i; char *data; - - ssize_t num_read = priv->num_sensors; - struct tsens_sensor *s = priv->sensor; + u32 p1[11]; data = qfprom_read(priv->dev, "calib"); if (IS_ERR(data)) @@ -204,49 +209,18 @@ static int calibrate_8960(struct tsens_priv *priv) if (IS_ERR(data)) return PTR_ERR(data); - for (i = 0; i < num_read; i++, s++) - s->offset = data[i]; + for (i = 0; i < priv->num_sensors; i++) { + p1[i] = data[i]; + priv->sensor[i].slope = tsens_msm8960_slope[i]; + } + + compute_intercept_slope(priv, p1, NULL, ONE_PT_CALIB); kfree(data); return 0; } -/* Temperature on y axis and ADC-code on x-axis */ -static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s) -{ - int slope, offset; - - slope = thermal_zone_get_slope(s->tzd); - offset = CAL_MDEGC - slope * s->offset; - - return adc_code * slope + offset; -} - -static int get_temp_8960(const struct tsens_sensor *s, int *temp) -{ - int ret; - u32 code, trdy; - struct tsens_priv *priv = s->priv; - unsigned long timeout; - - timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); - do { - ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy); - if (ret) - return ret; - if (!(trdy & TRDY_MASK)) - continue; - ret = regmap_read(priv->tm_map, s->status, &code); - if (ret) - return ret; - *temp = code_to_mdegC(code, s); - return 0; - } while (time_before(jiffies, timeout)); - - return -ETIMEDOUT; -} - static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = { /* ----- SROT ------ */ /* No VERSION information */ @@ -307,7 +281,7 @@ static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = { static const struct tsens_ops ops_8960 = { .init = init_common, .calibrate = calibrate_8960, - .get_temp = get_temp_8960, + .get_temp = get_temp_common, .enable = enable_8960, .disable = disable_8960, .suspend = suspend_8960, From 2ebd0982e6ba69d9f9c02a4a0aab705a5526283e Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:41 +0200 Subject: [PATCH 46/55] thermal/drivers/tsens: Drop unused define for msm8960 Drop unused define for msm8960 replaced by generic api and reg_field. Signed-off-by: Ansuel Smith Reviewed-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-8-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens-8960.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c index 58112f0dfe77..67c1748cdf73 100644 --- a/drivers/thermal/qcom/tsens-8960.c +++ b/drivers/thermal/qcom/tsens-8960.c @@ -10,8 +10,6 @@ #include #include "tsens.h" -#define CAL_MDEGC 30000 - #define CONFIG_ADDR 0x3640 #define CONFIG_ADDR_8660 0x3620 /* CONFIG_ADDR bitmasks */ @@ -21,39 +19,19 @@ #define CONFIG_SHIFT_8660 28 #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660) -#define STATUS_CNTL_ADDR_8064 0x3660 #define CNTL_ADDR 0x3620 /* CNTL_ADDR bitmasks */ #define EN BIT(0) #define SW_RST BIT(1) -#define SENSOR0_EN BIT(3) + #define MEASURE_PERIOD BIT(18) #define SLP_CLK_ENA BIT(26) #define SLP_CLK_ENA_8660 BIT(24) #define SENSOR0_SHIFT 3 -/* INT_STATUS_ADDR bitmasks */ -#define MIN_STATUS_MASK BIT(0) -#define LOWER_STATUS_CLR BIT(1) -#define UPPER_STATUS_CLR BIT(2) -#define MAX_STATUS_MASK BIT(3) - #define THRESHOLD_ADDR 0x3624 -/* THRESHOLD_ADDR bitmasks */ -#define THRESHOLD_MAX_LIMIT_SHIFT 24 -#define THRESHOLD_MIN_LIMIT_SHIFT 16 -#define THRESHOLD_UPPER_LIMIT_SHIFT 8 -#define THRESHOLD_LOWER_LIMIT_SHIFT 0 - -/* Initial temperature threshold values */ -#define LOWER_LIMIT_TH 0x50 -#define UPPER_LIMIT_TH 0xdf -#define MIN_LIMIT_TH 0x0 -#define MAX_LIMIT_TH 0xff #define INT_STATUS_ADDR 0x363c -#define TRDY_MASK BIT(7) -#define TIMEOUT_US 100 #define S0_STATUS_OFF 0x3628 #define S1_STATUS_OFF 0x362c From 6b3aeafbc12c18036809108e301efe8056249233 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:42 +0200 Subject: [PATCH 47/55] thermal/drivers/tsens: Add support for ipq8064-tsens Add support for tsens present in ipq806x SoCs based on generic msm8960 tsens driver. Signed-off-by: Ansuel Smith Reviewed-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-9-ansuelsmth@gmail.com --- drivers/thermal/qcom/tsens.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 83e01cb370f9..4c7ebd1d3f9c 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -968,6 +968,9 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume); static const struct of_device_id tsens_table[] = { { + .compatible = "qcom,ipq8064-tsens", + .data = &data_8960, + }, { .compatible = "qcom,mdm9607-tsens", .data = &data_9607, }, { From 26b2f03d2adf43d0dc9aeeb3fff54dcc9fcdb1f4 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 20 Apr 2021 20:33:43 +0200 Subject: [PATCH 48/55] dt-bindings: thermal: tsens: Document ipq8064 bindings Document the use of bindings used for msm8960 tsens based devices. msm8960 use the same gcc regs and is set as a child of the qcom gcc. Signed-off-by: Ansuel Smith Reviewed-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210420183343.2272-10-ansuelsmth@gmail.com --- .../bindings/thermal/qcom-tsens.yaml | 56 ++++++++++++++++--- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index fbd03cd3eb9b..0242fd91b622 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -19,6 +19,11 @@ description: | properties: compatible: oneOf: + - description: msm9860 TSENS based + items: + - enum: + - qcom,ipq8064-tsens + - description: v0.1 of TSENS items: - enum: @@ -75,7 +80,9 @@ properties: maxItems: 2 items: - const: calib - - const: calib_sel + - enum: + - calib_backup + - calib_sel "#qcom,sensors": description: @@ -90,12 +97,20 @@ properties: Number of cells required to uniquely identify the thermal sensors. Since we have multiple sensors this is set to 1 +required: + - compatible + - interrupts + - interrupt-names + - "#thermal-sensor-cells" + - "#qcom,sensors" + allOf: - if: properties: compatible: contains: enum: + - qcom,ipq8064-tsens - qcom,mdm9607-tsens - qcom,msm8916-tsens - qcom,msm8974-tsens @@ -117,17 +132,42 @@ allOf: interrupt-names: minItems: 2 -required: - - compatible - - reg - - "#qcom,sensors" - - interrupts - - interrupt-names - - "#thermal-sensor-cells" + - if: + properties: + compatible: + contains: + enum: + - qcom,tsens-v0_1 + - qcom,tsens-v1 + - qcom,tsens-v2 + + then: + required: + - reg additionalProperties: false examples: + - | + #include + // Example msm9860 based SoC (ipq8064): + gcc: clock-controller { + + /* ... */ + + tsens: thermal-sensor { + compatible = "qcom,ipq8064-tsens"; + + nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>; + nvmem-cell-names = "calib", "calib_backup"; + interrupts = ; + interrupt-names = "uplow"; + + #qcom,sensors = <11>; + #thermal-sensor-cells = <1>; + }; + }; + - | #include // Example 1 (legacy: for pre v1 IP): From b70dbf40eb075c596d86c42d93b86ff502290fc5 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 22 Apr 2021 12:43:06 +0100 Subject: [PATCH 49/55] thermal/core: Create a helper __thermal_cdev_update() without a lock There is a need to have a helper function which updates cooling device state from the governors code. With this change governor can use lock and unlock while calling helper function. This avoid unnecessary second time lock/unlock which was in previous solution present in governor implementation. This new helper function must be called with mutex 'cdev->lock' hold. The changed been discussed and part of code presented in thread: https://lore.kernel.org/linux-pm/20210419084536.25000-1-lukasz.luba@arm.com/ Co-developed-by: Daniel Lezcano Signed-off-by: Daniel Lezcano Signed-off-by: Lukasz Luba Link: https://lore.kernel.org/r/20210422114308.29684-2-lukasz.luba@arm.com --- drivers/thermal/thermal_core.h | 1 + drivers/thermal/thermal_helpers.c | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 86b8cef7310e..726e327b4205 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -66,6 +66,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); /** * struct thermal_trip - representation of a point in temperature domain diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index 7f50f412e02a..3edd047e144f 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -192,18 +192,11 @@ static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev, thermal_cooling_device_stats_update(cdev, target); } -void thermal_cdev_update(struct thermal_cooling_device *cdev) +void __thermal_cdev_update(struct thermal_cooling_device *cdev) { struct thermal_instance *instance; unsigned long target = 0; - mutex_lock(&cdev->lock); - /* cooling device is updated*/ - if (cdev->updated) { - mutex_unlock(&cdev->lock); - return; - } - /* Make sure cdev enters the deepest cooling state */ list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) { dev_dbg(&cdev->device, "zone%d->target=%lu\n", @@ -216,11 +209,25 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev) thermal_cdev_set_cur_state(cdev, target); - cdev->updated = true; - mutex_unlock(&cdev->lock); trace_cdev_update(cdev, target); dev_dbg(&cdev->device, "set to state %lu\n", target); } + +/** + * thermal_cdev_update - update cooling device state if needed + * @cdev: pointer to struct thermal_cooling_device + * + * Update the cooling device state if there is a need. + */ +void thermal_cdev_update(struct thermal_cooling_device *cdev) +{ + mutex_lock(&cdev->lock); + if (!cdev->updated) { + __thermal_cdev_update(cdev); + cdev->updated = true; + } + mutex_unlock(&cdev->lock); +} EXPORT_SYMBOL(thermal_cdev_update); /** From d3b60ed9b135e2c652115db691a87dc28b324bea Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 22 Apr 2021 12:43:07 +0100 Subject: [PATCH 50/55] thermal/core/power_allocator: Maintain the device statistics from going stale When the temperature is below the first activation trip point the cooling devices are not checked, so they cannot maintain fresh statistics. It leads into the situation, when temperature crosses first trip point, the statistics are stale and show state for very long period. This has impact on IPA algorithm calculation and wrong decisions. Thus, check the cooling devices even when the temperature is low, to refresh these statistics. Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422114308.29684-3-lukasz.luba@arm.com --- drivers/thermal/gov_power_allocator.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 2802a0e13c88..d393409fb786 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -575,15 +575,25 @@ static void allow_maximum_power(struct thermal_zone_device *tz) { struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; + u32 req_power; mutex_lock(&tz->lock); list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + struct thermal_cooling_device *cdev = instance->cdev; + if ((instance->trip != params->trip_max_desired_temperature) || (!cdev_is_power_actor(instance->cdev))) continue; instance->target = 0; mutex_lock(&instance->cdev->lock); + /* + * Call for updating the cooling devices local stats and avoid + * periods of dozen of seconds when those have not been + * maintained. + */ + cdev->ops->get_requested_power(cdev, &req_power); + instance->cdev->updated = false; mutex_unlock(&instance->cdev->lock); thermal_cdev_update(instance->cdev); From 0952177f2a1f63ba87a1940fac21768f402c0b94 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 22 Apr 2021 12:43:08 +0100 Subject: [PATCH 51/55] thermal/core/power_allocator: Update once cooling devices when temp is low The cooling device state change generates an event, also when there is no need, because temperature is low and device is not throttled. Avoid to unnecessary update the cooling device which means also not sending event. The cooling device state has not changed because the temperature is still below the first activation trip point value, so we can do this. Add a tracking mechanism to make sure it updates cooling devices only once - when the temperature dropps below first trip point. Reported-by: Daniel Lezcano Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422114308.29684-4-lukasz.luba@arm.com --- drivers/thermal/gov_power_allocator.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index d393409fb786..a6cdb2e892da 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -571,7 +571,7 @@ static void reset_pid_controller(struct power_allocator_params *params) params->prev_err = 0; } -static void allow_maximum_power(struct thermal_zone_device *tz) +static void allow_maximum_power(struct thermal_zone_device *tz, bool update) { struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; @@ -594,9 +594,10 @@ static void allow_maximum_power(struct thermal_zone_device *tz) */ cdev->ops->get_requested_power(cdev, &req_power); - instance->cdev->updated = false; + if (update) + __thermal_cdev_update(instance->cdev); + mutex_unlock(&instance->cdev->lock); - thermal_cdev_update(instance->cdev); } mutex_unlock(&tz->lock); } @@ -710,6 +711,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) int ret; int switch_on_temp, control_temp; struct power_allocator_params *params = tz->governor_data; + bool update; /* * We get called for every trip point but we only need to do @@ -721,9 +723,10 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, &switch_on_temp); if (!ret && (tz->temperature < switch_on_temp)) { + update = (tz->last_temperature >= switch_on_temp); tz->passive = 0; reset_pid_controller(params); - allow_maximum_power(tz); + allow_maximum_power(tz, update); return 0; } From fef05776eb02238dcad8d5514e666a42572c3f32 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 22 Apr 2021 16:36:22 +0100 Subject: [PATCH 52/55] thermal/core/fair share: Lock the thermal zone while looping over instances The tz->lock must be hold during the looping over the instances in that thermal zone. This lock was missing in the governor code since the beginning, so it's hard to point into a particular commit. CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422153624.6074-2-lukasz.luba@arm.com --- drivers/thermal/gov_fair_share.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index aaa07180ab48..645432ce6365 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -82,6 +82,8 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip) int total_instance = 0; int cur_trip_level = get_trip_level(tz); + mutex_lock(&tz->lock); + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { if (instance->trip != trip) continue; @@ -110,6 +112,8 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip) mutex_unlock(&instance->cdev->lock); thermal_cdev_update(cdev); } + + mutex_unlock(&tz->lock); return 0; } From 1a93369810660905f5e89b527cd709fa6832f7c8 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 22 Apr 2021 16:36:23 +0100 Subject: [PATCH 53/55] thermal/core/fair share: Use the lockless __thermal_cdev_update() function Use the new helper function and avoid unnecessery second lock/unlock, which was present in old approach with thermal_cdev_update(). Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422153624.6074-3-lukasz.luba@arm.com --- drivers/thermal/gov_fair_share.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index 645432ce6365..1e5abf4822be 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -107,10 +107,9 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip) instance->target = get_target_state(tz, cdev, percentage, cur_trip_level); - mutex_lock(&instance->cdev->lock); - instance->cdev->updated = false; - mutex_unlock(&instance->cdev->lock); - thermal_cdev_update(cdev); + mutex_lock(&cdev->lock); + __thermal_cdev_update(cdev); + mutex_unlock(&cdev->lock); } mutex_unlock(&tz->lock); From ab39c8853737158604e154ad3b03639e74082bd6 Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Thu, 22 Apr 2021 16:36:24 +0100 Subject: [PATCH 54/55] thermal/core/power allocator: Use the lockless __thermal_cdev_update() function Use the new helper function and avoid unnecessery second lock/unlock, which was present in old approach with thermal_cdev_update(). Signed-off-by: Lukasz Luba Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422153624.6074-4-lukasz.luba@arm.com --- drivers/thermal/gov_power_allocator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index a6cdb2e892da..13e375751d22 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -301,9 +301,8 @@ power_actor_set_power(struct thermal_cooling_device *cdev, instance->target = clamp_val(state, instance->lower, instance->upper); mutex_lock(&cdev->lock); - cdev->updated = false; + __thermal_cdev_update(cdev); mutex_unlock(&cdev->lock); - thermal_cdev_update(cdev); return 0; } From c310e546164d5cca4c12faf9582b75989b030b68 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 22 Apr 2021 13:04:12 +0100 Subject: [PATCH 55/55] thermal/drivers/mtk_thermal: Remove redundant initializations of several variables Several variables are being initialized with values that is never read and being updated later with a new value. The initializations are redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422120412.246291-1-colin.king@canonical.com --- drivers/thermal/mtk_thermal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 149c6d7fd5a0..97e8678ccf0e 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -573,12 +573,12 @@ static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw) static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw) { - s32 format_1 = 0; - s32 format_2 = 0; - s32 g_oe = 1; - s32 g_gain = 1; - s32 g_x_roomt = 0; - s32 tmp = 0; + s32 format_1; + s32 format_2; + s32 g_oe; + s32 g_gain; + s32 g_x_roomt; + s32 tmp; if (raw == 0) return 0;