Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux

Pull thermal management updates from Zhang Rui:

- introduce brcmstb AVS TMON thermal driver (Brian Norris)

- add Rockchip RV1108 support in rockchip thermal driver (Rocky Hao)

- major rework on HISI driver plus additional support of hisi3660
(Daniel Lezcano)

- add nvmem-cells binding on imx6sx (Leonard Crestez)

- fix a NULL pointer dereference on ti thermal driver unloading (Tony
Lindgren)

- improve tmon tool to make it easier to cross-compile tmon (Markus
Mayer)

- add Coffee Lake and Cannon Lake support for intel processor and pch
thermal drivers (Srinivas Pandruvada)

- other small fixes and cleanups (Arvind Yadav, Colin Ian King, Allen
Wild, Nicolin Chen, Baruch SiachNiklas Söderlund, Arnd Bergmann)

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (44 commits)
thermal: pch: Add Cannon Lake support
thermal: int340x: processor_thermal: Add Coffee Lake support
thermal: int340x: processor_thermal: Add Cannon Lake support
thermal: bxt: remove redundant variable trip
thermal: cpu_cooling: pr_err() strings should end with newlines
thermal: add brcmstb AVS TMON driver
Documentation: devicetree: add binding for Broadcom STB AVS TMON
thermal/drivers/hisi: Add support for hi3660 SoC
thermal/drivers/hisi: Prepare to add support for other hisi platforms
thermal/drivers/hisi: Add platform prefix to function name
thermal/drivers/hisi: Put platform code together
thermal/drivers/qcom-spmi: Use devm_iio_channel_get
thermal/drivers/generic-iio-adc: Switch tz request to devm version
thermal/drivers/step_wise: Fix temperature regulation misbehavior
thermal/drivers/hisi: Use round up step value
thermal/drivers/hisi: Move the clk setup in the corresponding functions
thermal/drivers/hisi: Remove mutex_lock in the code
thermal/drivers/hisi: Remove thermal data back pointer
thermal/drivers/hisi: Convert long to int
thermal/drivers/hisi: Rename and remove unused field
...

