From 03334ba8b425b2ad275c8f390cf83c7b081c3095 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Wed, 2 Jan 2019 00:34:03 +0000 Subject: thermal: hwmon: inline helpers when CONFIG_THERMAL_HWMON is not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid warnings like this: thermal_hwmon.h:29:1: warning: ‘thermal_remove_hwmon_sysfs’ defined but not used [-Wunused-function] thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) Fixes: 0dd88793aacd ("thermal: hwmon: move hwmon support to single file") Reviewed-by: Geert Uytterhoeven Signed-off-by: Eduardo Valentin --- drivers/thermal/thermal_hwmon.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_hwmon.h b/drivers/thermal/thermal_hwmon.h index 019f6f88224e..a160b9d62dd0 100644 --- a/drivers/thermal/thermal_hwmon.h +++ b/drivers/thermal/thermal_hwmon.h @@ -19,13 +19,13 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz); #else -static int +static inline int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) { return 0; } -static void +static inline void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) { } -- cgit v1.2.3-59-g8ed1b From d56c19d07e0bc3ceff366a49b7d7a2440c967b1b Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Sun, 21 Oct 2018 23:58:48 +0200 Subject: thermal: bcm2835: enable hwmon explicitly By defaul of-based thermal driver do not enable hwmon. This patch does this explicitly, so that the temperature can be read through the common hwmon sysfs. Signed-off-by: Matthias Brugger Acked-by: Stefan Wahren Signed-off-by: Eduardo Valentin --- drivers/thermal/broadcom/bcm2835_thermal.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 23ad4f9f2143..24b006a95142 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -27,6 +27,8 @@ #include #include +#include "../thermal_hwmon.h" + #define BCM2835_TS_TSENSCTL 0x00 #define BCM2835_TS_TSENSSTAT 0x04 @@ -275,6 +277,15 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tz); + /* + * Thermal_zone doesn't enable hwmon as default, + * enable it here + */ + tz->tzp->no_hwmon = false; + err = thermal_add_hwmon_sysfs(tz); + if (err) + goto err_tz; + bcm2835_thermal_debugfs(pdev); return 0; -- cgit v1.2.3-59-g8ed1b From adad7c7d6a0ce3e9308fc6596865cdf570b5c466 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 30 Oct 2018 17:08:51 +0100 Subject: thermal: broadcom: use devm_thermal_zone_of_sensor_register Using devm_thermal_zone_of_sensor_register allows to simplify some error handling code, drop a label, and drop the remove function. Signed-off-by: Julia Lawall Reviewed-by: Daniel Lezcano Signed-off-by: Eduardo Valentin --- drivers/thermal/broadcom/brcmstb_thermal.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c index 1919f91fa756..956eef8717bb 100644 --- a/drivers/thermal/broadcom/brcmstb_thermal.c +++ b/drivers/thermal/broadcom/brcmstb_thermal.c @@ -329,7 +329,8 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) priv->dev = &pdev->dev; platform_set_drvdata(pdev, priv); - thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops); + thermal = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, + &of_ops); if (IS_ERR(thermal)) { ret = PTR_ERR(thermal); dev_err(&pdev->dev, "could not register sensor: %d\n", ret); @@ -341,40 +342,23 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "could not get IRQ\n"); - ret = irq; - goto err; + return irq; } ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, brcmstb_tmon_irq_thread, IRQF_ONESHOT, DRV_NAME, priv); if (ret < 0) { dev_err(&pdev->dev, "could not request IRQ: %d\n", ret); - goto err; + return ret; } dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n"); return 0; - -err: - thermal_zone_of_sensor_unregister(&pdev->dev, thermal); - return ret; -} - -static int brcmstb_thermal_exit(struct platform_device *pdev) -{ - struct brcmstb_thermal_priv *priv = platform_get_drvdata(pdev); - struct thermal_zone_device *thermal = priv->thermal; - - if (thermal) - thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal); - - return 0; } static struct platform_driver brcmstb_thermal_driver = { .probe = brcmstb_thermal_probe, - .remove = brcmstb_thermal_exit, .driver = { .name = DRV_NAME, .of_match_table = brcmstb_thermal_id_table, -- cgit v1.2.3-59-g8ed1b From 24f1c13fa5f1599c373c53783f74de8a639f7999 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 7 Nov 2018 14:35:00 +0100 Subject: dt-bindings: thermal: rcar-gen3-thermal: All variants use 3 interrupts RZ/G2M also has 3 interrupts routed to the TSC, but the list was not updated to reflect this. Just drop the list, as this is the case for this TSC variant in all R-Car Gen3 and RZ/G2 SoCs. Fixes: be6af481f3b2d508 ("dt-bindings: thermal: rcar-gen3-thermal: Add r8a774a1 support") Signed-off-by: Geert Uytterhoeven Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Signed-off-by: Eduardo Valentin --- Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt index ad9a435afef4..b6ab60f6abbf 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt @@ -21,8 +21,7 @@ Required properties: Optional properties: -- interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N, - and V3H) +- interrupts : interrupts routed to the TSC (must be 3). - power-domain : Must contain a reference to the power domain. This property is mandatory if the thermal sensor instance is part of a controllable power domain. -- cgit v1.2.3-59-g8ed1b From ac31f6e25d4e9e9dfda9c0621242036b291b7754 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 13 Nov 2018 14:13:45 +0000 Subject: thermal: armada: Use PTR_ERR_OR_ZERO in armada_thermal_probe_legacy() Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Signed-off-by: YueHaibing Reviewed-by: Daniel Lezcano Signed-off-by: Eduardo Valentin --- drivers/thermal/armada_thermal.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 92f67d40f2e9..4b36a3022849 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -545,20 +545,14 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev, priv->syscon = devm_regmap_init_mmio(&pdev->dev, base, &armada_thermal_regmap_config); - if (IS_ERR(priv->syscon)) - return PTR_ERR(priv->syscon); - - return 0; + return PTR_ERR_OR_ZERO(priv->syscon); } static int armada_thermal_probe_syscon(struct platform_device *pdev, struct armada_thermal_priv *priv) { priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node); - if (IS_ERR(priv->syscon)) - return PTR_ERR(priv->syscon); - - return 0; + return PTR_ERR_OR_ZERO(priv->syscon); } static void armada_set_sane_name(struct platform_device *pdev, -- cgit v1.2.3-59-g8ed1b From 4ab248b3b10a58e379e2d32333fff99ea5ca256c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 15 Nov 2018 17:43:30 +0000 Subject: thermal: tsens: qcom: do not create duplicate regmap debugfs entries Regmap would use device name to create debugfs entries. If the device has multiple regmaps it is recommended to use name field in regmap_config. Fix this by providing name to the regmap configs correctly. Without this patch we would see below error on DB820c. qcom-tsens 4a9000.thermal-sensor: Failed to create 4a9000.thermal-sensor debugfs directory Signed-off-by: Srinivas Kandagatla Acked-by: Amit Kucheria Tested-by: Amit Kucheria Signed-off-by: Eduardo Valentin --- drivers/thermal/qcom/tsens-common.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c index 3be4be2e0465..78652cac7f3d 100644 --- a/drivers/thermal/qcom/tsens-common.c +++ b/drivers/thermal/qcom/tsens-common.c @@ -114,6 +114,14 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp) } static const struct regmap_config tsens_config = { + .name = "tm", + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static const struct regmap_config tsens_srot_config = { + .name = "srot", .reg_bits = 32, .val_bits = 32, .reg_stride = 4, @@ -139,8 +147,8 @@ int __init init_common(struct tsens_device *tmdev) if (IS_ERR(srot_base)) return PTR_ERR(srot_base); - tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, - srot_base, &tsens_config); + tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base, + &tsens_srot_config); if (IS_ERR(tmdev->srot_map)) return PTR_ERR(tmdev->srot_map); -- cgit v1.2.3-59-g8ed1b From c589c56671c914fbd6b56a6f92dce80edbbfdada Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 21 Nov 2018 05:49:36 +0000 Subject: thermal: imx: fix for dependency on cpu-freq The thermal driver is a standalone driver for monitoring SoC temperature by enabling thermal sensor, so it can be enabled even when CONFIG_CPU_FREQ is NOT set. So remove the dependency with CPU_THERMAL. Introduce dummy function of legacy cooling register/unregister to make thermal driver probe successfully when CONFIG_CPU_FREQ is NOT set. Signed-off-by: Anson Huang Acked-by: Viresh Kumar Reviewed-by: Daniel Lezcano Signed-off-by: Eduardo Valentin --- drivers/thermal/Kconfig | 2 +- drivers/thermal/imx_thermal.c | 47 ++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 5422523c03f8..93bd3bbefb9a 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -212,7 +212,7 @@ config HISI_THERMAL config IMX_THERMAL tristate "Temperature sensor driver for Freescale i.MX SoCs" - depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST + depends on ARCH_MXC || COMPILE_TEST depends on NVMEM || !NVMEM depends on MFD_SYSCON depends on OF diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 15661549eb67..c924396685a0 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -648,15 +648,24 @@ static const struct of_device_id of_imx_thermal_match[] = { }; MODULE_DEVICE_TABLE(of, of_imx_thermal_match); +#ifdef CONFIG_CPU_FREQ /* * Create cooling device in case no #cooling-cells property is available in * CPU node */ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) { - struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL); + struct device_node *np; int ret; + data->policy = cpufreq_cpu_get(0); + if (!data->policy) { + pr_debug("%s: CPUFreq policy not found\n", __func__); + return -EPROBE_DEFER; + } + + np = of_get_cpu_node(data->policy->cpu, NULL); + if (!np || !of_find_property(np, "#cooling-cells", NULL)) { data->cdev = cpufreq_cooling_register(data->policy); if (IS_ERR(data->cdev)) { @@ -669,6 +678,24 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) return 0; } +static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) +{ + cpufreq_cooling_unregister(data->cdev); + cpufreq_cpu_put(data->policy); +} + +#else + +static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) +{ + return 0; +} + +static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) +{ +} +#endif + static int imx_thermal_probe(struct platform_device *pdev) { struct imx_thermal_data *data; @@ -743,14 +770,11 @@ static int imx_thermal_probe(struct platform_device *pdev) regmap_write(map, data->socdata->sensor_ctrl + REG_SET, data->socdata->power_down_mask); - data->policy = cpufreq_cpu_get(0); - if (!data->policy) { - pr_debug("%s: CPUFreq policy not found\n", __func__); - return -EPROBE_DEFER; - } - ret = imx_thermal_register_legacy_cooling(data); if (ret) { + if (ret == -EPROBE_DEFER) + return ret; + dev_err(&pdev->dev, "failed to register cpufreq cooling device: %d\n", ret); return ret; @@ -762,7 +786,7 @@ static int imx_thermal_probe(struct platform_device *pdev) if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "failed to get thermal clk: %d\n", ret); - goto cpufreq_put; + goto legacy_cleanup; } /* @@ -775,7 +799,7 @@ static int imx_thermal_probe(struct platform_device *pdev) ret = clk_prepare_enable(data->thermal_clk); if (ret) { dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); - goto cpufreq_put; + goto legacy_cleanup; } data->tz = thermal_zone_device_register("imx_thermal_zone", @@ -829,9 +853,8 @@ thermal_zone_unregister: thermal_zone_device_unregister(data->tz); clk_disable: clk_disable_unprepare(data->thermal_clk); -cpufreq_put: - cpufreq_cooling_unregister(data->cdev); - cpufreq_cpu_put(data->policy); +legacy_cleanup: + imx_thermal_unregister_legacy_cooling(data); return ret; } -- cgit v1.2.3-59-g8ed1b From 925b38361852ef314e9ecc649e830ad5319e3a65 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 21 Nov 2018 05:49:40 +0000 Subject: thermal: imx: save one condition block for normal case of nvmem initialization Put return value checks of calling imx_init_from_nvmem_cells() into one block to save one condition block for normal case. Signed-off-by: Anson Huang Acked-by: Viresh Kumar Reviewed-by: Daniel Lezcano Signed-off-by: Eduardo Valentin --- drivers/thermal/imx_thermal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index c924396685a0..bb6754a5342c 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -742,9 +742,10 @@ static int imx_thermal_probe(struct platform_device *pdev) if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { ret = imx_init_from_nvmem_cells(pdev); - if (ret == -EPROBE_DEFER) - return ret; if (ret) { + if (ret == -EPROBE_DEFER) + return ret; + dev_err(&pdev->dev, "failed to init from nvmem: %d\n", ret); return ret; -- cgit v1.2.3-59-g8ed1b From 199bc54b4a1f3848a62ccb1fa22e9c43c352b8fa Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 23 Nov 2018 13:18:37 +0100 Subject: dt-bindings: thermal: tegra-bpmp: Add Tegra194 support The thermal controller implementation on Tegra194 is very similar to the implementation on Tegra186. Add a compatible string for the new generation. Signed-off-by: Thierry Reding Signed-off-by: Eduardo Valentin --- .../bindings/thermal/nvidia,tegra186-bpmp-thermal.txt | 3 ++- include/dt-bindings/thermal/tegra194-bpmp-thermal.h | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/thermal/tegra194-bpmp-thermal.h diff --git a/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.txt b/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.txt index 276387dd6815..e17c07be270b 100644 --- a/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.txt @@ -15,7 +15,8 @@ Required properties: - compatible: Array of strings. One of: - - "nvidia,tegra186-bpmp-thermal". + - "nvidia,tegra186-bpmp-thermal" + - "nvidia,tegra194-bpmp-thermal" - #thermal-sensor-cells: Cell for sensor index. Single-cell integer. Must be <1>. diff --git a/include/dt-bindings/thermal/tegra194-bpmp-thermal.h b/include/dt-bindings/thermal/tegra194-bpmp-thermal.h new file mode 100644 index 000000000000..aa7fb08135ca --- /dev/null +++ b/include/dt-bindings/thermal/tegra194-bpmp-thermal.h @@ -0,0 +1,15 @@ +/* + * This header provides constants for binding nvidia,tegra194-bpmp-thermal. + */ + +#ifndef _DT_BINDINGS_THERMAL_TEGRA194_BPMP_THERMAL_H +#define _DT_BINDINGS_THERMAL_TEGRA194_BPMP_THERMAL_H + +#define TEGRA194_BPMP_THERMAL_ZONE_CPU 2 +#define TEGRA194_BPMP_THERMAL_ZONE_GPU 3 +#define TEGRA194_BPMP_THERMAL_ZONE_AUX 4 +#define TEGRA194_BPMP_THERMAL_ZONE_PLLX 5 +#define TEGRA194_BPMP_THERMAL_ZONE_AO 6 +#define TEGRA194_BPMP_THERMAL_ZONE_TJ_MAX 7 + +#endif -- cgit v1.2.3-59-g8ed1b From 05c1b7058aeab8a121e9af57ef97233f83ebeb75 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Fri, 23 Nov 2018 09:50:58 -0500 Subject: thermal: tegra: soctherm: Change to use DEFINE_SHOW_ATTRIBUTE macro Use macro to simplify the code. Signed-off-by: Yangtao Li Signed-off-by: Eduardo Valentin --- drivers/thermal/tegra/soctherm.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index ed28110a3535..45b41b885f49 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -803,17 +803,7 @@ static int regs_show(struct seq_file *s, void *data) return 0; } -static int regs_open(struct inode *inode, struct file *file) -{ - return single_open(file, regs_show, inode->i_private); -} - -static const struct file_operations regs_fops = { - .open = regs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(regs); static void soctherm_debug_init(struct platform_device *pdev) { -- cgit v1.2.3-59-g8ed1b From 8632ed49c809160be3820cede35a7d0844c62c67 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Fri, 23 Nov 2018 09:55:22 -0500 Subject: thermal/intel_powerclamp: Change to use DEFINE_SHOW_ATTRIBUTE macro Use macro to simplify the code. Signed-off-by: Yangtao Li Signed-off-by: Eduardo Valentin --- drivers/thermal/intel_powerclamp.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index cde891c54cde..7571f7c2e7c9 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -708,19 +708,7 @@ static int powerclamp_debug_show(struct seq_file *m, void *unused) return 0; } -static int powerclamp_debug_open(struct inode *inode, - struct file *file) -{ - return single_open(file, powerclamp_debug_show, inode->i_private); -} - -static const struct file_operations powerclamp_debug_fops = { - .open = powerclamp_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; +DEFINE_SHOW_ATTRIBUTE(powerclamp_debug); static inline void powerclamp_create_debug_files(void) { -- cgit v1.2.3-59-g8ed1b From ca74472dead17ad8e5de92c054d71109ef8a4beb Mon Sep 17 00:00:00 2001 From: Kunihiko Hayashi Date: Fri, 7 Dec 2018 10:06:04 +0900 Subject: thermal: uniphier: Convert to SPDX identifier This converts license boilerplate to SPDX identifier, and removes unnecessary lines. Signed-off-by: Kunihiko Hayashi Reviewed-by: Daniel Lezcano Signed-off-by: Eduardo Valentin --- drivers/thermal/uniphier_thermal.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c index 55477d74d591..bba2284412d3 100644 --- a/drivers/thermal/uniphier_thermal.c +++ b/drivers/thermal/uniphier_thermal.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /** * uniphier_thermal.c - Socionext UniPhier thermal driver - * * Copyright 2014 Panasonic Corporation * Copyright 2016-2017 Socionext Inc. - * All rights reserved. - * * Author: * Kunihiko Hayashi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include -- cgit v1.2.3-59-g8ed1b From 5a78ad6d9c1b2c3c3226528346e9794ed3504381 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 10 Dec 2018 22:57:27 +0100 Subject: thermal: st: fix Makefile typo When STM32_THERMAL is enabled, this overrides all previously enabled files in the same directory, as seen from this link failure: ERROR: "st_thermal_pm_ops" [drivers/thermal/st/st_thermal_syscfg.ko] undefined! ERROR: "st_thermal_register" [drivers/thermal/st/st_thermal_syscfg.ko] undefined! ERROR: "st_thermal_unregister" [drivers/thermal/st/st_thermal_syscfg.ko] undefined! The correct syntax in Makefile requires using += instead of :=. Fixes: 1d6931556073 ("thermal: add stm32 thermal driver") Signed-off-by: Arnd Bergmann Reviewed-by: Daniel Lezcano Signed-off-by: Eduardo Valentin --- drivers/thermal/st/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/st/Makefile b/drivers/thermal/st/Makefile index b2b9e9b96296..243ca7881b12 100644 --- a/drivers/thermal/st/Makefile +++ b/drivers/thermal/st/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_ST_THERMAL) := st_thermal.o obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o -obj-$(CONFIG_STM32_THERMAL) := stm_thermal.o \ No newline at end of file +obj-$(CONFIG_STM32_THERMAL) += stm_thermal.o -- cgit v1.2.3-59-g8ed1b From 879d7362d1d01efd476a143c09048f5945936c32 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 12 Dec 2018 10:36:40 +0100 Subject: thermal: armada: add overheat interrupt support The IP can manage to trigger interrupts on overheat situation from all the sensors. However, the interrupt source changes along with the last selected source (ie. the last read sensor), which is an inconsistent behavior. Avoid possible glitches by always selecting back only one channel which will then be referenced as the "overheat_sensor" (arbitrarily: the first in the DT which has a critical trip point filled in). It is possible that the scan of all thermal zone nodes did not bring a critical trip point from which the overheat interrupt could be configured. In this case just complain but do not fail the probe. Also disable sensor switch during overheat situations because changing the channel while the system is too hot could clear the overheat state by changing the source while the temperature is still very high. Even if the overheat state is not declared, overheat interrupt must be cleared by reading the DFX interrupt cause _after_ the temperature has fallen down to the low threshold, otherwise future possible interrupts would not be served. A work polls the corresponding register until the overheat flag gets cleared in this case. Suggested-by: David Sniatkiwicz Signed-off-by: Miquel Raynal Signed-off-by: Eduardo Valentin --- drivers/thermal/armada_thermal.c | 270 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 269 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 4b36a3022849..df3054b0ae6b 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -26,6 +26,11 @@ #include #include #include +#include + +#include "thermal_core.h" + +#define TO_MCELSIUS(c) ((c) * 1000) /* Thermal Manager Control and Status Register */ #define PMU_TDC0_SW_RST_MASK (0x1 << 1) @@ -61,9 +66,13 @@ #define CONTROL1_TSEN_AVG_MASK 0x7 #define CONTROL1_EXT_TSEN_SW_RESET BIT(7) #define CONTROL1_EXT_TSEN_HW_RESETn BIT(8) +#define CONTROL1_TSEN_INT_EN BIT(25) +#define CONTROL1_TSEN_SELECT_OFF 21 +#define CONTROL1_TSEN_SELECT_MASK 0x3 #define STATUS_POLL_PERIOD_US 1000 #define STATUS_POLL_TIMEOUT_US 100000 +#define OVERHEAT_INT_POLL_DELAY_MS 1000 struct armada_thermal_data; @@ -75,7 +84,11 @@ struct armada_thermal_priv { /* serialize temperature reads/updates */ struct mutex update_lock; struct armada_thermal_data *data; + struct thermal_zone_device *overheat_sensor; + int interrupt_source; int current_channel; + long current_threshold; + long current_hysteresis; }; struct armada_thermal_data { @@ -93,12 +106,20 @@ struct armada_thermal_data { /* Register shift and mask to access the sensor temperature */ unsigned int temp_shift; unsigned int temp_mask; + unsigned int thresh_shift; + unsigned int hyst_shift; + unsigned int hyst_mask; u32 is_valid_bit; /* Syscon access */ unsigned int syscon_control0_off; unsigned int syscon_control1_off; unsigned int syscon_status_off; + unsigned int dfx_irq_cause_off; + unsigned int dfx_irq_mask_off; + unsigned int dfx_overheat_irq; + unsigned int dfx_server_irq_mask_off; + unsigned int dfx_server_irq_en; /* One sensor is in the thermal IC, the others are in the CPUs if any */ unsigned int cpu_nr; @@ -272,6 +293,41 @@ static bool armada_is_valid(struct armada_thermal_priv *priv) return reg & priv->data->is_valid_bit; } +static void armada_enable_overheat_interrupt(struct armada_thermal_priv *priv) +{ + struct armada_thermal_data *data = priv->data; + u32 reg; + + /* Clear DFX temperature IRQ cause */ + regmap_read(priv->syscon, data->dfx_irq_cause_off, ®); + + /* Enable DFX Temperature IRQ */ + regmap_read(priv->syscon, data->dfx_irq_mask_off, ®); + reg |= data->dfx_overheat_irq; + regmap_write(priv->syscon, data->dfx_irq_mask_off, reg); + + /* Enable DFX server IRQ */ + regmap_read(priv->syscon, data->dfx_server_irq_mask_off, ®); + reg |= data->dfx_server_irq_en; + regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg); + + /* Enable overheat interrupt */ + regmap_read(priv->syscon, data->syscon_control1_off, ®); + reg |= CONTROL1_TSEN_INT_EN; + regmap_write(priv->syscon, data->syscon_control1_off, reg); +} + +static void __maybe_unused +armada_disable_overheat_interrupt(struct armada_thermal_priv *priv) +{ + struct armada_thermal_data *data = priv->data; + u32 reg; + + regmap_read(priv->syscon, data->syscon_control1_off, ®); + reg &= ~CONTROL1_TSEN_INT_EN; + regmap_write(priv->syscon, data->syscon_control1_off, reg); +} + /* There is currently no board with more than one sensor per channel */ static int armada_select_channel(struct armada_thermal_priv *priv, int channel) { @@ -388,6 +444,14 @@ static int armada_get_temp(void *_sensor, int *temp) /* Do the actual reading */ ret = armada_read_sensor(priv, temp); + if (ret) + goto unlock_mutex; + + /* + * Select back the interrupt source channel from which a potential + * critical trip point has been set. + */ + ret = armada_select_channel(priv, priv->interrupt_source); unlock_mutex: mutex_unlock(&priv->update_lock); @@ -399,6 +463,123 @@ static struct thermal_zone_of_device_ops of_ops = { .get_temp = armada_get_temp, }; +static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data, + unsigned int temp_mc) +{ + s64 b = data->coef_b; + s64 m = data->coef_m; + s64 div = data->coef_div; + unsigned int sample; + + if (data->inverted) + sample = div_s64(((temp_mc * div) + b), m); + else + sample = div_s64((b - (temp_mc * div)), m); + + return sample & data->temp_mask; +} + +/* + * The documentation states: + * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2) + * which is the mathematical derivation for: + * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2°C + */ +static unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200}; + +static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data, + unsigned int hyst_mc) +{ + int i; + + /* + * We will always take the smallest possible hysteresis to avoid risking + * the hardware integrity by enlarging the threshold by +8°C in the + * worst case. + */ + for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--) + if (hyst_mc >= hyst_levels_mc[i]) + break; + + return i & data->hyst_mask; +} + +static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv, + int thresh_mc, int hyst_mc) +{ + struct armada_thermal_data *data = priv->data; + unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc); + unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc); + u32 ctrl1; + + regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1); + + /* Set Threshold */ + if (thresh_mc >= 0) { + ctrl1 &= ~(data->temp_mask << data->thresh_shift); + ctrl1 |= threshold << data->thresh_shift; + priv->current_threshold = thresh_mc; + } + + /* Set Hysteresis */ + if (hyst_mc >= 0) { + ctrl1 &= ~(data->hyst_mask << data->hyst_shift); + ctrl1 |= hysteresis << data->hyst_shift; + priv->current_hysteresis = hyst_mc; + } + + regmap_write(priv->syscon, data->syscon_control1_off, ctrl1); +} + +static irqreturn_t armada_overheat_isr(int irq, void *blob) +{ + /* + * Disable the IRQ and continue in thread context (thermal core + * notification and temperature monitoring). + */ + disable_irq_nosync(irq); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t armada_overheat_isr_thread(int irq, void *blob) +{ + struct armada_thermal_priv *priv = blob; + int low_threshold = priv->current_threshold - priv->current_hysteresis; + int temperature; + u32 dummy; + int ret; + + /* Notify the core in thread context */ + thermal_zone_device_update(priv->overheat_sensor, + THERMAL_EVENT_UNSPECIFIED); + + /* + * The overheat interrupt must be cleared by reading the DFX interrupt + * cause _after_ the temperature has fallen down to the low threshold. + * Otherwise future interrupts might not be served. + */ + do { + msleep(OVERHEAT_INT_POLL_DELAY_MS); + mutex_lock(&priv->update_lock); + ret = armada_read_sensor(priv, &temperature); + mutex_unlock(&priv->update_lock); + if (ret) + goto enable_irq; + } while (temperature >= low_threshold); + + regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy); + + /* Notify the thermal core that the temperature is acceptable again */ + thermal_zone_device_update(priv->overheat_sensor, + THERMAL_EVENT_UNSPECIFIED); + +enable_irq: + enable_irq(irq); + + return IRQ_HANDLED; +} + static const struct armada_thermal_data armadaxp_data = { .init = armadaxp_init, .temp_shift = 10, @@ -454,6 +635,9 @@ static const struct armada_thermal_data armada_ap806_data = { .is_valid_bit = BIT(16), .temp_shift = 0, .temp_mask = 0x3ff, + .thresh_shift = 3, + .hyst_shift = 19, + .hyst_mask = 0x3, .coef_b = -150000LL, .coef_m = 423ULL, .coef_div = 1, @@ -462,6 +646,11 @@ static const struct armada_thermal_data armada_ap806_data = { .syscon_control0_off = 0x84, .syscon_control1_off = 0x88, .syscon_status_off = 0x8C, + .dfx_irq_cause_off = 0x108, + .dfx_irq_mask_off = 0x10C, + .dfx_overheat_irq = BIT(22), + .dfx_server_irq_mask_off = 0x104, + .dfx_server_irq_en = BIT(1), .cpu_nr = 4, }; @@ -470,6 +659,9 @@ static const struct armada_thermal_data armada_cp110_data = { .is_valid_bit = BIT(10), .temp_shift = 0, .temp_mask = 0x3ff, + .thresh_shift = 16, + .hyst_shift = 26, + .hyst_mask = 0x3, .coef_b = 1172499100ULL, .coef_m = 2000096ULL, .coef_div = 4201, @@ -477,6 +669,11 @@ static const struct armada_thermal_data armada_cp110_data = { .syscon_control0_off = 0x70, .syscon_control1_off = 0x74, .syscon_status_off = 0x78, + .dfx_irq_cause_off = 0x108, + .dfx_irq_mask_off = 0x10C, + .dfx_overheat_irq = BIT(20), + .dfx_server_irq_mask_off = 0x104, + .dfx_server_irq_en = BIT(1), }; static const struct of_device_id armada_thermal_id_table[] = { @@ -586,6 +783,48 @@ static void armada_set_sane_name(struct platform_device *pdev, } while (insane_char); } +/* + * The IP can manage to trigger interrupts on overheat situation from all the + * sensors. However, the interrupt source changes along with the last selected + * source (ie. the last read sensor), which is an inconsistent behavior. Avoid + * possible glitches by always selecting back only one channel (arbitrarily: the + * first in the DT which has a critical trip point). We also disable sensor + * switch during overheat situations. + */ +static int armada_configure_overheat_int(struct armada_thermal_priv *priv, + struct thermal_zone_device *tz, + int sensor_id) +{ + /* Retrieve the critical trip point to enable the overheat interrupt */ + const struct thermal_trip *trips = of_thermal_get_trip_points(tz); + int ret; + int i; + + if (!trips) + return -EINVAL; + + for (i = 0; i < of_thermal_get_ntrips(tz); i++) + if (trips[i].type == THERMAL_TRIP_CRITICAL) + break; + + if (i == of_thermal_get_ntrips(tz)) + return -EINVAL; + + ret = armada_select_channel(priv, sensor_id); + if (ret) + return ret; + + armada_set_overheat_thresholds(priv, + trips[i].temperature, + trips[i].hysteresis); + priv->overheat_sensor = tz; + priv->interrupt_source = sensor_id; + + armada_enable_overheat_interrupt(priv); + + return 0; +} + static int armada_thermal_probe(struct platform_device *pdev) { struct thermal_zone_device *tz; @@ -593,7 +832,7 @@ static int armada_thermal_probe(struct platform_device *pdev) struct armada_drvdata *drvdata; const struct of_device_id *match; struct armada_thermal_priv *priv; - int sensor_id; + int sensor_id, irq; int ret; match = of_match_device(armada_thermal_id_table, &pdev->dev); @@ -663,6 +902,23 @@ static int armada_thermal_probe(struct platform_device *pdev) drvdata->data.priv = priv; platform_set_drvdata(pdev, drvdata); + irq = platform_get_irq(pdev, 0); + if (irq == -EPROBE_DEFER) + return irq; + + /* The overheat interrupt feature is not mandatory */ + if (irq > 0) { + ret = devm_request_threaded_irq(&pdev->dev, irq, + armada_overheat_isr, + armada_overheat_isr_thread, + 0, NULL, priv); + if (ret) { + dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n", + irq); + return ret; + } + } + /* * There is one channel for the IC and one per CPU (if any), each * channel has one sensor. @@ -686,8 +942,20 @@ static int armada_thermal_probe(struct platform_device *pdev) devm_kfree(&pdev->dev, sensor); continue; } + + /* + * The first channel that has a critical trip point registered + * in the DT will serve as interrupt source. Others possible + * critical trip points will simply be ignored by the driver. + */ + if (irq > 0 && !priv->overheat_sensor) + armada_configure_overheat_int(priv, tz, sensor->id); } + /* Just complain if no overheat interrupt was set up */ + if (!priv->overheat_sensor) + dev_warn(&pdev->dev, "Overheat interrupt not available\n"); + return 0; } -- cgit v1.2.3-59-g8ed1b From ad3e72030bff0cbd4409074374a2a0f37ca1e20d Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 12 Dec 2018 10:36:41 +0100 Subject: MAINTAINERS: thermal: add entry for Marvell MVEBU thermal driver Add myself as Marvell MVEBU thermal driver maintainer. Signed-off-by: Miquel Raynal Signed-off-by: Eduardo Valentin --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6682420421c1..3c457ff4826b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8985,6 +8985,11 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/phy/marvell10g.c +MARVELL MVEBU THERMAL DRIVER +M: Miquel Raynal +S: Maintained +F: drivers/thermal/armada_thermal.c + MARVELL MVNETA ETHERNET DRIVER M: Thomas Petazzoni L: netdev@vger.kernel.org -- cgit v1.2.3-59-g8ed1b From 1bc7523817215f94d8597f4daccb17a394a5703a Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 12 Dec 2018 10:36:42 +0100 Subject: dt-bindings: ap806: document the thermal interrupt capabilities The thermal IP can produce interrupts on overheat situation. Describe them. Signed-off-by: Miquel Raynal Signed-off-by: Eduardo Valentin --- .../devicetree/bindings/arm/marvell/ap806-system-controller.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt index 3fd21bb7cb37..7b8b8eb0191f 100644 --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt @@ -114,12 +114,17 @@ Documentation/devicetree/bindings/thermal/thermal.txt The thermal IP can probe the temperature all around the processor. It may feature several channels, each of them wired to one sensor. +It is possible to setup an overheat interrupt by giving at least one +critical point to any subnode of the thermal-zone node. + Required properties: - compatible: must be one of: * marvell,armada-ap806-thermal - reg: register range associated with the thermal functions. Optional properties: +- interrupts: overheat interrupt handle. Should point to line 18 of the + SEI irqchip. See interrupt-controller/interrupts.txt - #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer to this IP and represents the channel ID. There is one sensor per channel. O refers to the thermal IP internal channel, while positive @@ -133,6 +138,8 @@ ap_syscon1: system-controller@6f8000 { ap_thermal: thermal-sensor@80 { compatible = "marvell,armada-ap806-thermal"; reg = <0x80 0x10>; + interrupt-parent = <&sei>; + interrupts = <18>; #thermal-sensor-cells = <1>; }; }; -- cgit v1.2.3-59-g8ed1b From bf9ff83f93baf4f404b7e3a90037604f86bea854 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 12 Dec 2018 10:36:43 +0100 Subject: dt-bindings: cp110: document the thermal interrupt capabilities The thermal IP can produce interrupts on overheat situation. Describe them. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Eduardo Valentin --- .../devicetree/bindings/arm/marvell/cp110-system-controller.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt index 81ce742d2760..4db4119a6d19 100644 --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt @@ -199,6 +199,9 @@ Thermal: The thermal IP can probe the temperature all around the processor. It may feature several channels, each of them wired to one sensor. +It is possible to setup an overheat interrupt by giving at least one +critical point to any subnode of the thermal-zone node. + For common binding part and usage, refer to Documentation/devicetree/bindings/thermal/thermal.txt @@ -208,6 +211,11 @@ Required properties: - reg: register range associated with the thermal functions. Optional properties: +- interrupts-extended: overheat interrupt handle. Should point to + a line of the ICU-SEI irqchip (116 is what is usually used by the + firmware). The ICU-SEI will redirect towards interrupt line #37 of the + AP SEI which is shared across all CPs. + See interrupt-controller/interrupts.txt - #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer to this IP and represents the channel ID. There is one sensor per channel. O refers to the thermal IP internal channel. @@ -220,6 +228,7 @@ CP110_LABEL(syscon1): system-controller@6f8000 { CP110_LABEL(thermal): thermal-sensor@70 { compatible = "marvell,armada-cp110-thermal"; reg = <0x70 0x10>; + interrupts-extended = <&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>; #thermal-sensor-cells = <1>; }; }; -- cgit v1.2.3-59-g8ed1b From 69f8f55185ff2405366b1b193d3d2fea16589e54 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Thu, 13 Dec 2018 20:19:48 +0000 Subject: dt-bindings: thermal: rcar-thermal: add R8A774C0 support Document RZ/G2E SoC (a.k.a. r8a774c0) bindings. Signed-off-by: Fabrizio Castro Reviewed-by: Geert Uytterhoeven Signed-off-by: Eduardo Valentin --- Documentation/devicetree/bindings/thermal/rcar-thermal.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt index 73e1613d2cb0..a679fb4160d8 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt @@ -4,11 +4,12 @@ Required properties: - compatible : "renesas,thermal-", "renesas,rcar-gen2-thermal" (with thermal-zone) or "renesas,rcar-thermal" (without thermal-zone) as - fallback except R-Car V3M/D3. + fallback except R-Car V3M/D3 and RZ/G2E. Examples with soctypes are: - "renesas,thermal-r8a73a4" (R-Mobile APE6) - "renesas,thermal-r8a7743" (RZ/G1M) - "renesas,thermal-r8a7744" (RZ/G1N) + - "renesas,thermal-r8a774c0" (RZ/G2E) - "renesas,thermal-r8a7779" (R-Car H1) - "renesas,thermal-r8a7790" (R-Car H2) - "renesas,thermal-r8a7791" (R-Car M2-W) @@ -23,7 +24,7 @@ Required properties: Option properties: - interrupts : If present should contain 3 interrupts for - R-Car V3M/D3 or 1 interrupt otherwise. + R-Car V3M/D3 and RZ/G2E or 1 interrupt otherwise. Example (non interrupt support): -- cgit v1.2.3-59-g8ed1b From b8d3d11203afddf9e6c4e8b8ccecd401b6a8cc3e Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Thu, 13 Dec 2018 20:23:10 +0000 Subject: thermal: rcar_thermal: add R8A774C0 support Add thermal support for the RZ/G2E SoC (a.k.a. R8A774C0). Signed-off-by: Fabrizio Castro Reviewed-by: Geert Uytterhoeven Reviewed-by: Simon Horman Signed-off-by: Eduardo Valentin --- drivers/thermal/rcar_thermal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 8014a207d8d9..335cfcbce245 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -112,6 +112,10 @@ static const struct of_device_id rcar_thermal_dt_ids[] = { .compatible = "renesas,rcar-gen2-thermal", .data = &rcar_gen2_thermal, }, + { + .compatible = "renesas,thermal-r8a774c0", + .data = &rcar_gen3_thermal, + }, { .compatible = "renesas,thermal-r8a77970", .data = &rcar_gen3_thermal, -- cgit v1.2.3-59-g8ed1b From 6471a52deeea8bba8163a1f8c7aa309d4e287eb1 Mon Sep 17 00:00:00 2001 From: Yoshihiro Kaneko Date: Mon, 17 Dec 2018 23:50:20 +0900 Subject: dt-bindings: thermal: rcar-thermal: add R8A77990 support Document the R-Car E3 (R8A77990) SoC bindings. Signed-off-by: Yoshihiro Kaneko Reviewed-by: Geert Uytterhoeven Reviewed-by: Simon Horman Tested-by: Simon Horman Signed-off-by: Eduardo Valentin --- Documentation/devicetree/bindings/thermal/rcar-thermal.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt index a679fb4160d8..196112d23b1e 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt @@ -4,7 +4,7 @@ Required properties: - compatible : "renesas,thermal-", "renesas,rcar-gen2-thermal" (with thermal-zone) or "renesas,rcar-thermal" (without thermal-zone) as - fallback except R-Car V3M/D3 and RZ/G2E. + fallback except R-Car V3M/E3/D3 and RZ/G2E. Examples with soctypes are: - "renesas,thermal-r8a73a4" (R-Mobile APE6) - "renesas,thermal-r8a7743" (RZ/G1M) @@ -16,6 +16,7 @@ Required properties: - "renesas,thermal-r8a7792" (R-Car V2H) - "renesas,thermal-r8a7793" (R-Car M2-N) - "renesas,thermal-r8a77970" (R-Car V3M) + - "renesas,thermal-r8a77990" (R-Car E3) - "renesas,thermal-r8a77995" (R-Car D3) - reg : Address range of the thermal registers. The 1st reg will be recognized as common register @@ -24,7 +25,7 @@ Required properties: Option properties: - interrupts : If present should contain 3 interrupts for - R-Car V3M/D3 and RZ/G2E or 1 interrupt otherwise. + R-Car V3M/E3/D3 and RZ/G2E or 1 interrupt otherwise. Example (non interrupt support): -- cgit v1.2.3-59-g8ed1b From e36e13003efd8b0160d49138385b0cec570900aa Mon Sep 17 00:00:00 2001 From: Yoshihiro Kaneko Date: Mon, 17 Dec 2018 23:50:21 +0900 Subject: thermal: rcar_thermal: add R8A77990 support Add support for R-Car E3 (R8A77990) thermal support. Signed-off-by: Yoshihiro Kaneko Reviewed-by: Geert Uytterhoeven Reviewed-by: Simon Horman Signed-off-by: Eduardo Valentin --- drivers/thermal/rcar_thermal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 335cfcbce245..97462e9b40d8 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -120,6 +120,10 @@ static const struct of_device_id rcar_thermal_dt_ids[] = { .compatible = "renesas,thermal-r8a77970", .data = &rcar_gen3_thermal, }, + { + .compatible = "renesas,thermal-r8a77990", + .data = &rcar_gen3_thermal, + }, { .compatible = "renesas,thermal-r8a77995", .data = &rcar_gen3_thermal, -- cgit v1.2.3-59-g8ed1b From 9d216211fded20fff301d0317af3238d8383634c Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sun, 23 Dec 2018 23:26:44 -0800 Subject: thermal: generic-adc: Fix adc to temp interpolation First correct the edge case to return the last element if we're outside the range, rather than at the last element, so that interpolation is not omitted for points between the two last entries in the table. Then correct the formula to perform linear interpolation based the two points surrounding the read ADC value. The indices for temp are kept as "hi" and "lo" to pair with the adc indices, but there's no requirement that the temperature is provided in descendent order. mult_frac() is used to prevent issues with overflowing the int. Cc: Laxman Dewangan Signed-off-by: Bjorn Andersson Signed-off-by: Eduardo Valentin --- drivers/thermal/thermal-generic-adc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index bf1c628d4a7a..e22fc60ad36d 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -26,7 +26,7 @@ struct gadc_thermal_info { static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) { - int temp, adc_hi, adc_lo; + int temp, temp_hi, temp_lo, adc_hi, adc_lo; int i; for (i = 0; i < gti->nlookup_table; i++) { @@ -36,13 +36,17 @@ static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) if (i == 0) { temp = gti->lookup_table[0]; - } else if (i >= (gti->nlookup_table - 1)) { + } else if (i >= gti->nlookup_table) { temp = gti->lookup_table[2 * (gti->nlookup_table - 1)]; } else { adc_hi = gti->lookup_table[2 * i - 1]; adc_lo = gti->lookup_table[2 * i + 1]; - temp = gti->lookup_table[2 * i]; - temp -= ((val - adc_lo) * 1000) / (adc_hi - adc_lo); + + temp_hi = gti->lookup_table[2 * i - 2]; + temp_lo = gti->lookup_table[2 * i]; + + temp = temp_hi + mult_frac(temp_lo - temp_hi, val - adc_hi, + adc_lo - adc_hi); } return temp; -- cgit v1.2.3-59-g8ed1b