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

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal SoC updates from Eduardo Valentin:

- Tegra DT binding documentation for Tegra194

- Armada now supports ap806 and cp110

- RCAR thermal now supports R8A774C0 and R8A77990

- Fixes on thermal_hwmon, IMX, generic-ADC, ST, RCAR, Broadcom,
Uniphier, QCOM, Tegra, PowerClamp, and Armada thermal drivers.

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (22 commits)
thermal: generic-adc: Fix adc to temp interpolation
thermal: rcar_thermal: add R8A77990 support
dt-bindings: thermal: rcar-thermal: add R8A77990 support
thermal: rcar_thermal: add R8A774C0 support
dt-bindings: thermal: rcar-thermal: add R8A774C0 support
dt-bindings: cp110: document the thermal interrupt capabilities
dt-bindings: ap806: document the thermal interrupt capabilities
MAINTAINERS: thermal: add entry for Marvell MVEBU thermal driver
thermal: armada: add overheat interrupt support
thermal: st: fix Makefile typo
thermal: uniphier: Convert to SPDX identifier
thermal/intel_powerclamp: Change to use DEFINE_SHOW_ATTRIBUTE macro
thermal: tegra: soctherm: Change to use DEFINE_SHOW_ATTRIBUTE macro
dt-bindings: thermal: tegra-bpmp: Add Tegra194 support
thermal: imx: save one condition block for normal case of nvmem initialization
thermal: imx: fix for dependency on cpu-freq
thermal: tsens: qcom: do not create duplicate regmap debugfs entries
thermal: armada: Use PTR_ERR_OR_ZERO in armada_thermal_probe_legacy()
dt-bindings: thermal: rcar-gen3-thermal: All variants use 3 interrupts
thermal: broadcom: use devm_thermal_zone_of_sensor_register
...