+1069 -341
+20
Documentation/devicetree/bindings/thermal/brcm,avs-tmon.txt
··· 1 + * Broadcom STB thermal management 2 + 3 + Thermal management core, provided by the AVS TMON hardware block. 4 + 5 + Required properties: 6 + - compatible: must be "brcm,avs-tmon" and/or "brcm,avs-tmon-bcm7445" 7 + - reg: address range for the AVS TMON registers 8 + - interrupts: temperature monitor interrupt, for high/low threshold triggers 9 + - interrupt-names: should be "tmon" 10 + - interrupt-parent: the parent interrupt controller 11 + 12 + Example: 13 + 14 + thermal@f04d1500 { 15 + compatible = "brcm,avs-tmon-bcm7445", "brcm,avs-tmon"; 16 + reg = <0xf04d1500 0x28>; 17 + interrupts = <0x6>; 18 + interrupt-names = "tmon"; 19 + interrupt-parent = <&avs_host_l2_intc>; 20 + };
+7
Documentation/devicetree/bindings/thermal/imx-thermal.txt
··· 7 7 is higher than panic threshold, system will auto reboot by SRC module. 8 8 - fsl,tempmon : phandle pointer to system controller that contains TEMPMON 9 9 control registers, e.g. ANATOP on imx6q. 10 + - nvmem-cells: A phandle to the calibration cells provided by ocotp. 11 + - nvmem-cell-names: Should be "calib", "temp_grade". 12 + 13 + Deprecated properties: 10 14 - fsl,tempmon-data : phandle pointer to fuse controller that contains TEMPMON 11 15 calibration data, e.g. OCOTP on imx6q. The details about calibration data 12 16 can be found in SoC Reference Manual. 17 + 18 + Direct access to OCOTP via fsl,tempmon-data is incorrect on some newer chips 19 + because it does not handle OCOTP clock requirements. 13 20 14 21 Optional properties: 15 22 - clocks : thermal sensor's clock source.
+1
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
··· 2 2 3 3 Required properties: 4 4 - compatible : should be "rockchip,<name>-tsadc" 5 + "rockchip,rv1108-tsadc": found on RV1108 SoCs 5 6 "rockchip,rk3228-tsadc": found on RK3228 SoCs 6 7 "rockchip,rk3288-tsadc": found on RK3288 SoCs 7 8 "rockchip,rk3328-tsadc": found on RK3328 SoCs
+8
MAINTAINERS
··· 2986 2986 F: Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt 2987 2987 F: drivers/cpufreq/brcmstb* 2988 2988 2989 + BROADCOM STB AVS TMON DRIVER 2990 + M: Markus Mayer <mmayer@broadcom.com> 2991 + M: bcm-kernel-feedback-list@broadcom.com 2992 + L: linux-pm@vger.kernel.org 2993 + S: Maintained 2994 + F: Documentation/devicetree/bindings/thermal/brcm,avs-tmon.txt 2995 + F: drivers/thermal/broadcom/brcmstb* 2996 + 2989 2997 BROADCOM STB NAND FLASH DRIVER 2990 2998 M: Brian Norris <computersforpeace@gmail.com> 2991 2999 M: Kamal Dasu <kdasu.kdev@gmail.com>
+2 -1
drivers/thermal/Kconfig
··· 206 206 config IMX_THERMAL 207 207 tristate "Temperature sensor driver for Freescale i.MX SoCs" 208 208 depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST 209 + depends on NVMEM || !NVMEM 209 210 depends on MFD_SYSCON 210 211 depends on OF 211 212 help ··· 409 408 controller present in Mediatek SoCs 410 409 411 410 menu "Broadcom thermal drivers" 412 - depends on ARCH_BCM || COMPILE_TEST 411 + depends on ARCH_BCM || ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST 413 412 source "drivers/thermal/broadcom/Kconfig" 414 413 endmenu 415 414
+1 -1
drivers/thermal/armada_thermal.c
··· 58 58 /* Test for a valid sensor value (optional) */ 59 59 bool (*is_valid)(struct armada_thermal_priv *); 60 60 61 - /* Formula coeficients: temp = (b + m * reg) / div */ 61 + /* Formula coeficients: temp = (b - m * reg) / div */ 62 62 unsigned long coef_b; 63 63 unsigned long coef_m; 64 64 unsigned long coef_div;
+7
drivers/thermal/broadcom/Kconfig
··· 6 6 help 7 7 Support for thermal sensors on Broadcom bcm2835 SoCs. 8 8 9 + config BRCMSTB_THERMAL 10 + tristate "Broadcom STB AVS TMON thermal driver" 11 + depends on ARCH_BRCMSTB || COMPILE_TEST 12 + help 13 + Enable this driver if you have a Broadcom STB SoC and would like 14 + thermal framework support. 15 + 9 16 config BCM_NS_THERMAL 10 17 tristate "Northstar thermal driver" 11 18 depends on ARCH_BCM_IPROC || COMPILE_TEST
+1
drivers/thermal/broadcom/Makefile
··· 1 1 obj-$(CONFIG_BCM2835_THERMAL) += bcm2835_thermal.o 2 + obj-$(CONFIG_BRCMSTB_THERMAL) += brcmstb_thermal.o 2 3 obj-$(CONFIG_BCM_NS_THERMAL) += ns-thermal.o
+387
drivers/thermal/broadcom/brcmstb_thermal.c
··· 1 + /* 2 + * Broadcom STB AVS TMON thermal sensor driver 3 + * 4 + * Copyright (c) 2015-2017 Broadcom 5 + * 6 + * This software is licensed under the terms of the GNU General Public 7 + * License version 2, as published by the Free Software Foundation, and 8 + * may be copied, distributed, and modified under those terms. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + */ 16 + 17 + #define DRV_NAME "brcmstb_thermal" 18 + 19 + #define pr_fmt(fmt) DRV_NAME ": " fmt 20 + 21 + #include <linux/bitops.h> 22 + #include <linux/device.h> 23 + #include <linux/err.h> 24 + #include <linux/io.h> 25 + #include <linux/irqreturn.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/kernel.h> 28 + #include <linux/module.h> 29 + #include <linux/platform_device.h> 30 + #include <linux/of_device.h> 31 + #include <linux/thermal.h> 32 + 33 + #define AVS_TMON_STATUS 0x00 34 + #define AVS_TMON_STATUS_valid_msk BIT(11) 35 + #define AVS_TMON_STATUS_data_msk GENMASK(10, 1) 36 + #define AVS_TMON_STATUS_data_shift 1 37 + 38 + #define AVS_TMON_EN_OVERTEMP_RESET 0x04 39 + #define AVS_TMON_EN_OVERTEMP_RESET_msk BIT(0) 40 + 41 + #define AVS_TMON_RESET_THRESH 0x08 42 + #define AVS_TMON_RESET_THRESH_msk GENMASK(10, 1) 43 + #define AVS_TMON_RESET_THRESH_shift 1 44 + 45 + #define AVS_TMON_INT_IDLE_TIME 0x10 46 + 47 + #define AVS_TMON_EN_TEMP_INT_SRCS 0x14 48 + #define AVS_TMON_EN_TEMP_INT_SRCS_high BIT(1) 49 + #define AVS_TMON_EN_TEMP_INT_SRCS_low BIT(0) 50 + 51 + #define AVS_TMON_INT_THRESH 0x18 52 + #define AVS_TMON_INT_THRESH_high_msk GENMASK(26, 17) 53 + #define AVS_TMON_INT_THRESH_high_shift 17 54 + #define AVS_TMON_INT_THRESH_low_msk GENMASK(10, 1) 55 + #define AVS_TMON_INT_THRESH_low_shift 1 56 + 57 + #define AVS_TMON_TEMP_INT_CODE 0x1c 58 + #define AVS_TMON_TP_TEST_ENABLE 0x20 59 + 60 + /* Default coefficients */ 61 + #define AVS_TMON_TEMP_SLOPE -487 62 + #define AVS_TMON_TEMP_OFFSET 410040 63 + 64 + /* HW related temperature constants */ 65 + #define AVS_TMON_TEMP_MAX 0x3ff 66 + #define AVS_TMON_TEMP_MIN -88161 67 + #define AVS_TMON_TEMP_MASK AVS_TMON_TEMP_MAX 68 + 69 + enum avs_tmon_trip_type { 70 + TMON_TRIP_TYPE_LOW = 0, 71 + TMON_TRIP_TYPE_HIGH, 72 + TMON_TRIP_TYPE_RESET, 73 + TMON_TRIP_TYPE_MAX, 74 + }; 75 + 76 + struct avs_tmon_trip { 77 + /* HW bit to enable the trip */ 78 + u32 enable_offs; 79 + u32 enable_mask; 80 + 81 + /* HW field to read the trip temperature */ 82 + u32 reg_offs; 83 + u32 reg_msk; 84 + int reg_shift; 85 + }; 86 + 87 + static struct avs_tmon_trip avs_tmon_trips[] = { 88 + /* Trips when temperature is below threshold */ 89 + [TMON_TRIP_TYPE_LOW] = { 90 + .enable_offs = AVS_TMON_EN_TEMP_INT_SRCS, 91 + .enable_mask = AVS_TMON_EN_TEMP_INT_SRCS_low, 92 + .reg_offs = AVS_TMON_INT_THRESH, 93 + .reg_msk = AVS_TMON_INT_THRESH_low_msk, 94 + .reg_shift = AVS_TMON_INT_THRESH_low_shift, 95 + }, 96 + /* Trips when temperature is above threshold */ 97 + [TMON_TRIP_TYPE_HIGH] = { 98 + .enable_offs = AVS_TMON_EN_TEMP_INT_SRCS, 99 + .enable_mask = AVS_TMON_EN_TEMP_INT_SRCS_high, 100 + .reg_offs = AVS_TMON_INT_THRESH, 101 + .reg_msk = AVS_TMON_INT_THRESH_high_msk, 102 + .reg_shift = AVS_TMON_INT_THRESH_high_shift, 103 + }, 104 + /* Automatically resets chip when above threshold */ 105 + [TMON_TRIP_TYPE_RESET] = { 106 + .enable_offs = AVS_TMON_EN_OVERTEMP_RESET, 107 + .enable_mask = AVS_TMON_EN_OVERTEMP_RESET_msk, 108 + .reg_offs = AVS_TMON_RESET_THRESH, 109 + .reg_msk = AVS_TMON_RESET_THRESH_msk, 110 + .reg_shift = AVS_TMON_RESET_THRESH_shift, 111 + }, 112 + }; 113 + 114 + struct brcmstb_thermal_priv { 115 + void __iomem *tmon_base; 116 + struct device *dev; 117 + struct thermal_zone_device *thermal; 118 + }; 119 + 120 + static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope, 121 + int *offset) 122 + { 123 + *slope = thermal_zone_get_slope(tz); 124 + *offset = thermal_zone_get_offset(tz); 125 + } 126 + 127 + /* Convert a HW code to a temperature reading (millidegree celsius) */ 128 + static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, 129 + u32 code) 130 + { 131 + const int val = code & AVS_TMON_TEMP_MASK; 132 + int slope, offset; 133 + 134 + avs_tmon_get_coeffs(tz, &slope, &offset); 135 + 136 + return slope * val + offset; 137 + } 138 + 139 + /* 140 + * Convert a temperature value (millidegree celsius) to a HW code 141 + * 142 + * @temp: temperature to convert 143 + * @low: if true, round toward the low side 144 + */ 145 + static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz, 146 + int temp, bool low) 147 + { 148 + int slope, offset; 149 + 150 + if (temp < AVS_TMON_TEMP_MIN) 151 + return AVS_TMON_TEMP_MAX; /* Maximum code value */ 152 + 153 + avs_tmon_get_coeffs(tz, &slope, &offset); 154 + 155 + if (temp >= offset) 156 + return 0; /* Minimum code value */ 157 + 158 + if (low) 159 + return (u32)(DIV_ROUND_UP(offset - temp, abs(slope))); 160 + else 161 + return (u32)((offset - temp) / abs(slope)); 162 + } 163 + 164 + static int brcmstb_get_temp(void *data, int *temp) 165 + { 166 + struct brcmstb_thermal_priv *priv = data; 167 + u32 val; 168 + long t; 169 + 170 + val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS); 171 + 172 + if (!(val & AVS_TMON_STATUS_valid_msk)) { 173 + dev_err(priv->dev, "reading not valid\n"); 174 + return -EIO; 175 + } 176 + 177 + val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift; 178 + 179 + t = avs_tmon_code_to_temp(priv->thermal, val); 180 + if (t < 0) 181 + *temp = 0; 182 + else 183 + *temp = t; 184 + 185 + return 0; 186 + } 187 + 188 + static void avs_tmon_trip_enable(struct brcmstb_thermal_priv *priv, 189 + enum avs_tmon_trip_type type, int en) 190 + { 191 + struct avs_tmon_trip *trip = &avs_tmon_trips[type]; 192 + u32 val = __raw_readl(priv->tmon_base + trip->enable_offs); 193 + 194 + dev_dbg(priv->dev, "%sable trip, type %d\n", en ? "en" : "dis", type); 195 + 196 + if (en) 197 + val |= trip->enable_mask; 198 + else 199 + val &= ~trip->enable_mask; 200 + 201 + __raw_writel(val, priv->tmon_base + trip->enable_offs); 202 + } 203 + 204 + static int avs_tmon_get_trip_temp(struct brcmstb_thermal_priv *priv, 205 + enum avs_tmon_trip_type type) 206 + { 207 + struct avs_tmon_trip *trip = &avs_tmon_trips[type]; 208 + u32 val = __raw_readl(priv->tmon_base + trip->reg_offs); 209 + 210 + val &= trip->reg_msk; 211 + val >>= trip->reg_shift; 212 + 213 + return avs_tmon_code_to_temp(priv->thermal, val); 214 + } 215 + 216 + static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv, 217 + enum avs_tmon_trip_type type, 218 + int temp) 219 + { 220 + struct avs_tmon_trip *trip = &avs_tmon_trips[type]; 221 + u32 val, orig; 222 + 223 + dev_dbg(priv->dev, "set temp %d to %d\n", type, temp); 224 + 225 + /* round toward low temp for the low interrupt */ 226 + val = avs_tmon_temp_to_code(priv->thermal, temp, 227 + type == TMON_TRIP_TYPE_LOW); 228 + 229 + val <<= trip->reg_shift; 230 + val &= trip->reg_msk; 231 + 232 + orig = __raw_readl(priv->tmon_base + trip->reg_offs); 233 + orig &= ~trip->reg_msk; 234 + orig |= val; 235 + __raw_writel(orig, priv->tmon_base + trip->reg_offs); 236 + } 237 + 238 + static int avs_tmon_get_intr_temp(struct brcmstb_thermal_priv *priv) 239 + { 240 + u32 val; 241 + 242 + val = __raw_readl(priv->tmon_base + AVS_TMON_TEMP_INT_CODE); 243 + return avs_tmon_code_to_temp(priv->thermal, val); 244 + } 245 + 246 + static irqreturn_t brcmstb_tmon_irq_thread(int irq, void *data) 247 + { 248 + struct brcmstb_thermal_priv *priv = data; 249 + int low, high, intr; 250 + 251 + low = avs_tmon_get_trip_temp(priv, TMON_TRIP_TYPE_LOW); 252 + high = avs_tmon_get_trip_temp(priv, TMON_TRIP_TYPE_HIGH); 253 + intr = avs_tmon_get_intr_temp(priv); 254 + 255 + dev_dbg(priv->dev, "low/intr/high: %d/%d/%d\n", 256 + low, intr, high); 257 + 258 + /* Disable high-temp until next threshold shift */ 259 + if (intr >= high) 260 + avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_HIGH, 0); 261 + /* Disable low-temp until next threshold shift */ 262 + if (intr <= low) 263 + avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_LOW, 0); 264 + 265 + /* 266 + * Notify using the interrupt temperature, in case the temperature 267 + * changes before it can next be read out 268 + */ 269 + thermal_zone_device_update(priv->thermal, intr); 270 + 271 + return IRQ_HANDLED; 272 + } 273 + 274 + static int brcmstb_set_trips(void *data, int low, int high) 275 + { 276 + struct brcmstb_thermal_priv *priv = data; 277 + 278 + dev_dbg(priv->dev, "set trips %d <--> %d\n", low, high); 279 + 280 + /* 281 + * Disable low-temp if "low" is too small. As per thermal framework 282 + * API, we use -INT_MAX rather than INT_MIN. 283 + */ 284 + if (low <= -INT_MAX) { 285 + avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_LOW, 0); 286 + } else { 287 + avs_tmon_set_trip_temp(priv, TMON_TRIP_TYPE_LOW, low); 288 + avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_LOW, 1); 289 + } 290 + 291 + /* Disable high-temp if "high" is too big. */ 292 + if (high == INT_MAX) { 293 + avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_HIGH, 0); 294 + } else { 295 + avs_tmon_set_trip_temp(priv, TMON_TRIP_TYPE_HIGH, high); 296 + avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_HIGH, 1); 297 + } 298 + 299 + return 0; 300 + } 301 + 302 + static struct thermal_zone_of_device_ops of_ops = { 303 + .get_temp = brcmstb_get_temp, 304 + .set_trips = brcmstb_set_trips, 305 + }; 306 + 307 + static const struct of_device_id brcmstb_thermal_id_table[] = { 308 + { .compatible = "brcm,avs-tmon" }, 309 + {}, 310 + }; 311 + MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table); 312 + 313 + static int brcmstb_thermal_probe(struct platform_device *pdev) 314 + { 315 + struct thermal_zone_device *thermal; 316 + struct brcmstb_thermal_priv *priv; 317 + struct resource *res; 318 + int irq, ret; 319 + 320 + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 321 + if (!priv) 322 + return -ENOMEM; 323 + 324 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 325 + priv->tmon_base = devm_ioremap_resource(&pdev->dev, res); 326 + if (IS_ERR(priv->tmon_base)) 327 + return PTR_ERR(priv->tmon_base); 328 + 329 + priv->dev = &pdev->dev; 330 + platform_set_drvdata(pdev, priv); 331 + 332 + thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops); 333 + if (IS_ERR(thermal)) { 334 + ret = PTR_ERR(thermal); 335 + dev_err(&pdev->dev, "could not register sensor: %d\n", ret); 336 + return ret; 337 + } 338 + 339 + priv->thermal = thermal; 340 + 341 + irq = platform_get_irq(pdev, 0); 342 + if (irq < 0) { 343 + dev_err(&pdev->dev, "could not get IRQ\n"); 344 + ret = irq; 345 + goto err; 346 + } 347 + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 348 + brcmstb_tmon_irq_thread, IRQF_ONESHOT, 349 + DRV_NAME, priv); 350 + if (ret < 0) { 351 + dev_err(&pdev->dev, "could not request IRQ: %d\n", ret); 352 + goto err; 353 + } 354 + 355 + dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n"); 356 + 357 + return 0; 358 + 359 + err: 360 + thermal_zone_of_sensor_unregister(&pdev->dev, thermal); 361 + return ret; 362 + } 363 + 364 + static int brcmstb_thermal_exit(struct platform_device *pdev) 365 + { 366 + struct brcmstb_thermal_priv *priv = platform_get_drvdata(pdev); 367 + struct thermal_zone_device *thermal = priv->thermal; 368 + 369 + if (thermal) 370 + thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal); 371 + 372 + return 0; 373 + } 374 + 375 + static struct platform_driver brcmstb_thermal_driver = { 376 + .probe = brcmstb_thermal_probe, 377 + .remove = brcmstb_thermal_exit, 378 + .driver = { 379 + .name = DRV_NAME, 380 + .of_match_table = brcmstb_thermal_id_table, 381 + }, 382 + }; 383 + module_platform_driver(brcmstb_thermal_driver); 384 + 385 + MODULE_LICENSE("GPL v2"); 386 + MODULE_AUTHOR("Brian Norris"); 387 + MODULE_DESCRIPTION("Broadcom STB AVS TMON thermal driver");
+1 -1
drivers/thermal/cpu_cooling.c
··· 696 696 bool first; 697 697 698 698 if (IS_ERR_OR_NULL(policy)) { 699 - pr_err("%s: cpufreq policy isn't valid: %p", __func__, policy); 699 + pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy); 700 700 return ERR_PTR(-EINVAL); 701 701 } 702 702
+418 -222
drivers/thermal/hisi_thermal.c
··· 23 23 #include <linux/module.h> 24 24 #include <linux/platform_device.h> 25 25 #include <linux/io.h> 26 + #include <linux/of_device.h> 26 27 27 28 #include "thermal_core.h" 28 29 29 - #define TEMP0_TH (0x4) 30 - #define TEMP0_RST_TH (0x8) 31 - #define TEMP0_CFG (0xC) 32 - #define TEMP0_EN (0x10) 33 - #define TEMP0_INT_EN (0x14) 34 - #define TEMP0_INT_CLR (0x18) 35 - #define TEMP0_RST_MSK (0x1C) 36 - #define TEMP0_VALUE (0x28) 30 + #define HI6220_TEMP0_LAG (0x0) 31 + #define HI6220_TEMP0_TH (0x4) 32 + #define HI6220_TEMP0_RST_TH (0x8) 33 + #define HI6220_TEMP0_CFG (0xC) 34 + #define HI6220_TEMP0_CFG_SS_MSK (0xF000) 35 + #define HI6220_TEMP0_CFG_HDAK_MSK (0x30) 36 + #define HI6220_TEMP0_EN (0x10) 37 + #define HI6220_TEMP0_INT_EN (0x14) 38 + #define HI6220_TEMP0_INT_CLR (0x18) 39 + #define HI6220_TEMP0_RST_MSK (0x1C) 40 + #define HI6220_TEMP0_VALUE (0x28) 37 41 38 - #define HISI_TEMP_BASE (-60) 39 - #define HISI_TEMP_RESET (100000) 42 + #define HI3660_OFFSET(chan) ((chan) * 0x40) 43 + #define HI3660_TEMP(chan) (HI3660_OFFSET(chan) + 0x1C) 44 + #define HI3660_TH(chan) (HI3660_OFFSET(chan) + 0x20) 45 + #define HI3660_LAG(chan) (HI3660_OFFSET(chan) + 0x28) 46 + #define HI3660_INT_EN(chan) (HI3660_OFFSET(chan) + 0x2C) 47 + #define HI3660_INT_CLR(chan) (HI3660_OFFSET(chan) + 0x30) 40 48 41 - #define HISI_MAX_SENSORS 4 49 + #define HI6220_TEMP_BASE (-60000) 50 + #define HI6220_TEMP_RESET (100000) 51 + #define HI6220_TEMP_STEP (785) 52 + #define HI6220_TEMP_LAG (3500) 53 + 54 + #define HI3660_TEMP_BASE (-63780) 55 + #define HI3660_TEMP_STEP (205) 56 + #define HI3660_TEMP_LAG (4000) 57 + 58 + #define HI6220_DEFAULT_SENSOR 2 59 + #define HI3660_DEFAULT_SENSOR 1 42 60 43 61 struct hisi_thermal_sensor { 44 - struct hisi_thermal_data *thermal; 45 62 struct thermal_zone_device *tzd; 46 - 47 - long sensor_temp; 48 63 uint32_t id; 49 64 uint32_t thres_temp; 50 65 }; 51 66 52 67 struct hisi_thermal_data { 53 - struct mutex thermal_lock; /* protects register data */ 68 + int (*get_temp)(struct hisi_thermal_data *data); 69 + int (*enable_sensor)(struct hisi_thermal_data *data); 70 + int (*disable_sensor)(struct hisi_thermal_data *data); 71 + int (*irq_handler)(struct hisi_thermal_data *data); 54 72 struct platform_device *pdev; 55 73 struct clk *clk; 56 - struct hisi_thermal_sensor sensors[HISI_MAX_SENSORS]; 57 - 58 - int irq, irq_bind_sensor; 59 - bool irq_enabled; 60 - 74 + struct hisi_thermal_sensor sensor; 61 75 void __iomem *regs; 76 + int irq; 62 77 }; 63 78 64 - /* in millicelsius */ 65 - static inline int _step_to_temp(int step) 79 + /* 80 + * The temperature computation on the tsensor is as follow: 81 + * Unit: millidegree Celsius 82 + * Step: 200/255 (0.7843) 83 + * Temperature base: -60°C 84 + * 85 + * The register is programmed in temperature steps, every step is 785 86 + * millidegree and begins at -60 000 m°C 87 + * 88 + * The temperature from the steps: 89 + * 90 + * Temp = TempBase + (steps x 785) 91 + * 92 + * and the steps from the temperature: 93 + * 94 + * steps = (Temp - TempBase) / 785 95 + * 96 + */ 97 + static inline int hi6220_thermal_step_to_temp(int step) 66 98 { 67 - /* 68 - * Every step equals (1 * 200) / 255 celsius, and finally 69 - * need convert to millicelsius. 70 - */ 71 - return (HISI_TEMP_BASE * 1000 + (step * 200000 / 255)); 99 + return HI6220_TEMP_BASE + (step * HI6220_TEMP_STEP); 72 100 } 73 101 74 - static inline long _temp_to_step(long temp) 102 + static inline int hi6220_thermal_temp_to_step(int temp) 75 103 { 76 - return ((temp - HISI_TEMP_BASE * 1000) * 255) / 200000; 104 + return DIV_ROUND_UP(temp - HI6220_TEMP_BASE, HI6220_TEMP_STEP); 77 105 } 78 106 79 - static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data, 80 - struct hisi_thermal_sensor *sensor) 107 + /* 108 + * for Hi3660, 109 + * Step: 189/922 (0.205) 110 + * Temperature base: -63.780°C 111 + * 112 + * The register is programmed in temperature steps, every step is 205 113 + * millidegree and begins at -63 780 m°C 114 + */ 115 + static inline int hi3660_thermal_step_to_temp(int step) 81 116 { 82 - long val; 117 + return HI3660_TEMP_BASE + step * HI3660_TEMP_STEP; 118 + } 83 119 84 - mutex_lock(&data->thermal_lock); 120 + static inline int hi3660_thermal_temp_to_step(int temp) 121 + { 122 + return DIV_ROUND_UP(temp - HI3660_TEMP_BASE, HI3660_TEMP_STEP); 123 + } 85 124 86 - /* disable interrupt */ 87 - writel(0x0, data->regs + TEMP0_INT_EN); 88 - writel(0x1, data->regs + TEMP0_INT_CLR); 125 + /* 126 + * The lag register contains 5 bits encoding the temperature in steps. 127 + * 128 + * Each time the temperature crosses the threshold boundary, an 129 + * interrupt is raised. It could be when the temperature is going 130 + * above the threshold or below. However, if the temperature is 131 + * fluctuating around this value due to the load, we can receive 132 + * several interrupts which may not desired. 133 + * 134 + * We can setup a temperature representing the delta between the 135 + * threshold and the current temperature when the temperature is 136 + * decreasing. 137 + * 138 + * For instance: the lag register is 5°C, the threshold is 65°C, when 139 + * the temperature reaches 65°C an interrupt is raised and when the 140 + * temperature decrease to 65°C - 5°C another interrupt is raised. 141 + * 142 + * A very short lag can lead to an interrupt storm, a long lag 143 + * increase the latency to react to the temperature changes. In our 144 + * case, that is not really a problem as we are polling the 145 + * temperature. 146 + * 147 + * [0:4] : lag register 148 + * 149 + * The temperature is coded in steps, cf. HI6220_TEMP_STEP. 150 + * 151 + * Min : 0x00 : 0.0 °C 152 + * Max : 0x1F : 24.3 °C 153 + * 154 + * The 'value' parameter is in milliCelsius. 155 + */ 156 + static inline void hi6220_thermal_set_lag(void __iomem *addr, int value) 157 + { 158 + writel(DIV_ROUND_UP(value, HI6220_TEMP_STEP) & 0x1F, 159 + addr + HI6220_TEMP0_LAG); 160 + } 161 + 162 + static inline void hi6220_thermal_alarm_clear(void __iomem *addr, int value) 163 + { 164 + writel(value, addr + HI6220_TEMP0_INT_CLR); 165 + } 166 + 167 + static inline void hi6220_thermal_alarm_enable(void __iomem *addr, int value) 168 + { 169 + writel(value, addr + HI6220_TEMP0_INT_EN); 170 + } 171 + 172 + static inline void hi6220_thermal_alarm_set(void __iomem *addr, int temp) 173 + { 174 + writel(hi6220_thermal_temp_to_step(temp) | 0x0FFFFFF00, 175 + addr + HI6220_TEMP0_TH); 176 + } 177 + 178 + static inline void hi6220_thermal_reset_set(void __iomem *addr, int temp) 179 + { 180 + writel(hi6220_thermal_temp_to_step(temp), addr + HI6220_TEMP0_RST_TH); 181 + } 182 + 183 + static inline void hi6220_thermal_reset_enable(void __iomem *addr, int value) 184 + { 185 + writel(value, addr + HI6220_TEMP0_RST_MSK); 186 + } 187 + 188 + static inline void hi6220_thermal_enable(void __iomem *addr, int value) 189 + { 190 + writel(value, addr + HI6220_TEMP0_EN); 191 + } 192 + 193 + static inline int hi6220_thermal_get_temperature(void __iomem *addr) 194 + { 195 + return hi6220_thermal_step_to_temp(readl(addr + HI6220_TEMP0_VALUE)); 196 + } 197 + 198 + /* 199 + * [0:6] lag register 200 + * 201 + * The temperature is coded in steps, cf. HI3660_TEMP_STEP. 202 + * 203 + * Min : 0x00 : 0.0 °C 204 + * Max : 0x7F : 26.0 °C 205 + * 206 + */ 207 + static inline void hi3660_thermal_set_lag(void __iomem *addr, 208 + int id, int value) 209 + { 210 + writel(DIV_ROUND_UP(value, HI3660_TEMP_STEP) & 0x7F, 211 + addr + HI3660_LAG(id)); 212 + } 213 + 214 + static inline void hi3660_thermal_alarm_clear(void __iomem *addr, 215 + int id, int value) 216 + { 217 + writel(value, addr + HI3660_INT_CLR(id)); 218 + } 219 + 220 + static inline void hi3660_thermal_alarm_enable(void __iomem *addr, 221 + int id, int value) 222 + { 223 + writel(value, addr + HI3660_INT_EN(id)); 224 + } 225 + 226 + static inline void hi3660_thermal_alarm_set(void __iomem *addr, 227 + int id, int value) 228 + { 229 + writel(value, addr + HI3660_TH(id)); 230 + } 231 + 232 + static inline int hi3660_thermal_get_temperature(void __iomem *addr, int id) 233 + { 234 + return hi3660_thermal_step_to_temp(readl(addr + HI3660_TEMP(id))); 235 + } 236 + 237 + /* 238 + * Temperature configuration register - Sensor selection 239 + * 240 + * Bits [19:12] 241 + * 242 + * 0x0: local sensor (default) 243 + * 0x1: remote sensor 1 (ACPU cluster 1) 244 + * 0x2: remote sensor 2 (ACPU cluster 0) 245 + * 0x3: remote sensor 3 (G3D) 246 + */ 247 + static inline void hi6220_thermal_sensor_select(void __iomem *addr, int sensor) 248 + { 249 + writel((readl(addr + HI6220_TEMP0_CFG) & ~HI6220_TEMP0_CFG_SS_MSK) | 250 + (sensor << 12), addr + HI6220_TEMP0_CFG); 251 + } 252 + 253 + /* 254 + * Temperature configuration register - Hdak conversion polling interval 255 + * 256 + * Bits [5:4] 257 + * 258 + * 0x0 : 0.768 ms 259 + * 0x1 : 6.144 ms 260 + * 0x2 : 49.152 ms 261 + * 0x3 : 393.216 ms 262 + */ 263 + static inline void hi6220_thermal_hdak_set(void __iomem *addr, int value) 264 + { 265 + writel((readl(addr + HI6220_TEMP0_CFG) & ~HI6220_TEMP0_CFG_HDAK_MSK) | 266 + (value << 4), addr + HI6220_TEMP0_CFG); 267 + } 268 + 269 + static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data) 270 + { 271 + hi6220_thermal_alarm_clear(data->regs, 1); 272 + return 0; 273 + } 274 + 275 + static int hi3660_thermal_irq_handler(struct hisi_thermal_data *data) 276 + { 277 + hi3660_thermal_alarm_clear(data->regs, data->sensor.id, 1); 278 + return 0; 279 + } 280 + 281 + static int hi6220_thermal_get_temp(struct hisi_thermal_data *data) 282 + { 283 + return hi6220_thermal_get_temperature(data->regs); 284 + } 285 + 286 + static int hi3660_thermal_get_temp(struct hisi_thermal_data *data) 287 + { 288 + return hi3660_thermal_get_temperature(data->regs, data->sensor.id); 289 + } 290 + 291 + static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) 292 + { 293 + /* disable sensor module */ 294 + hi6220_thermal_enable(data->regs, 0); 295 + hi6220_thermal_alarm_enable(data->regs, 0); 296 + hi6220_thermal_reset_enable(data->regs, 0); 297 + 298 + clk_disable_unprepare(data->clk); 299 + 300 + return 0; 301 + } 302 + 303 + static int hi3660_thermal_disable_sensor(struct hisi_thermal_data *data) 304 + { 305 + /* disable sensor module */ 306 + hi3660_thermal_alarm_enable(data->regs, data->sensor.id, 0); 307 + return 0; 308 + } 309 + 310 + static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) 311 + { 312 + struct hisi_thermal_sensor *sensor = &data->sensor; 313 + int ret; 314 + 315 + /* enable clock for tsensor */ 316 + ret = clk_prepare_enable(data->clk); 317 + if (ret) 318 + return ret; 89 319 90 320 /* disable module firstly */ 91 - writel(0x0, data->regs + TEMP0_EN); 321 + hi6220_thermal_reset_enable(data->regs, 0); 322 + hi6220_thermal_enable(data->regs, 0); 92 323 93 324 /* select sensor id */ 94 - writel((sensor->id << 12), data->regs + TEMP0_CFG); 95 - 96 - /* enable module */ 97 - writel(0x1, data->regs + TEMP0_EN); 98 - 99 - usleep_range(3000, 5000); 100 - 101 - val = readl(data->regs + TEMP0_VALUE); 102 - val = _step_to_temp(val); 103 - 104 - mutex_unlock(&data->thermal_lock); 105 - 106 - return val; 107 - } 108 - 109 - static void hisi_thermal_enable_bind_irq_sensor 110 - (struct hisi_thermal_data *data) 111 - { 112 - struct hisi_thermal_sensor *sensor; 113 - 114 - mutex_lock(&data->thermal_lock); 115 - 116 - sensor = &data->sensors[data->irq_bind_sensor]; 325 + hi6220_thermal_sensor_select(data->regs, sensor->id); 117 326 118 327 /* setting the hdak time */ 119 - writel(0x0, data->regs + TEMP0_CFG); 328 + hi6220_thermal_hdak_set(data->regs, 0); 120 329 121 - /* disable module firstly */ 122 - writel(0x0, data->regs + TEMP0_RST_MSK); 123 - writel(0x0, data->regs + TEMP0_EN); 124 - 125 - /* select sensor id */ 126 - writel((sensor->id << 12), data->regs + TEMP0_CFG); 330 + /* setting lag value between current temp and the threshold */ 331 + hi6220_thermal_set_lag(data->regs, HI6220_TEMP_LAG); 127 332 128 333 /* enable for interrupt */ 129 - writel(_temp_to_step(sensor->thres_temp) | 0x0FFFFFF00, 130 - data->regs + TEMP0_TH); 334 + hi6220_thermal_alarm_set(data->regs, sensor->thres_temp); 131 335 132 - writel(_temp_to_step(HISI_TEMP_RESET), data->regs + TEMP0_RST_TH); 336 + hi6220_thermal_reset_set(data->regs, HI6220_TEMP_RESET); 133 337 134 338 /* enable module */ 135 - writel(0x1, data->regs + TEMP0_RST_MSK); 136 - writel(0x1, data->regs + TEMP0_EN); 339 + hi6220_thermal_reset_enable(data->regs, 1); 340 + hi6220_thermal_enable(data->regs, 1); 137 341 138 - writel(0x0, data->regs + TEMP0_INT_CLR); 139 - writel(0x1, data->regs + TEMP0_INT_EN); 342 + hi6220_thermal_alarm_clear(data->regs, 0); 343 + hi6220_thermal_alarm_enable(data->regs, 1); 140 344 141 - usleep_range(3000, 5000); 142 - 143 - mutex_unlock(&data->thermal_lock); 345 + return 0; 144 346 } 145 347 146 - static void hisi_thermal_disable_sensor(struct hisi_thermal_data *data) 348 + static int hi3660_thermal_enable_sensor(struct hisi_thermal_data *data) 147 349 { 148 - mutex_lock(&data->thermal_lock); 350 + unsigned int value; 351 + struct hisi_thermal_sensor *sensor = &data->sensor; 149 352 150 - /* disable sensor module */ 151 - writel(0x0, data->regs + TEMP0_INT_EN); 152 - writel(0x0, data->regs + TEMP0_RST_MSK); 153 - writel(0x0, data->regs + TEMP0_EN); 353 + /* disable interrupt */ 354 + hi3660_thermal_alarm_enable(data->regs, sensor->id, 0); 154 355 155 - mutex_unlock(&data->thermal_lock); 356 + /* setting lag value between current temp and the threshold */ 357 + hi3660_thermal_set_lag(data->regs, sensor->id, HI3660_TEMP_LAG); 358 + 359 + /* set interrupt threshold */ 360 + value = hi3660_thermal_temp_to_step(sensor->thres_temp); 361 + hi3660_thermal_alarm_set(data->regs, sensor->id, value); 362 + 363 + /* enable interrupt */ 364 + hi3660_thermal_alarm_clear(data->regs, sensor->id, 1); 365 + hi3660_thermal_alarm_enable(data->regs, sensor->id, 1); 366 + 367 + return 0; 156 368 } 157 369 158 - static int hisi_thermal_get_temp(void *_sensor, int *temp) 370 + static int hi6220_thermal_probe(struct hisi_thermal_data *data) 159 371 { 160 - struct hisi_thermal_sensor *sensor = _sensor; 161 - struct hisi_thermal_data *data = sensor->thermal; 372 + struct platform_device *pdev = data->pdev; 373 + struct device *dev = &pdev->dev; 374 + struct resource *res; 375 + int ret; 162 376 163 - int sensor_id = -1, i; 164 - long max_temp = 0; 377 + data->get_temp = hi6220_thermal_get_temp; 378 + data->enable_sensor = hi6220_thermal_enable_sensor; 379 + data->disable_sensor = hi6220_thermal_disable_sensor; 380 + data->irq_handler = hi6220_thermal_irq_handler; 165 381 166 - *temp = hisi_thermal_get_sensor_temp(data, sensor); 167 - 168 - sensor->sensor_temp = *temp; 169 - 170 - for (i = 0; i < HISI_MAX_SENSORS; i++) { 171 - if (!data->sensors[i].tzd) 172 - continue; 173 - 174 - if (data->sensors[i].sensor_temp >= max_temp) { 175 - max_temp = data->sensors[i].sensor_temp; 176 - sensor_id = i; 177 - } 382 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 383 + data->regs = devm_ioremap_resource(dev, res); 384 + if (IS_ERR(data->regs)) { 385 + dev_err(dev, "failed to get io address\n"); 386 + return PTR_ERR(data->regs); 178 387 } 179 388 180 - /* If no sensor has been enabled, then skip to enable irq */ 181 - if (sensor_id == -1) 182 - return 0; 183 - 184 - mutex_lock(&data->thermal_lock); 185 - data->irq_bind_sensor = sensor_id; 186 - mutex_unlock(&data->thermal_lock); 187 - 188 - dev_dbg(&data->pdev->dev, "id=%d, irq=%d, temp=%d, thres=%d\n", 189 - sensor->id, data->irq_enabled, *temp, sensor->thres_temp); 190 - /* 191 - * Bind irq to sensor for two cases: 192 - * Reenable alarm IRQ if temperature below threshold; 193 - * if irq has been enabled, always set it; 194 - */ 195 - if (data->irq_enabled) { 196 - hisi_thermal_enable_bind_irq_sensor(data); 197 - return 0; 389 + data->clk = devm_clk_get(dev, "thermal_clk"); 390 + if (IS_ERR(data->clk)) { 391 + ret = PTR_ERR(data->clk); 392 + if (ret != -EPROBE_DEFER) 393 + dev_err(dev, "failed to get thermal clk: %d\n", ret); 394 + return ret; 198 395 } 199 396 200 - if (max_temp < sensor->thres_temp) { 201 - data->irq_enabled = true; 202 - hisi_thermal_enable_bind_irq_sensor(data); 203 - enable_irq(data->irq); 397 + data->irq = platform_get_irq(pdev, 0); 398 + if (data->irq < 0) 399 + return data->irq; 400 + 401 + data->sensor.id = HI6220_DEFAULT_SENSOR; 402 + 403 + return 0; 404 + } 405 + 406 + static int hi3660_thermal_probe(struct hisi_thermal_data *data) 407 + { 408 + struct platform_device *pdev = data->pdev; 409 + struct device *dev = &pdev->dev; 410 + struct resource *res; 411 + 412 + data->get_temp = hi3660_thermal_get_temp; 413 + data->enable_sensor = hi3660_thermal_enable_sensor; 414 + data->disable_sensor = hi3660_thermal_disable_sensor; 415 + data->irq_handler = hi3660_thermal_irq_handler; 416 + 417 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 418 + data->regs = devm_ioremap_resource(dev, res); 419 + if (IS_ERR(data->regs)) { 420 + dev_err(dev, "failed to get io address\n"); 421 + return PTR_ERR(data->regs); 204 422 } 423 + 424 + data->irq = platform_get_irq(pdev, 0); 425 + if (data->irq < 0) 426 + return data->irq; 427 + 428 + data->sensor.id = HI3660_DEFAULT_SENSOR; 429 + 430 + return 0; 431 + } 432 + 433 + static int hisi_thermal_get_temp(void *__data, int *temp) 434 + { 435 + struct hisi_thermal_data *data = __data; 436 + struct hisi_thermal_sensor *sensor = &data->sensor; 437 + 438 + *temp = data->get_temp(data); 439 + 440 + dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n", 441 + sensor->id, *temp, sensor->thres_temp); 205 442 206 443 return 0; 207 444 } ··· 447 210 .get_temp = hisi_thermal_get_temp, 448 211 }; 449 212 450 - static irqreturn_t hisi_thermal_alarm_irq(int irq, void *dev) 451 - { 452 - struct hisi_thermal_data *data = dev; 453 - 454 - disable_irq_nosync(irq); 455 - data->irq_enabled = false; 456 - 457 - return IRQ_WAKE_THREAD; 458 - } 459 - 460 213 static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) 461 214 { 462 215 struct hisi_thermal_data *data = dev; 463 - struct hisi_thermal_sensor *sensor; 464 - int i; 216 + struct hisi_thermal_sensor *sensor = &data->sensor; 217 + int temp = 0; 465 218 466 - mutex_lock(&data->thermal_lock); 467 - sensor = &data->sensors[data->irq_bind_sensor]; 219 + data->irq_handler(data); 468 220 469 - dev_crit(&data->pdev->dev, "THERMAL ALARM: T > %d\n", 470 - sensor->thres_temp / 1000); 471 - mutex_unlock(&data->thermal_lock); 221 + hisi_thermal_get_temp(data, &temp); 472 222 473 - for (i = 0; i < HISI_MAX_SENSORS; i++) { 474 - if (!data->sensors[i].tzd) 475 - continue; 223 + if (temp >= sensor->thres_temp) { 224 + dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n", 225 + temp, sensor->thres_temp); 476 226 477 - thermal_zone_device_update(data->sensors[i].tzd, 227 + thermal_zone_device_update(data->sensor.tzd, 478 228 THERMAL_EVENT_UNSPECIFIED); 229 + 230 + } else { 231 + dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n", 232 + temp, sensor->thres_temp); 479 233 } 480 234 481 235 return IRQ_HANDLED; ··· 474 246 475 247 static int hisi_thermal_register_sensor(struct platform_device *pdev, 476 248 struct hisi_thermal_data *data, 477 - struct hisi_thermal_sensor *sensor, 478 - int index) 249 + struct hisi_thermal_sensor *sensor) 479 250 { 480 251 int ret, i; 481 252 const struct thermal_trip *trip; 482 253 483 - sensor->id = index; 484 - sensor->thermal = data; 485 - 486 254 sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 487 - sensor->id, sensor, &hisi_of_thermal_ops); 255 + sensor->id, data, 256 + &hisi_of_thermal_ops); 488 257 if (IS_ERR(sensor->tzd)) { 489 258 ret = PTR_ERR(sensor->tzd); 490 259 sensor->tzd = NULL; ··· 503 278 } 504 279 505 280 static const struct of_device_id of_hisi_thermal_match[] = { 506 - { .compatible = "hisilicon,tsensor" }, 281 + { 282 + .compatible = "hisilicon,tsensor", 283 + .data = hi6220_thermal_probe 284 + }, 285 + { 286 + .compatible = "hisilicon,hi3660-tsensor", 287 + .data = hi3660_thermal_probe 288 + }, 507 289 { /* end */ } 508 290 }; 509 291 MODULE_DEVICE_TABLE(of, of_hisi_thermal_match); ··· 527 295 static int hisi_thermal_probe(struct platform_device *pdev) 528 296 { 529 297 struct hisi_thermal_data *data; 530 - struct resource *res; 531 - int i; 298 + int const (*platform_probe)(struct hisi_thermal_data *); 299 + struct device *dev = &pdev->dev; 532 300 int ret; 533 301 534 - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 302 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 535 303 if (!data) 536 304 return -ENOMEM; 537 305 538 - mutex_init(&data->thermal_lock); 539 306 data->pdev = pdev; 540 - 541 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 542 - data->regs = devm_ioremap_resource(&pdev->dev, res); 543 - if (IS_ERR(data->regs)) { 544 - dev_err(&pdev->dev, "failed to get io address\n"); 545 - return PTR_ERR(data->regs); 546 - } 547 - 548 - data->irq = platform_get_irq(pdev, 0); 549 - if (data->irq < 0) 550 - return data->irq; 551 - 552 - ret = devm_request_threaded_irq(&pdev->dev, data->irq, 553 - hisi_thermal_alarm_irq, 554 - hisi_thermal_alarm_irq_thread, 555 - 0, "hisi_thermal", data); 556 - if (ret < 0) { 557 - dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); 558 - return ret; 559 - } 560 - 561 307 platform_set_drvdata(pdev, data); 562 308 563 - data->clk = devm_clk_get(&pdev->dev, "thermal_clk"); 564 - if (IS_ERR(data->clk)) { 565 - ret = PTR_ERR(data->clk); 566 - if (ret != -EPROBE_DEFER) 567 - dev_err(&pdev->dev, 568 - "failed to get thermal clk: %d\n", ret); 569 - return ret; 309 + platform_probe = of_device_get_match_data(dev); 310 + if (!platform_probe) { 311 + dev_err(dev, "failed to get probe func\n"); 312 + return -EINVAL; 570 313 } 571 314 572 - /* enable clock for thermal */ 573 - ret = clk_prepare_enable(data->clk); 315 + ret = platform_probe(data); 316 + if (ret) 317 + return ret; 318 + 319 + ret = hisi_thermal_register_sensor(pdev, data, 320 + &data->sensor); 574 321 if (ret) { 575 - dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 322 + dev_err(dev, "failed to register thermal sensor: %d\n", ret); 576 323 return ret; 577 324 } 578 325 579 - hisi_thermal_enable_bind_irq_sensor(data); 580 - irq_get_irqchip_state(data->irq, IRQCHIP_STATE_MASKED, 581 - &data->irq_enabled); 582 - 583 - for (i = 0; i < HISI_MAX_SENSORS; ++i) { 584 - ret = hisi_thermal_register_sensor(pdev, data, 585 - &data->sensors[i], i); 586 - if (ret) 587 - dev_err(&pdev->dev, 588 - "failed to register thermal sensor: %d\n", ret); 589 - else 590 - hisi_thermal_toggle_sensor(&data->sensors[i], true); 326 + ret = data->enable_sensor(data); 327 + if (ret) { 328 + dev_err(dev, "Failed to setup the sensor: %d\n", ret); 329 + return ret; 591 330 } 331 + 332 + if (data->irq) { 333 + ret = devm_request_threaded_irq(dev, data->irq, NULL, 334 + hisi_thermal_alarm_irq_thread, 335 + IRQF_ONESHOT, "hisi_thermal", data); 336 + if (ret < 0) { 337 + dev_err(dev, "failed to request alarm irq: %d\n", ret); 338 + return ret; 339 + } 340 + } 341 + 342 + hisi_thermal_toggle_sensor(&data->sensor, true); 592 343 593 344 return 0; 594 345 } ··· 579 364 static int hisi_thermal_remove(struct platform_device *pdev) 580 365 { 581 366 struct hisi_thermal_data *data = platform_get_drvdata(pdev); 582 - int i; 367 + struct hisi_thermal_sensor *sensor = &data->sensor; 583 368 584 - for (i = 0; i < HISI_MAX_SENSORS; i++) { 585 - struct hisi_thermal_sensor *sensor = &data->sensors[i]; 369 + hisi_thermal_toggle_sensor(sensor, false); 586 370 587 - if (!sensor->tzd) 588 - continue; 589 - 590 - hisi_thermal_toggle_sensor(sensor, false); 591 - } 592 - 593 - hisi_thermal_disable_sensor(data); 594 - clk_disable_unprepare(data->clk); 371 + data->disable_sensor(data); 595 372 596 373 return 0; 597 374 } ··· 593 386 { 594 387 struct hisi_thermal_data *data = dev_get_drvdata(dev); 595 388 596 - hisi_thermal_disable_sensor(data); 597 - data->irq_enabled = false; 598 - 599 - clk_disable_unprepare(data->clk); 389 + data->disable_sensor(data); 600 390 601 391 return 0; 602 392 } ··· 601 397 static int hisi_thermal_resume(struct device *dev) 602 398 { 603 399 struct hisi_thermal_data *data = dev_get_drvdata(dev); 604 - int ret; 605 400 606 - ret = clk_prepare_enable(data->clk); 607 - if (ret) 608 - return ret; 609 - 610 - data->irq_enabled = true; 611 - hisi_thermal_enable_bind_irq_sensor(data); 612 - 613 - return 0; 401 + return data->enable_sensor(data); 614 402 } 615 403 #endif 616 404
+74 -30
drivers/thermal/imx_thermal.c
··· 25 25 #include <linux/slab.h> 26 26 #include <linux/thermal.h> 27 27 #include <linux/types.h> 28 + #include <linux/nvmem-consumer.h> 28 29 29 30 #define REG_SET 0x4 30 31 #define REG_CLR 0x8 ··· 95 94 struct thermal_cooling_device *cdev; 96 95 enum thermal_device_mode mode; 97 96 struct regmap *tempmon; 98 - u32 c1, c2; /* See formula in imx_get_sensor_data() */ 97 + u32 c1, c2; /* See formula in imx_init_calib() */ 99 98 int temp_passive; 100 99 int temp_critical; 101 100 int temp_max; ··· 178 177 179 178 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; 180 179 181 - /* See imx_get_sensor_data() for formula derivation */ 180 + /* See imx_init_calib() for formula derivation */ 182 181 *temp = data->c2 - n_meas * data->c1; 183 182 184 183 /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */ ··· 347 346 .set_trip_temp = imx_set_trip_temp, 348 347 }; 349 348 350 - static int imx_get_sensor_data(struct platform_device *pdev) 349 + static int imx_init_calib(struct platform_device *pdev, u32 val) 351 350 { 352 351 struct imx_thermal_data *data = platform_get_drvdata(pdev); 353 - struct regmap *map; 354 352 int t1, n1; 355 - int ret; 356 - u32 val; 357 353 u64 temp64; 358 - 359 - map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 360 - "fsl,tempmon-data"); 361 - if (IS_ERR(map)) { 362 - ret = PTR_ERR(map); 363 - dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret); 364 - return ret; 365 - } 366 - 367 - ret = regmap_read(map, OCOTP_ANA1, &val); 368 - if (ret) { 369 - dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret); 370 - return ret; 371 - } 372 354 373 355 if (val == 0 || val == ~0) { 374 356 dev_err(&pdev->dev, "invalid sensor calibration data\n"); ··· 389 405 data->c1 = temp64; 390 406 data->c2 = n1 * data->c1 + 1000 * t1; 391 407 392 - /* use OTP for thermal grade */ 393 - ret = regmap_read(map, OCOTP_MEM0, &val); 394 - if (ret) { 395 - dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret); 396 - return ret; 397 - } 408 + return 0; 409 + } 410 + 411 + static void imx_init_temp_grade(struct platform_device *pdev, u32 val) 412 + { 413 + struct imx_thermal_data *data = platform_get_drvdata(pdev); 398 414 399 415 /* The maximum die temp is specified by the Temperature Grade */ 400 416 switch ((val >> 6) & 0x3) { ··· 422 438 */ 423 439 data->temp_critical = data->temp_max - (1000 * 5); 424 440 data->temp_passive = data->temp_max - (1000 * 10); 441 + } 442 + 443 + static int imx_init_from_tempmon_data(struct platform_device *pdev) 444 + { 445 + struct regmap *map; 446 + int ret; 447 + u32 val; 448 + 449 + map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 450 + "fsl,tempmon-data"); 451 + if (IS_ERR(map)) { 452 + ret = PTR_ERR(map); 453 + dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret); 454 + return ret; 455 + } 456 + 457 + ret = regmap_read(map, OCOTP_ANA1, &val); 458 + if (ret) { 459 + dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret); 460 + return ret; 461 + } 462 + ret = imx_init_calib(pdev, val); 463 + if (ret) 464 + return ret; 465 + 466 + ret = regmap_read(map, OCOTP_MEM0, &val); 467 + if (ret) { 468 + dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret); 469 + return ret; 470 + } 471 + imx_init_temp_grade(pdev, val); 472 + 473 + return 0; 474 + } 475 + 476 + static int imx_init_from_nvmem_cells(struct platform_device *pdev) 477 + { 478 + int ret; 479 + u32 val; 480 + 481 + ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val); 482 + if (ret) 483 + return ret; 484 + imx_init_calib(pdev, val); 485 + 486 + ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val); 487 + if (ret) 488 + return ret; 489 + imx_init_temp_grade(pdev, val); 425 490 426 491 return 0; 427 492 } ··· 547 514 548 515 platform_set_drvdata(pdev, data); 549 516 550 - ret = imx_get_sensor_data(pdev); 551 - if (ret) { 552 - dev_err(&pdev->dev, "failed to get sensor data\n"); 553 - return ret; 517 + if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { 518 + ret = imx_init_from_nvmem_cells(pdev); 519 + if (ret == -EPROBE_DEFER) 520 + return ret; 521 + if (ret) { 522 + dev_err(&pdev->dev, "failed to init from nvmem: %d\n", 523 + ret); 524 + return ret; 525 + } 526 + } else { 527 + ret = imx_init_from_tempmon_data(pdev); 528 + if (ret) { 529 + dev_err(&pdev->dev, "failed to init from from fsl,tempmon-data\n"); 530 + return ret; 531 + } 554 532 } 555 533 556 534 /* Make sure sensor is in known good state for measurements */
+6
drivers/thermal/int340x_thermal/processor_thermal_device.c
··· 30 30 /* Skylake thermal reporting device */ 31 31 #define PCI_DEVICE_ID_PROC_SKL_THERMAL 0x1903 32 32 33 + /* CannonLake thermal reporting device */ 34 + #define PCI_DEVICE_ID_PROC_CNL_THERMAL 0x5a03 35 + #define PCI_DEVICE_ID_PROC_CFL_THERMAL 0x3E83 36 + 33 37 /* Braswell thermal reporting device */ 34 38 #define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC 35 39 ··· 465 461 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT1_THERMAL)}, 466 462 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTX_THERMAL)}, 467 463 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTP_THERMAL)}, 464 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)}, 465 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)}, 468 466 { 0, }, 469 467 }; 470 468
+1 -2
drivers/thermal/intel_bxt_pmic_thermal.c
··· 166 166 struct pmic_thermal_data *td; 167 167 struct intel_soc_pmic *pmic; 168 168 struct regmap *regmap; 169 - u8 reg_val, mask, irq_stat, trip; 169 + u8 reg_val, mask, irq_stat; 170 170 u16 reg, evt_stat_reg; 171 171 int i, j, ret; 172 172 ··· 201 201 if (regmap_read(regmap, evt_stat_reg, &ret)) 202 202 return IRQ_HANDLED; 203 203 204 - trip = td->maps[i].trip_config[j].trip_num; 205 204 tzd = thermal_zone_get_zone_by_name(td->maps[i].handle); 206 205 if (!IS_ERR(tzd)) 207 206 thermal_zone_device_update(tzd,
+11
drivers/thermal/intel_pch_thermal.c
··· 30 30 #define PCH_THERMAL_DID_WPT 0x9CA4 /* Wildcat Point */ 31 31 #define PCH_THERMAL_DID_SKL 0x9D31 /* Skylake PCH */ 32 32 #define PCH_THERMAL_DID_SKL_H 0xA131 /* Skylake PCH 100 series */ 33 + #define PCH_THERMAL_DID_CNL 0x9Df9 /* CNL PCH */ 34 + #define PCH_THERMAL_DID_CNL_H 0xA379 /* CNL-H PCH */ 33 35 34 36 /* Wildcat Point-LP PCH Thermal registers */ 35 37 #define WPT_TEMP 0x0000 /* Temperature */ ··· 280 278 board_hsw, 281 279 board_wpt, 282 280 board_skl, 281 + board_cnl, 283 282 }; 284 283 285 284 static const struct board_info { ··· 297 294 }, 298 295 [board_skl] = { 299 296 .name = "pch_skylake", 297 + .ops = &pch_dev_ops_wpt, 298 + }, 299 + [board_cnl] = { 300 + .name = "pch_cannonlake", 300 301 .ops = &pch_dev_ops_wpt, 301 302 }, 302 303 }; ··· 405 398 .driver_data = board_skl, }, 406 399 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL_H), 407 400 .driver_data = board_skl, }, 401 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL), 402 + .driver_data = board_cnl, }, 403 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL_H), 404 + .driver_data = board_cnl, }, 408 405 { 0, }, 409 406 }; 410 407 MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id);
+2 -2
drivers/thermal/intel_powerclamp.c
··· 675 675 { 676 676 677 677 if (!x86_match_cpu(intel_powerclamp_ids)) { 678 - pr_err("CPU does not support MWAIT"); 678 + pr_err("CPU does not support MWAIT\n"); 679 679 return -ENODEV; 680 680 } 681 681 682 682 /* The goal for idle time alignment is to achieve package cstate. */ 683 683 if (!has_pkg_state_counter()) { 684 - pr_info("No package C-state available"); 684 + pr_info("No package C-state available\n"); 685 685 return -ENODEV; 686 686 } 687 687
+14 -29
drivers/thermal/qcom-spmi-temp-alarm.c
··· 125 125 if (!temp) 126 126 return -EINVAL; 127 127 128 - if (IS_ERR(chip->adc)) { 128 + if (!chip->adc) { 129 129 ret = qpnp_tm_update_temp_no_adc(chip); 130 130 if (ret < 0) 131 131 return ret; ··· 224 224 return irq; 225 225 226 226 /* ADC based measurements are optional */ 227 - chip->adc = iio_channel_get(&pdev->dev, "thermal"); 228 - if (PTR_ERR(chip->adc) == -EPROBE_DEFER) 229 - return PTR_ERR(chip->adc); 227 + chip->adc = devm_iio_channel_get(&pdev->dev, "thermal"); 228 + if (IS_ERR(chip->adc)) { 229 + ret = PTR_ERR(chip->adc); 230 + chip->adc = NULL; 231 + if (ret == -EPROBE_DEFER) 232 + return ret; 233 + } 230 234 231 235 chip->base = res; 232 236 233 237 ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type); 234 238 if (ret < 0) { 235 239 dev_err(&pdev->dev, "could not read type\n"); 236 - goto fail; 240 + return ret; 237 241 } 238 242 239 243 ret = qpnp_tm_read(chip, QPNP_TM_REG_SUBTYPE, &subtype); 240 244 if (ret < 0) { 241 245 dev_err(&pdev->dev, "could not read subtype\n"); 242 - goto fail; 246 + return ret; 243 247 } 244 248 245 249 if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) { 246 250 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", 247 251 type, subtype); 248 - ret = -ENODEV; 249 - goto fail; 252 + return -ENODEV; 250 253 } 251 254 252 255 ret = qpnp_tm_init(chip); 253 256 if (ret < 0) { 254 257 dev_err(&pdev->dev, "init failed\n"); 255 - goto fail; 258 + return ret; 256 259 } 257 260 258 261 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr, 259 262 IRQF_ONESHOT, node->name, chip); 260 263 if (ret < 0) 261 - goto fail; 264 + return ret; 262 265 263 266 chip->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, chip, 264 267 &qpnp_tm_sensor_ops); 265 268 if (IS_ERR(chip->tz_dev)) { 266 269 dev_err(&pdev->dev, "failed to register sensor\n"); 267 - ret = PTR_ERR(chip->tz_dev); 268 - goto fail; 270 + return PTR_ERR(chip->tz_dev); 269 271 } 270 - 271 - return 0; 272 - 273 - fail: 274 - if (!IS_ERR(chip->adc)) 275 - iio_channel_release(chip->adc); 276 - 277 - return ret; 278 - } 279 - 280 - static int qpnp_tm_remove(struct platform_device *pdev) 281 - { 282 - struct qpnp_tm_chip *chip = dev_get_drvdata(&pdev->dev); 283 - 284 - if (!IS_ERR(chip->adc)) 285 - iio_channel_release(chip->adc); 286 272 287 273 return 0; 288 274 } ··· 285 299 .of_match_table = qpnp_tm_match_table, 286 300 }, 287 301 .probe = qpnp_tm_probe, 288 - .remove = qpnp_tm_remove, 289 302 }; 290 303 module_platform_driver(qpnp_tm_driver); 291 304
+15 -19
drivers/thermal/rcar_gen3_thermal.c
··· 24 24 #include <linux/platform_device.h> 25 25 #include <linux/pm_runtime.h> 26 26 #include <linux/spinlock.h> 27 + #include <linux/sys_soc.h> 27 28 #include <linux/thermal.h> 28 29 29 30 #include "thermal_core.h" ··· 91 90 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; 92 91 unsigned int num_tscs; 93 92 spinlock_t lock; /* Protect interrupts on and off */ 94 - const struct rcar_gen3_thermal_data *data; 95 - }; 96 - 97 - struct rcar_gen3_thermal_data { 98 93 void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc); 99 94 }; 100 95 ··· 275 278 return IRQ_HANDLED; 276 279 } 277 280 278 - static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc) 281 + static const struct soc_device_attribute r8a7795es1[] = { 282 + { .soc_id = "r8a7795", .revision = "ES1.*" }, 283 + { /* sentinel */ } 284 + }; 285 + 286 + static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc) 279 287 { 280 288 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR); 281 289 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0); ··· 305 303 usleep_range(1000, 2000); 306 304 } 307 305 308 - static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc) 306 + static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc) 309 307 { 310 308 u32 reg_val; 311 309 ··· 326 324 usleep_range(1000, 2000); 327 325 } 328 326 329 - static const struct rcar_gen3_thermal_data r8a7795_data = { 330 - .thermal_init = r8a7795_thermal_init, 331 - }; 332 - 333 - static const struct rcar_gen3_thermal_data r8a7796_data = { 334 - .thermal_init = r8a7796_thermal_init, 335 - }; 336 - 337 327 static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { 338 - { .compatible = "renesas,r8a7795-thermal", .data = &r8a7795_data}, 339 - { .compatible = "renesas,r8a7796-thermal", .data = &r8a7796_data}, 328 + { .compatible = "renesas,r8a7795-thermal", }, 329 + { .compatible = "renesas,r8a7796-thermal", }, 340 330 {}, 341 331 }; 342 332 MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); ··· 365 371 if (!priv) 366 372 return -ENOMEM; 367 373 368 - priv->data = of_device_get_match_data(dev); 374 + priv->thermal_init = rcar_gen3_thermal_init; 375 + if (soc_device_match(r8a7795es1)) 376 + priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1; 369 377 370 378 spin_lock_init(&priv->lock); 371 379 ··· 419 423 420 424 priv->tscs[i] = tsc; 421 425 422 - priv->data->thermal_init(tsc); 426 + priv->thermal_init(tsc); 423 427 rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); 424 428 425 429 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, ··· 472 476 for (i = 0; i < priv->num_tscs; i++) { 473 477 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; 474 478 475 - priv->data->thermal_init(tsc); 479 + priv->thermal_init(tsc); 476 480 rcar_gen3_thermal_set_trips(tsc, tsc->low, tsc->high); 477 481 } 478 482
+67
drivers/thermal/rockchip_thermal.c
··· 242 242 int temp; 243 243 }; 244 244 245 + static const struct tsadc_table rv1108_table[] = { 246 + {0, -40000}, 247 + {374, -40000}, 248 + {382, -35000}, 249 + {389, -30000}, 250 + {397, -25000}, 251 + {405, -20000}, 252 + {413, -15000}, 253 + {421, -10000}, 254 + {429, -5000}, 255 + {436, 0}, 256 + {444, 5000}, 257 + {452, 10000}, 258 + {460, 15000}, 259 + {468, 20000}, 260 + {476, 25000}, 261 + {483, 30000}, 262 + {491, 35000}, 263 + {499, 40000}, 264 + {507, 45000}, 265 + {515, 50000}, 266 + {523, 55000}, 267 + {531, 60000}, 268 + {539, 65000}, 269 + {547, 70000}, 270 + {555, 75000}, 271 + {562, 80000}, 272 + {570, 85000}, 273 + {578, 90000}, 274 + {586, 95000}, 275 + {594, 100000}, 276 + {602, 105000}, 277 + {610, 110000}, 278 + {618, 115000}, 279 + {626, 120000}, 280 + {634, 125000}, 281 + {TSADCV2_DATA_MASK, 125000}, 282 + }; 283 + 245 284 static const struct tsadc_table rk3228_code_table[] = { 246 285 {0, -40000}, 247 286 {588, -40000}, ··· 818 779 writel_relaxed(val, regs + TSADCV2_INT_EN); 819 780 } 820 781 782 + static const struct rockchip_tsadc_chip rv1108_tsadc_data = { 783 + .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ 784 + .chn_num = 1, /* one channel for tsadc */ 785 + 786 + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ 787 + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ 788 + .tshut_temp = 95000, 789 + 790 + .initialize = rk_tsadcv2_initialize, 791 + .irq_ack = rk_tsadcv3_irq_ack, 792 + .control = rk_tsadcv3_control, 793 + .get_temp = rk_tsadcv2_get_temp, 794 + .set_alarm_temp = rk_tsadcv2_alarm_temp, 795 + .set_tshut_temp = rk_tsadcv2_tshut_temp, 796 + .set_tshut_mode = rk_tsadcv2_tshut_mode, 797 + 798 + .table = { 799 + .id = rv1108_table, 800 + .length = ARRAY_SIZE(rv1108_table), 801 + .data_mask = TSADCV2_DATA_MASK, 802 + .mode = ADC_INCREMENT, 803 + }, 804 + }; 805 + 821 806 static const struct rockchip_tsadc_chip rk3228_tsadc_data = { 822 807 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ 823 808 .chn_num = 1, /* one channel for tsadc */ ··· 990 927 }; 991 928 992 929 static const struct of_device_id of_rockchip_thermal_match[] = { 930 + { 931 + .compatible = "rockchip,rv1108-tsadc", 932 + .data = (void *)&rv1108_tsadc_data, 933 + }, 993 934 { 994 935 .compatible = "rockchip,rk3228-tsadc", 995 936 .data = (void *)&rk3228_tsadc_data,
+6 -5
drivers/thermal/step_wise.c
··· 31 31 * If the temperature is higher than a trip point, 32 32 * a. if the trend is THERMAL_TREND_RAISING, use higher cooling 33 33 * state for this trip point 34 - * b. if the trend is THERMAL_TREND_DROPPING, use lower cooling 35 - * state for this trip point 34 + * b. if the trend is THERMAL_TREND_DROPPING, do nothing 36 35 * c. if the trend is THERMAL_TREND_RAISE_FULL, use upper limit 37 36 * for this trip point 38 37 * d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit ··· 93 94 if (!throttle) 94 95 next_target = THERMAL_NO_TARGET; 95 96 } else { 96 - next_target = cur_state - 1; 97 - if (next_target > instance->upper) 98 - next_target = instance->upper; 97 + if (!throttle) { 98 + next_target = cur_state - 1; 99 + if (next_target > instance->upper) 100 + next_target = instance->upper; 101 + } 99 102 } 100 103 break; 101 104 case THERMAL_TREND_DROP_FULL:
+1 -1
drivers/thermal/tegra/soctherm.c
··· 483 483 unsigned int throt; 484 484 u32 r, reg_off; 485 485 486 - if (!dev || !sg || !stc || !stc->init) 486 + if (!sg || !stc || !stc->init) 487 487 return -EINVAL; 488 488 489 489 temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
+4 -20
drivers/thermal/thermal-generic-adc.c
··· 126 126 gti->dev = &pdev->dev; 127 127 platform_set_drvdata(pdev, gti); 128 128 129 - gti->channel = iio_channel_get(&pdev->dev, "sensor-channel"); 129 + gti->channel = devm_iio_channel_get(&pdev->dev, "sensor-channel"); 130 130 if (IS_ERR(gti->channel)) { 131 131 ret = PTR_ERR(gti->channel); 132 132 dev_err(&pdev->dev, "IIO channel not found: %d\n", ret); 133 133 return ret; 134 134 } 135 135 136 - gti->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, 0, 137 - gti, &gadc_thermal_ops); 136 + gti->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, gti, 137 + &gadc_thermal_ops); 138 138 if (IS_ERR(gti->tz_dev)) { 139 139 ret = PTR_ERR(gti->tz_dev); 140 140 dev_err(&pdev->dev, "Thermal zone sensor register failed: %d\n", 141 141 ret); 142 - goto sensor_fail; 142 + return ret; 143 143 } 144 - 145 - return 0; 146 - 147 - sensor_fail: 148 - iio_channel_release(gti->channel); 149 - 150 - return ret; 151 - } 152 - 153 - static int gadc_thermal_remove(struct platform_device *pdev) 154 - { 155 - struct gadc_thermal_info *gti = platform_get_drvdata(pdev); 156 - 157 - thermal_zone_of_sensor_unregister(&pdev->dev, gti->tz_dev); 158 - iio_channel_release(gti->channel); 159 144 160 145 return 0; 161 146 } ··· 157 172 .of_match_table = of_adc_thermal_match, 158 173 }, 159 174 .probe = gadc_thermal_probe, 160 - .remove = gadc_thermal_remove, 161 175 }; 162 176 163 177 module_platform_driver(gadc_thermal_driver);
+2 -1
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
··· 278 278 279 279 if (data) { 280 280 cpufreq_cooling_unregister(data->cool_dev); 281 - cpufreq_cpu_put(data->policy); 281 + if (data->policy) 282 + cpufreq_cpu_put(data->policy); 282 283 } 283 284 284 285 return 0;
+1 -1
include/linux/thermal.h
··· 488 488 static inline struct thermal_zone_device *thermal_zone_device_register( 489 489 const char *type, int trips, int mask, void *devdata, 490 490 struct thermal_zone_device_ops *ops, 491 - const struct thermal_zone_params *tzp, 491 + struct thermal_zone_params *tzp, 492 492 int passive_delay, int polling_delay) 493 493 { return ERR_PTR(-ENODEV); } 494 494 static inline void thermal_zone_device_unregister(
+12 -6
tools/thermal/tmon/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 + # We need this for the "cc-option" macro. 3 + include ../../../scripts/Kbuild.include 4 + 2 5 VERSION = 1.0 3 6 4 7 BINDIR=usr/bin 5 8 WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int 6 - CFLAGS+= -O1 ${WARNFLAGS} -fstack-protector 7 - CC=$(CROSS_COMPILE)gcc 9 + CFLAGS+= -O1 ${WARNFLAGS} 10 + # Add "-fstack-protector" only if toolchain supports it. 11 + CFLAGS+= $(call cc-option,-fstack-protector) 12 + CC?= $(CROSS_COMPILE)gcc 13 + PKG_CONFIG?= pkg-config 8 14 9 15 CFLAGS+=-D VERSION=\"$(VERSION)\" 10 16 LDFLAGS+= ··· 25 19 endif 26 20 27 21 TMON_LIBS=-lm -lpthread 28 - TMON_LIBS += $(shell pkg-config --libs $(STATIC) panelw ncursesw 2> /dev/null || \ 29 - pkg-config --libs $(STATIC) panel ncurses 2> /dev/null || \ 22 + TMON_LIBS += $(shell $(PKG_CONFIG) --libs $(STATIC) panelw ncursesw 2> /dev/null || \ 23 + $(PKG_CONFIG) --libs $(STATIC) panel ncurses 2> /dev/null || \ 30 24 echo -lpanel -lncurses) 31 25 32 - CFLAGS += $(shell pkg-config --cflags $(STATIC) panelw ncursesw 2> /dev/null || \ 33 - pkg-config --cflags $(STATIC) panel ncurses 2> /dev/null) 26 + CFLAGS += $(shell $(PKG_CONFIG) --cflags $(STATIC) panelw ncursesw 2> /dev/null || \ 27 + $(PKG_CONFIG) --cflags $(STATIC) panel ncurses 2> /dev/null) 34 28 35 29 OBJS = tmon.o tui.o sysfs.o pid.o 36 30 OBJS +=