+383 -93
+7
Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
··· 114 114 The thermal IP can probe the temperature all around the processor. It 115 115 may feature several channels, each of them wired to one sensor. 116 116 117 + It is possible to setup an overheat interrupt by giving at least one 118 + critical point to any subnode of the thermal-zone node. 119 + 117 120 Required properties: 118 121 - compatible: must be one of: 119 122 * marvell,armada-ap806-thermal 120 123 - reg: register range associated with the thermal functions. 121 124 122 125 Optional properties: 126 + - interrupts: overheat interrupt handle. Should point to line 18 of the 127 + SEI irqchip. See interrupt-controller/interrupts.txt 123 128 - #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer 124 129 to this IP and represents the channel ID. There is one sensor per 125 130 channel. O refers to the thermal IP internal channel, while positive ··· 138 133 ap_thermal: thermal-sensor@80 { 139 134 compatible = "marvell,armada-ap806-thermal"; 140 135 reg = <0x80 0x10>; 136 + interrupt-parent = <&sei>; 137 + interrupts = <18>; 141 138 #thermal-sensor-cells = <1>; 142 139 }; 143 140 };
+9
Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
··· 199 199 The thermal IP can probe the temperature all around the processor. It 200 200 may feature several channels, each of them wired to one sensor. 201 201 202 + It is possible to setup an overheat interrupt by giving at least one 203 + critical point to any subnode of the thermal-zone node. 204 + 202 205 For common binding part and usage, refer to 203 206 Documentation/devicetree/bindings/thermal/thermal.txt 204 207 ··· 211 208 - reg: register range associated with the thermal functions. 212 209 213 210 Optional properties: 211 + - interrupts-extended: overheat interrupt handle. Should point to 212 + a line of the ICU-SEI irqchip (116 is what is usually used by the 213 + firmware). The ICU-SEI will redirect towards interrupt line #37 of the 214 + AP SEI which is shared across all CPs. 215 + See interrupt-controller/interrupts.txt 214 216 - #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer 215 217 to this IP and represents the channel ID. There is one sensor per 216 218 channel. O refers to the thermal IP internal channel. ··· 228 220 CP110_LABEL(thermal): thermal-sensor@70 { 229 221 compatible = "marvell,armada-cp110-thermal"; 230 222 reg = <0x70 0x10>; 223 + interrupts-extended = <&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>; 231 224 #thermal-sensor-cells = <1>; 232 225 }; 233 226 };
+1 -2
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
··· 21 21 22 22 Optional properties: 23 23 24 - - interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N, 25 - and V3H) 24 + - interrupts : interrupts routed to the TSC (must be 3). 26 25 - power-domain : Must contain a reference to the power domain. This 27 26 property is mandatory if the thermal sensor instance 28 27 is part of a controllable power domain.
+4 -2
Documentation/devicetree/bindings/thermal/rcar-thermal.txt
··· 4 4 - compatible : "renesas,thermal-<soctype>", 5 5 "renesas,rcar-gen2-thermal" (with thermal-zone) or 6 6 "renesas,rcar-thermal" (without thermal-zone) as 7 - fallback except R-Car V3M/D3. 7 + fallback except R-Car V3M/E3/D3 and RZ/G2E. 8 8 Examples with soctypes are: 9 9 - "renesas,thermal-r8a73a4" (R-Mobile APE6) 10 10 - "renesas,thermal-r8a7743" (RZ/G1M) 11 11 - "renesas,thermal-r8a7744" (RZ/G1N) 12 + - "renesas,thermal-r8a774c0" (RZ/G2E) 12 13 - "renesas,thermal-r8a7779" (R-Car H1) 13 14 - "renesas,thermal-r8a7790" (R-Car H2) 14 15 - "renesas,thermal-r8a7791" (R-Car M2-W) 15 16 - "renesas,thermal-r8a7792" (R-Car V2H) 16 17 - "renesas,thermal-r8a7793" (R-Car M2-N) 17 18 - "renesas,thermal-r8a77970" (R-Car V3M) 19 + - "renesas,thermal-r8a77990" (R-Car E3) 18 20 - "renesas,thermal-r8a77995" (R-Car D3) 19 21 - reg : Address range of the thermal registers. 20 22 The 1st reg will be recognized as common register ··· 25 23 Option properties: 26 24 27 25 - interrupts : If present should contain 3 interrupts for 28 - R-Car V3M/D3 or 1 interrupt otherwise. 26 + R-Car V3M/E3/D3 and RZ/G2E or 1 interrupt otherwise. 29 27 30 28 Example (non interrupt support): 31 29
+5
MAINTAINERS
··· 9109 9109 S: Maintained 9110 9110 F: drivers/net/phy/marvell10g.c 9111 9111 9112 + MARVELL MVEBU THERMAL DRIVER 9113 + M: Miquel Raynal <miquel.raynal@bootlin.com> 9114 + S: Maintained 9115 + F: drivers/thermal/armada_thermal.c 9116 + 9112 9117 MARVELL MVNETA ETHERNET DRIVER 9113 9118 M: Thomas Petazzoni <thomas.petazzoni@bootlin.com> 9114 9119 L: netdev@vger.kernel.org
+1 -1
drivers/thermal/Kconfig
··· 212 212 213 213 config IMX_THERMAL 214 214 tristate "Temperature sensor driver for Freescale i.MX SoCs" 215 - depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST 215 + depends on ARCH_MXC || COMPILE_TEST 216 216 depends on NVMEM || !NVMEM 217 217 depends on MFD_SYSCON 218 218 depends on OF
+271 -9
drivers/thermal/armada_thermal.c
··· 26 26 #include <linux/iopoll.h> 27 27 #include <linux/mfd/syscon.h> 28 28 #include <linux/regmap.h> 29 + #include <linux/interrupt.h> 30 + 31 + #include "thermal_core.h" 32 + 33 + #define TO_MCELSIUS(c) ((c) * 1000) 29 34 30 35 /* Thermal Manager Control and Status Register */ 31 36 #define PMU_TDC0_SW_RST_MASK (0x1 << 1) ··· 66 61 #define CONTROL1_TSEN_AVG_MASK 0x7 67 62 #define CONTROL1_EXT_TSEN_SW_RESET BIT(7) 68 63 #define CONTROL1_EXT_TSEN_HW_RESETn BIT(8) 64 + #define CONTROL1_TSEN_INT_EN BIT(25) 65 + #define CONTROL1_TSEN_SELECT_OFF 21 66 + #define CONTROL1_TSEN_SELECT_MASK 0x3 69 67 70 68 #define STATUS_POLL_PERIOD_US 1000 71 69 #define STATUS_POLL_TIMEOUT_US 100000 70 + #define OVERHEAT_INT_POLL_DELAY_MS 1000 72 71 73 72 struct armada_thermal_data; 74 73 ··· 84 75 /* serialize temperature reads/updates */ 85 76 struct mutex update_lock; 86 77 struct armada_thermal_data *data; 78 + struct thermal_zone_device *overheat_sensor; 79 + int interrupt_source; 87 80 int current_channel; 81 + long current_threshold; 82 + long current_hysteresis; 88 83 }; 89 84 90 85 struct armada_thermal_data { ··· 106 93 /* Register shift and mask to access the sensor temperature */ 107 94 unsigned int temp_shift; 108 95 unsigned int temp_mask; 96 + unsigned int thresh_shift; 97 + unsigned int hyst_shift; 98 + unsigned int hyst_mask; 109 99 u32 is_valid_bit; 110 100 111 101 /* Syscon access */ 112 102 unsigned int syscon_control0_off; 113 103 unsigned int syscon_control1_off; 114 104 unsigned int syscon_status_off; 105 + unsigned int dfx_irq_cause_off; 106 + unsigned int dfx_irq_mask_off; 107 + unsigned int dfx_overheat_irq; 108 + unsigned int dfx_server_irq_mask_off; 109 + unsigned int dfx_server_irq_en; 115 110 116 111 /* One sensor is in the thermal IC, the others are in the CPUs if any */ 117 112 unsigned int cpu_nr; ··· 293 272 return reg & priv->data->is_valid_bit; 294 273 } 295 274 275 + static void armada_enable_overheat_interrupt(struct armada_thermal_priv *priv) 276 + { 277 + struct armada_thermal_data *data = priv->data; 278 + u32 reg; 279 + 280 + /* Clear DFX temperature IRQ cause */ 281 + regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg); 282 + 283 + /* Enable DFX Temperature IRQ */ 284 + regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg); 285 + reg |= data->dfx_overheat_irq; 286 + regmap_write(priv->syscon, data->dfx_irq_mask_off, reg); 287 + 288 + /* Enable DFX server IRQ */ 289 + regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg); 290 + reg |= data->dfx_server_irq_en; 291 + regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg); 292 + 293 + /* Enable overheat interrupt */ 294 + regmap_read(priv->syscon, data->syscon_control1_off, &reg); 295 + reg |= CONTROL1_TSEN_INT_EN; 296 + regmap_write(priv->syscon, data->syscon_control1_off, reg); 297 + } 298 + 299 + static void __maybe_unused 300 + armada_disable_overheat_interrupt(struct armada_thermal_priv *priv) 301 + { 302 + struct armada_thermal_data *data = priv->data; 303 + u32 reg; 304 + 305 + regmap_read(priv->syscon, data->syscon_control1_off, &reg); 306 + reg &= ~CONTROL1_TSEN_INT_EN; 307 + regmap_write(priv->syscon, data->syscon_control1_off, reg); 308 + } 309 + 296 310 /* There is currently no board with more than one sensor per channel */ 297 311 static int armada_select_channel(struct armada_thermal_priv *priv, int channel) 298 312 { ··· 444 388 445 389 /* Do the actual reading */ 446 390 ret = armada_read_sensor(priv, temp); 391 + if (ret) 392 + goto unlock_mutex; 393 + 394 + /* 395 + * Select back the interrupt source channel from which a potential 396 + * critical trip point has been set. 397 + */ 398 + ret = armada_select_channel(priv, priv->interrupt_source); 447 399 448 400 unlock_mutex: 449 401 mutex_unlock(&priv->update_lock); ··· 462 398 static const struct thermal_zone_of_device_ops of_ops = { 463 399 .get_temp = armada_get_temp, 464 400 }; 401 + 402 + static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data, 403 + unsigned int temp_mc) 404 + { 405 + s64 b = data->coef_b; 406 + s64 m = data->coef_m; 407 + s64 div = data->coef_div; 408 + unsigned int sample; 409 + 410 + if (data->inverted) 411 + sample = div_s64(((temp_mc * div) + b), m); 412 + else 413 + sample = div_s64((b - (temp_mc * div)), m); 414 + 415 + return sample & data->temp_mask; 416 + } 417 + 418 + /* 419 + * The documentation states: 420 + * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2) 421 + * which is the mathematical derivation for: 422 + * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2°C 423 + */ 424 + static unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200}; 425 + 426 + static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data, 427 + unsigned int hyst_mc) 428 + { 429 + int i; 430 + 431 + /* 432 + * We will always take the smallest possible hysteresis to avoid risking 433 + * the hardware integrity by enlarging the threshold by +8°C in the 434 + * worst case. 435 + */ 436 + for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--) 437 + if (hyst_mc >= hyst_levels_mc[i]) 438 + break; 439 + 440 + return i & data->hyst_mask; 441 + } 442 + 443 + static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv, 444 + int thresh_mc, int hyst_mc) 445 + { 446 + struct armada_thermal_data *data = priv->data; 447 + unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc); 448 + unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc); 449 + u32 ctrl1; 450 + 451 + regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1); 452 + 453 + /* Set Threshold */ 454 + if (thresh_mc >= 0) { 455 + ctrl1 &= ~(data->temp_mask << data->thresh_shift); 456 + ctrl1 |= threshold << data->thresh_shift; 457 + priv->current_threshold = thresh_mc; 458 + } 459 + 460 + /* Set Hysteresis */ 461 + if (hyst_mc >= 0) { 462 + ctrl1 &= ~(data->hyst_mask << data->hyst_shift); 463 + ctrl1 |= hysteresis << data->hyst_shift; 464 + priv->current_hysteresis = hyst_mc; 465 + } 466 + 467 + regmap_write(priv->syscon, data->syscon_control1_off, ctrl1); 468 + } 469 + 470 + static irqreturn_t armada_overheat_isr(int irq, void *blob) 471 + { 472 + /* 473 + * Disable the IRQ and continue in thread context (thermal core 474 + * notification and temperature monitoring). 475 + */ 476 + disable_irq_nosync(irq); 477 + 478 + return IRQ_WAKE_THREAD; 479 + } 480 + 481 + static irqreturn_t armada_overheat_isr_thread(int irq, void *blob) 482 + { 483 + struct armada_thermal_priv *priv = blob; 484 + int low_threshold = priv->current_threshold - priv->current_hysteresis; 485 + int temperature; 486 + u32 dummy; 487 + int ret; 488 + 489 + /* Notify the core in thread context */ 490 + thermal_zone_device_update(priv->overheat_sensor, 491 + THERMAL_EVENT_UNSPECIFIED); 492 + 493 + /* 494 + * The overheat interrupt must be cleared by reading the DFX interrupt 495 + * cause _after_ the temperature has fallen down to the low threshold. 496 + * Otherwise future interrupts might not be served. 497 + */ 498 + do { 499 + msleep(OVERHEAT_INT_POLL_DELAY_MS); 500 + mutex_lock(&priv->update_lock); 501 + ret = armada_read_sensor(priv, &temperature); 502 + mutex_unlock(&priv->update_lock); 503 + if (ret) 504 + goto enable_irq; 505 + } while (temperature >= low_threshold); 506 + 507 + regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy); 508 + 509 + /* Notify the thermal core that the temperature is acceptable again */ 510 + thermal_zone_device_update(priv->overheat_sensor, 511 + THERMAL_EVENT_UNSPECIFIED); 512 + 513 + enable_irq: 514 + enable_irq(irq); 515 + 516 + return IRQ_HANDLED; 517 + } 465 518 466 519 static const struct armada_thermal_data armadaxp_data = { 467 520 .init = armadaxp_init, ··· 635 454 .is_valid_bit = BIT(16), 636 455 .temp_shift = 0, 637 456 .temp_mask = 0x3ff, 457 + .thresh_shift = 3, 458 + .hyst_shift = 19, 459 + .hyst_mask = 0x3, 638 460 .coef_b = -150000LL, 639 461 .coef_m = 423ULL, 640 462 .coef_div = 1, ··· 646 462 .syscon_control0_off = 0x84, 647 463 .syscon_control1_off = 0x88, 648 464 .syscon_status_off = 0x8C, 465 + .dfx_irq_cause_off = 0x108, 466 + .dfx_irq_mask_off = 0x10C, 467 + .dfx_overheat_irq = BIT(22), 468 + .dfx_server_irq_mask_off = 0x104, 469 + .dfx_server_irq_en = BIT(1), 649 470 .cpu_nr = 4, 650 471 }; 651 472 ··· 659 470 .is_valid_bit = BIT(10), 660 471 .temp_shift = 0, 661 472 .temp_mask = 0x3ff, 473 + .thresh_shift = 16, 474 + .hyst_shift = 26, 475 + .hyst_mask = 0x3, 662 476 .coef_b = 1172499100ULL, 663 477 .coef_m = 2000096ULL, 664 478 .coef_div = 4201, ··· 669 477 .syscon_control0_off = 0x70, 670 478 .syscon_control1_off = 0x74, 671 479 .syscon_status_off = 0x78, 480 + .dfx_irq_cause_off = 0x108, 481 + .dfx_irq_mask_off = 0x10C, 482 + .dfx_overheat_irq = BIT(20), 483 + .dfx_server_irq_mask_off = 0x104, 484 + .dfx_server_irq_en = BIT(1), 672 485 }; 673 486 674 487 static const struct of_device_id armada_thermal_id_table[] = { ··· 740 543 741 544 priv->syscon = devm_regmap_init_mmio(&pdev->dev, base, 742 545 &armada_thermal_regmap_config); 743 - if (IS_ERR(priv->syscon)) 744 - return PTR_ERR(priv->syscon); 745 - 746 - return 0; 546 + return PTR_ERR_OR_ZERO(priv->syscon); 747 547 } 748 548 749 549 static int armada_thermal_probe_syscon(struct platform_device *pdev, 750 550 struct armada_thermal_priv *priv) 751 551 { 752 552 priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node); 753 - if (IS_ERR(priv->syscon)) 754 - return PTR_ERR(priv->syscon); 755 - 756 - return 0; 553 + return PTR_ERR_OR_ZERO(priv->syscon); 757 554 } 758 555 759 556 static void armada_set_sane_name(struct platform_device *pdev, ··· 781 590 } while (insane_char); 782 591 } 783 592 593 + /* 594 + * The IP can manage to trigger interrupts on overheat situation from all the 595 + * sensors. However, the interrupt source changes along with the last selected 596 + * source (ie. the last read sensor), which is an inconsistent behavior. Avoid 597 + * possible glitches by always selecting back only one channel (arbitrarily: the 598 + * first in the DT which has a critical trip point). We also disable sensor 599 + * switch during overheat situations. 600 + */ 601 + static int armada_configure_overheat_int(struct armada_thermal_priv *priv, 602 + struct thermal_zone_device *tz, 603 + int sensor_id) 604 + { 605 + /* Retrieve the critical trip point to enable the overheat interrupt */ 606 + const struct thermal_trip *trips = of_thermal_get_trip_points(tz); 607 + int ret; 608 + int i; 609 + 610 + if (!trips) 611 + return -EINVAL; 612 + 613 + for (i = 0; i < of_thermal_get_ntrips(tz); i++) 614 + if (trips[i].type == THERMAL_TRIP_CRITICAL) 615 + break; 616 + 617 + if (i == of_thermal_get_ntrips(tz)) 618 + return -EINVAL; 619 + 620 + ret = armada_select_channel(priv, sensor_id); 621 + if (ret) 622 + return ret; 623 + 624 + armada_set_overheat_thresholds(priv, 625 + trips[i].temperature, 626 + trips[i].hysteresis); 627 + priv->overheat_sensor = tz; 628 + priv->interrupt_source = sensor_id; 629 + 630 + armada_enable_overheat_interrupt(priv); 631 + 632 + return 0; 633 + } 634 + 784 635 static int armada_thermal_probe(struct platform_device *pdev) 785 636 { 786 637 struct thermal_zone_device *tz; ··· 830 597 struct armada_drvdata *drvdata; 831 598 const struct of_device_id *match; 832 599 struct armada_thermal_priv *priv; 833 - int sensor_id; 600 + int sensor_id, irq; 834 601 int ret; 835 602 836 603 match = of_match_device(armada_thermal_id_table, &pdev->dev); ··· 900 667 drvdata->data.priv = priv; 901 668 platform_set_drvdata(pdev, drvdata); 902 669 670 + irq = platform_get_irq(pdev, 0); 671 + if (irq == -EPROBE_DEFER) 672 + return irq; 673 + 674 + /* The overheat interrupt feature is not mandatory */ 675 + if (irq > 0) { 676 + ret = devm_request_threaded_irq(&pdev->dev, irq, 677 + armada_overheat_isr, 678 + armada_overheat_isr_thread, 679 + 0, NULL, priv); 680 + if (ret) { 681 + dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n", 682 + irq); 683 + return ret; 684 + } 685 + } 686 + 903 687 /* 904 688 * There is one channel for the IC and one per CPU (if any), each 905 689 * channel has one sensor. ··· 940 690 devm_kfree(&pdev->dev, sensor); 941 691 continue; 942 692 } 693 + 694 + /* 695 + * The first channel that has a critical trip point registered 696 + * in the DT will serve as interrupt source. Others possible 697 + * critical trip points will simply be ignored by the driver. 698 + */ 699 + if (irq > 0 && !priv->overheat_sensor) 700 + armada_configure_overheat_int(priv, tz, sensor->id); 943 701 } 702 + 703 + /* Just complain if no overheat interrupt was set up */ 704 + if (!priv->overheat_sensor) 705 + dev_warn(&pdev->dev, "Overheat interrupt not available\n"); 944 706 945 707 return 0; 946 708 }
+11
drivers/thermal/broadcom/bcm2835_thermal.c
··· 18 18 #include <linux/platform_device.h> 19 19 #include <linux/thermal.h> 20 20 21 + #include "../thermal_hwmon.h" 22 + 21 23 #define BCM2835_TS_TSENSCTL 0x00 22 24 #define BCM2835_TS_TSENSSTAT 0x04 23 25 ··· 267 265 data->tz = tz; 268 266 269 267 platform_set_drvdata(pdev, tz); 268 + 269 + /* 270 + * Thermal_zone doesn't enable hwmon as default, 271 + * enable it here 272 + */ 273 + tz->tzp->no_hwmon = false; 274 + err = thermal_add_hwmon_sysfs(tz); 275 + if (err) 276 + goto err_tz; 270 277 271 278 bcm2835_thermal_debugfs(pdev); 272 279
+4 -20
drivers/thermal/broadcom/brcmstb_thermal.c
··· 329 329 priv->dev = &pdev->dev; 330 330 platform_set_drvdata(pdev, priv); 331 331 332 - thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops); 332 + thermal = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, 333 + &of_ops); 333 334 if (IS_ERR(thermal)) { 334 335 ret = PTR_ERR(thermal); 335 336 dev_err(&pdev->dev, "could not register sensor: %d\n", ret); ··· 342 341 irq = platform_get_irq(pdev, 0); 343 342 if (irq < 0) { 344 343 dev_err(&pdev->dev, "could not get IRQ\n"); 345 - ret = irq; 346 - goto err; 344 + return irq; 347 345 } 348 346 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 349 347 brcmstb_tmon_irq_thread, IRQF_ONESHOT, 350 348 DRV_NAME, priv); 351 349 if (ret < 0) { 352 350 dev_err(&pdev->dev, "could not request IRQ: %d\n", ret); 353 - goto err; 351 + return ret; 354 352 } 355 353 356 354 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n"); 357 - 358 - return 0; 359 - 360 - err: 361 - thermal_zone_of_sensor_unregister(&pdev->dev, thermal); 362 - return ret; 363 - } 364 - 365 - static int brcmstb_thermal_exit(struct platform_device *pdev) 366 - { 367 - struct brcmstb_thermal_priv *priv = platform_get_drvdata(pdev); 368 - struct thermal_zone_device *thermal = priv->thermal; 369 - 370 - if (thermal) 371 - thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal); 372 355 373 356 return 0; 374 357 } 375 358 376 359 static struct platform_driver brcmstb_thermal_driver = { 377 360 .probe = brcmstb_thermal_probe, 378 - .remove = brcmstb_thermal_exit, 379 361 .driver = { 380 362 .name = DRV_NAME, 381 363 .of_match_table = brcmstb_thermal_id_table,
+38 -14
drivers/thermal/imx_thermal.c
··· 648 648 }; 649 649 MODULE_DEVICE_TABLE(of, of_imx_thermal_match); 650 650 651 + #ifdef CONFIG_CPU_FREQ 651 652 /* 652 653 * Create cooling device in case no #cooling-cells property is available in 653 654 * CPU node 654 655 */ 655 656 static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) 656 657 { 657 - struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL); 658 + struct device_node *np; 658 659 int ret; 660 + 661 + data->policy = cpufreq_cpu_get(0); 662 + if (!data->policy) { 663 + pr_debug("%s: CPUFreq policy not found\n", __func__); 664 + return -EPROBE_DEFER; 665 + } 666 + 667 + np = of_get_cpu_node(data->policy->cpu, NULL); 659 668 660 669 if (!np || !of_find_property(np, "#cooling-cells", NULL)) { 661 670 data->cdev = cpufreq_cooling_register(data->policy); ··· 677 668 678 669 return 0; 679 670 } 671 + 672 + static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) 673 + { 674 + cpufreq_cooling_unregister(data->cdev); 675 + cpufreq_cpu_put(data->policy); 676 + } 677 + 678 + #else 679 + 680 + static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) 681 + { 682 + return 0; 683 + } 684 + 685 + static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) 686 + { 687 + } 688 + #endif 680 689 681 690 static int imx_thermal_probe(struct platform_device *pdev) 682 691 { ··· 742 715 743 716 if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { 744 717 ret = imx_init_from_nvmem_cells(pdev); 745 - if (ret == -EPROBE_DEFER) 746 - return ret; 747 718 if (ret) { 719 + if (ret == -EPROBE_DEFER) 720 + return ret; 721 + 748 722 dev_err(&pdev->dev, "failed to init from nvmem: %d\n", 749 723 ret); 750 724 return ret; ··· 771 743 regmap_write(map, data->socdata->sensor_ctrl + REG_SET, 772 744 data->socdata->power_down_mask); 773 745 774 - data->policy = cpufreq_cpu_get(0); 775 - if (!data->policy) { 776 - pr_debug("%s: CPUFreq policy not found\n", __func__); 777 - return -EPROBE_DEFER; 778 - } 779 - 780 746 ret = imx_thermal_register_legacy_cooling(data); 781 747 if (ret) { 748 + if (ret == -EPROBE_DEFER) 749 + return ret; 750 + 782 751 dev_err(&pdev->dev, 783 752 "failed to register cpufreq cooling device: %d\n", ret); 784 753 return ret; ··· 787 762 if (ret != -EPROBE_DEFER) 788 763 dev_err(&pdev->dev, 789 764 "failed to get thermal clk: %d\n", ret); 790 - goto cpufreq_put; 765 + goto legacy_cleanup; 791 766 } 792 767 793 768 /* ··· 800 775 ret = clk_prepare_enable(data->thermal_clk); 801 776 if (ret) { 802 777 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 803 - goto cpufreq_put; 778 + goto legacy_cleanup; 804 779 } 805 780 806 781 data->tz = thermal_zone_device_register("imx_thermal_zone", ··· 854 829 thermal_zone_device_unregister(data->tz); 855 830 clk_disable: 856 831 clk_disable_unprepare(data->thermal_clk); 857 - cpufreq_put: 858 - cpufreq_cooling_unregister(data->cdev); 859 - cpufreq_cpu_put(data->policy); 832 + legacy_cleanup: 833 + imx_thermal_unregister_legacy_cooling(data); 860 834 861 835 return ret; 862 836 }
+1 -13
drivers/thermal/intel_powerclamp.c
··· 708 708 return 0; 709 709 } 710 710 711 - static int powerclamp_debug_open(struct inode *inode, 712 - struct file *file) 713 - { 714 - return single_open(file, powerclamp_debug_show, inode->i_private); 715 - } 716 - 717 - static const struct file_operations powerclamp_debug_fops = { 718 - .open = powerclamp_debug_open, 719 - .read = seq_read, 720 - .llseek = seq_lseek, 721 - .release = single_release, 722 - .owner = THIS_MODULE, 723 - }; 711 + DEFINE_SHOW_ATTRIBUTE(powerclamp_debug); 724 712 725 713 static inline void powerclamp_create_debug_files(void) 726 714 {
+10 -2
drivers/thermal/qcom/tsens-common.c
··· 114 114 } 115 115 116 116 static const struct regmap_config tsens_config = { 117 + .name = "tm", 118 + .reg_bits = 32, 119 + .val_bits = 32, 120 + .reg_stride = 4, 121 + }; 122 + 123 + static const struct regmap_config tsens_srot_config = { 124 + .name = "srot", 117 125 .reg_bits = 32, 118 126 .val_bits = 32, 119 127 .reg_stride = 4, ··· 147 139 if (IS_ERR(srot_base)) 148 140 return PTR_ERR(srot_base); 149 141 150 - tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, 151 - srot_base, &tsens_config); 142 + tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base, 143 + &tsens_srot_config); 152 144 if (IS_ERR(tmdev->srot_map)) 153 145 return PTR_ERR(tmdev->srot_map); 154 146
+8
drivers/thermal/rcar_thermal.c
··· 113 113 .data = &rcar_gen2_thermal, 114 114 }, 115 115 { 116 + .compatible = "renesas,thermal-r8a774c0", 117 + .data = &rcar_gen3_thermal, 118 + }, 119 + { 116 120 .compatible = "renesas,thermal-r8a77970", 121 + .data = &rcar_gen3_thermal, 122 + }, 123 + { 124 + .compatible = "renesas,thermal-r8a77990", 117 125 .data = &rcar_gen3_thermal, 118 126 }, 119 127 {
+1 -1
drivers/thermal/st/Makefile
··· 1 1 obj-$(CONFIG_ST_THERMAL) := st_thermal.o 2 2 obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o 3 3 obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o 4 - obj-$(CONFIG_STM32_THERMAL) := stm_thermal.o 4 + obj-$(CONFIG_STM32_THERMAL) += stm_thermal.o
+1 -11
drivers/thermal/tegra/soctherm.c
··· 803 803 return 0; 804 804 } 805 805 806 - static int regs_open(struct inode *inode, struct file *file) 807 - { 808 - return single_open(file, regs_show, inode->i_private); 809 - } 810 - 811 - static const struct file_operations regs_fops = { 812 - .open = regs_open, 813 - .read = seq_read, 814 - .llseek = seq_lseek, 815 - .release = single_release, 816 - }; 806 + DEFINE_SHOW_ATTRIBUTE(regs); 817 807 818 808 static void soctherm_debug_init(struct platform_device *pdev) 819 809 {
+8 -4
drivers/thermal/thermal-generic-adc.c
··· 26 26 27 27 static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) 28 28 { 29 - int temp, adc_hi, adc_lo; 29 + int temp, temp_hi, temp_lo, adc_hi, adc_lo; 30 30 int i; 31 31 32 32 for (i = 0; i < gti->nlookup_table; i++) { ··· 36 36 37 37 if (i == 0) { 38 38 temp = gti->lookup_table[0]; 39 - } else if (i >= (gti->nlookup_table - 1)) { 39 + } else if (i >= gti->nlookup_table) { 40 40 temp = gti->lookup_table[2 * (gti->nlookup_table - 1)]; 41 41 } else { 42 42 adc_hi = gti->lookup_table[2 * i - 1]; 43 43 adc_lo = gti->lookup_table[2 * i + 1]; 44 - temp = gti->lookup_table[2 * i]; 45 - temp -= ((val - adc_lo) * 1000) / (adc_hi - adc_lo); 44 + 45 + temp_hi = gti->lookup_table[2 * i - 2]; 46 + temp_lo = gti->lookup_table[2 * i]; 47 + 48 + temp = temp_hi + mult_frac(temp_lo - temp_hi, val - adc_hi, 49 + adc_lo - adc_hi); 46 50 } 47 51 48 52 return temp;
+2 -2
drivers/thermal/thermal_hwmon.h
··· 19 19 int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); 20 20 void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz); 21 21 #else 22 - static int 22 + static inline int 23 23 thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) 24 24 { 25 25 return 0; 26 26 } 27 27 28 - static void 28 + static inline void 29 29 thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) 30 30 { 31 31 }
+1 -12
drivers/thermal/uniphier_thermal.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /** 2 3 * uniphier_thermal.c - Socionext UniPhier thermal driver 3 - * 4 4 * Copyright 2014 Panasonic Corporation 5 5 * Copyright 2016-2017 Socionext Inc. 6 - * All rights reserved. 7 - * 8 6 * Author: 9 7 * Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 10 - * 11 - * This program is free software: you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License version 2 of 13 - * the License as published by the Free Software Foundation. 14 - * 15 - * This program is distributed in the hope that it will be useful, 16 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 - * GNU General Public License for more details. 19 8 */ 20 9 21 10 #include <linux/bitops.h>