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:
"Several new things coming up. Specifics:

- Rework of tsens and hisi thermal drivers

- OF-thermal now allows sharing multiple cooling devices on maps

- Added support for r8a7744 and R8A77970 on rcar thermal driver

- Added support for r8a774a1 on rcar_gen3 thermal driver

- New thermal driver stm32

- Fixes on multiple thermal drivers: of-thermal, imx, qoriq, armada,
qcom-spmi, rcar, da9062/61"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (41 commits)
thermal: da9062/61: Prevent hardware access during system suspend
thermal: rcar_thermal: Prevent doing work after unbind
thermal: rcar_thermal: Prevent hardware access during system suspend
thermal: rcar_gen3_thermal: add R8A77980 support
dt-bindings: thermal: rcar-gen3-thermal: document R8A77980 bindings
thermal: add stm32 thermal driver
dt-bindings: stm32-thermal: add binding documentation
thermal: rcar_thermal: add R8A77970 support
dt-bindings: thermal: rcar-thermal: document R8A77970 bindings
thermal: rcar_thermal: fix duplicate IRQ request
dt-bindings: thermal: rcar: Add device tree support for r8a7744
thermal/drivers/hisi: Add the dual clusters sensors for hi3660
thermal/drivers/hisi: Add more sensors channel
thermal/drivers/hisi: Remove pointless irq field
thermal/drivers/hisi: Use platform_get_irq_byname
thermal/drivers/hisi: Replace macro name with relevant sensor location
thermal/drivers/hisi: Add multiple sensors support
thermal/drivers/hisi: Prepare to support multiple sensors
thermal/drivers/hisi: Factor out the probe functions
thermal/drivers/hisi: Set the thermal zone private data to the sensor pointer
...

+1366 -304
+5 -11
Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt
··· 6 6 7 7 Required properties: 8 8 - compatible: Should contain "qcom,spmi-temp-alarm". 9 - - reg: Specifies the SPMI address and length of the controller's 10 - registers. 9 + - reg: Specifies the SPMI address. 11 10 - interrupts: PMIC temperature alarm interrupt. 12 11 - #thermal-sensor-cells: Should be 0. See thermal.txt for a description. 13 12 ··· 19 20 20 21 pm8941_temp: thermal-alarm@2400 { 21 22 compatible = "qcom,spmi-temp-alarm"; 22 - reg = <0x2400 0x100>; 23 + reg = <0x2400>; 23 24 interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; 24 25 #thermal-sensor-cells = <0>; 25 26 ··· 35 36 thermal-sensors = <&pm8941_temp>; 36 37 37 38 trips { 38 - passive { 39 - temperature = <1050000>; 39 + stage1 { 40 + temperature = <105000>; 40 41 hysteresis = <2000>; 41 42 type = "passive"; 42 43 }; 43 - alert { 44 + stage2 { 44 45 temperature = <125000>; 45 - hysteresis = <2000>; 46 - type = "hot"; 47 - }; 48 - crit { 49 - temperature = <145000>; 50 46 hysteresis = <2000>; 51 47 type = "critical"; 52 48 };
+3 -3
Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
··· 1 1 * Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs 2 2 3 3 Required properties: 4 - - compatible : Must include "fsl,qoriq-tmu". The version of the device is 5 - determined by the TMU IP Block Revision Register (IPBRR0) at 6 - offset 0x0BF8. 4 + - compatible : Must include "fsl,qoriq-tmu" or "fsl,imx8mq-tmu". The 5 + version of the device is determined by the TMU IP Block Revision 6 + Register (IPBRR0) at offset 0x0BF8. 7 7 Table of correspondences between IPBRR0 values and example chips: 8 8 Value Device 9 9 ---------- -----
+4 -1
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
··· 7 7 Required properties: 8 8 - compatible : "renesas,<soctype>-thermal", 9 9 Examples with soctypes are: 10 + - "renesas,r8a774a1-thermal" (RZ/G2M) 10 11 - "renesas,r8a7795-thermal" (R-Car H3) 11 12 - "renesas,r8a7796-thermal" (R-Car M3-W) 12 13 - "renesas,r8a77965-thermal" (R-Car M3-N) 14 + - "renesas,r8a77980-thermal" (R-Car V3H) 13 15 - reg : Address ranges of the thermal registers. Each sensor 14 16 needs one address range. Sorting must be done in 15 17 increasing order according to datasheet, i.e. ··· 21 19 22 20 Optional properties: 23 21 24 - - interrupts : interrupts routed to the TSC (3 for H3, M3-W and M3-N) 22 + - interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N, 23 + and V3H) 25 24 - power-domain : Must contain a reference to the power domain. This 26 25 property is mandatory if the thermal sensor instance 27 26 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 D3. 7 + fallback except R-Car V3M/D3. 8 8 Examples with soctypes are: 9 9 - "renesas,thermal-r8a73a4" (R-Mobile APE6) 10 10 - "renesas,thermal-r8a7743" (RZ/G1M) 11 + - "renesas,thermal-r8a7744" (RZ/G1N) 11 12 - "renesas,thermal-r8a7779" (R-Car H1) 12 13 - "renesas,thermal-r8a7790" (R-Car H2) 13 14 - "renesas,thermal-r8a7791" (R-Car M2-W) 14 15 - "renesas,thermal-r8a7792" (R-Car V2H) 15 16 - "renesas,thermal-r8a7793" (R-Car M2-N) 17 + - "renesas,thermal-r8a77970" (R-Car V3M) 16 18 - "renesas,thermal-r8a77995" (R-Car D3) 17 19 - reg : Address range of the thermal registers. 18 20 The 1st reg will be recognized as common register ··· 23 21 Option properties: 24 22 25 23 - interrupts : If present should contain 3 interrupts for 26 - R-Car D3 or 1 interrupt otherwise. 24 + R-Car V3M/D3 or 1 interrupt otherwise. 27 25 28 26 Example (non interrupt support): 29 27
+61
Documentation/devicetree/bindings/thermal/stm32-thermal.txt
··· 1 + Binding for Thermal Sensor for STMicroelectronics STM32 series of SoCs. 2 + 3 + On STM32 SoCs, the Digital Temperature Sensor (DTS) is in charge of managing an 4 + analog block which delivers a frequency depending on the internal SoC's 5 + temperature. By using a reference frequency, DTS is able to provide a sample 6 + number which can be translated into a temperature by the user. 7 + 8 + DTS provides interrupt notification mechanism by threshold. This mechanism 9 + offers two temperature trip points: passive and critical. The first is intended 10 + for passive cooling notification while the second is used for over-temperature 11 + reset. 12 + 13 + Required parameters: 14 + ------------------- 15 + 16 + compatible: Should be "st,stm32-thermal" 17 + reg: This should be the physical base address and length of the 18 + sensor's registers. 19 + clocks: Phandle of the clock used by the thermal sensor. 20 + See: Documentation/devicetree/bindings/clock/clock-bindings.txt 21 + clock-names: Should be "pclk" for register access clock and reference clock. 22 + See: Documentation/devicetree/bindings/resource-names.txt 23 + #thermal-sensor-cells: Should be 0. See ./thermal.txt for a description. 24 + interrupts: Standard way to define interrupt number. 25 + 26 + Example: 27 + 28 + thermal-zones { 29 + cpu_thermal: cpu-thermal { 30 + polling-delay-passive = <0>; 31 + polling-delay = <0>; 32 + 33 + thermal-sensors = <&thermal>; 34 + 35 + trips { 36 + cpu_alert1: cpu-alert1 { 37 + temperature = <85000>; 38 + hysteresis = <0>; 39 + type = "passive"; 40 + }; 41 + 42 + cpu-crit: cpu-crit { 43 + temperature = <120000>; 44 + hysteresis = <0>; 45 + type = "critical"; 46 + }; 47 + }; 48 + 49 + cooling-maps { 50 + }; 51 + }; 52 + }; 53 + 54 + thermal: thermal@50028000 { 55 + compatible = "st,stm32-thermal"; 56 + reg = <0x50028000 0x100>; 57 + clocks = <&rcc TMPSENS>; 58 + clock-names = "pclk"; 59 + #thermal-sensor-cells = <0>; 60 + interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>; 61 + };
+1 -1
Documentation/devicetree/bindings/thermal/thermal.txt
··· 152 152 Elem size: one cell the sensors listed in the thermal-sensors property. 153 153 Elem type: signed Coefficients defaults to 1, in case this property 154 154 is not specified. A simple linear polynomial is used: 155 - Z = c0 * x0 + c1 + x1 + ... + c(n-1) * x(n-1) + cn. 155 + Z = c0 * x0 + c1 * x1 + ... + c(n-1) * x(n-1) + cn. 156 156 157 157 The coefficients are ordered and they match with sensors 158 158 by means of sensor ID. Additional coefficients are
+1 -1
drivers/thermal/Kconfig
··· 432 432 endmenu 433 433 434 434 menu "STMicroelectronics thermal drivers" 435 - depends on ARCH_STI && OF 435 + depends on (ARCH_STI || ARCH_STM32) && OF 436 436 source "drivers/thermal/st/Kconfig" 437 437 endmenu 438 438
+1 -1
drivers/thermal/Makefile
··· 53 53 obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ 54 54 obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o 55 55 obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o 56 - obj-$(CONFIG_ST_THERMAL) += st/ 56 + obj-y += st/ 57 57 obj-$(CONFIG_QCOM_TSENS) += qcom/ 58 58 obj-y += tegra/ 59 59 obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
+2 -2
drivers/thermal/armada_thermal.c
··· 526 526 527 527 /* First memory region points towards the status register */ 528 528 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 529 - if (IS_ERR(res)) 530 - return PTR_ERR(res); 529 + if (!res) 530 + return -EIO; 531 531 532 532 /* 533 533 * Edit the resource start address and length to map over all the
+2 -2
drivers/thermal/da9062-thermal.c
··· 106 106 THERMAL_EVENT_UNSPECIFIED); 107 107 108 108 delay = msecs_to_jiffies(thermal->zone->passive_delay); 109 - schedule_delayed_work(&thermal->work, delay); 109 + queue_delayed_work(system_freezable_wq, &thermal->work, delay); 110 110 return; 111 111 } 112 112 ··· 125 125 struct da9062_thermal *thermal = data; 126 126 127 127 disable_irq_nosync(thermal->irq); 128 - schedule_delayed_work(&thermal->work, 0); 128 + queue_delayed_work(system_freezable_wq, &thermal->work, 0); 129 129 130 130 return IRQ_HANDLED; 131 131 }
+150 -103
drivers/thermal/hisi_thermal.c
··· 55 55 #define HI3660_TEMP_STEP (205) 56 56 #define HI3660_TEMP_LAG (4000) 57 57 58 - #define HI6220_DEFAULT_SENSOR 2 59 - #define HI3660_DEFAULT_SENSOR 1 58 + #define HI6220_CLUSTER0_SENSOR 2 59 + #define HI6220_CLUSTER1_SENSOR 1 60 + 61 + #define HI3660_LITTLE_SENSOR 0 62 + #define HI3660_BIG_SENSOR 1 63 + #define HI3660_G3D_SENSOR 2 64 + #define HI3660_MODEM_SENSOR 3 65 + 66 + struct hisi_thermal_data; 60 67 61 68 struct hisi_thermal_sensor { 69 + struct hisi_thermal_data *data; 62 70 struct thermal_zone_device *tzd; 71 + const char *irq_name; 63 72 uint32_t id; 64 73 uint32_t thres_temp; 65 74 }; 66 75 76 + struct hisi_thermal_ops { 77 + int (*get_temp)(struct hisi_thermal_sensor *sensor); 78 + int (*enable_sensor)(struct hisi_thermal_sensor *sensor); 79 + int (*disable_sensor)(struct hisi_thermal_sensor *sensor); 80 + int (*irq_handler)(struct hisi_thermal_sensor *sensor); 81 + int (*probe)(struct hisi_thermal_data *data); 82 + }; 83 + 67 84 struct hisi_thermal_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); 85 + const struct hisi_thermal_ops *ops; 86 + struct hisi_thermal_sensor *sensor; 72 87 struct platform_device *pdev; 73 88 struct clk *clk; 74 - struct hisi_thermal_sensor sensor; 75 89 void __iomem *regs; 76 - int irq; 90 + int nr_sensors; 77 91 }; 78 92 79 93 /* ··· 280 266 (value << 4), addr + HI6220_TEMP0_CFG); 281 267 } 282 268 283 - static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data) 269 + static int hi6220_thermal_irq_handler(struct hisi_thermal_sensor *sensor) 284 270 { 271 + struct hisi_thermal_data *data = sensor->data; 272 + 285 273 hi6220_thermal_alarm_clear(data->regs, 1); 286 274 return 0; 287 275 } 288 276 289 - static int hi3660_thermal_irq_handler(struct hisi_thermal_data *data) 277 + static int hi3660_thermal_irq_handler(struct hisi_thermal_sensor *sensor) 290 278 { 291 - hi3660_thermal_alarm_clear(data->regs, data->sensor.id, 1); 279 + struct hisi_thermal_data *data = sensor->data; 280 + 281 + hi3660_thermal_alarm_clear(data->regs, sensor->id, 1); 292 282 return 0; 293 283 } 294 284 295 - static int hi6220_thermal_get_temp(struct hisi_thermal_data *data) 285 + static int hi6220_thermal_get_temp(struct hisi_thermal_sensor *sensor) 296 286 { 287 + struct hisi_thermal_data *data = sensor->data; 288 + 297 289 return hi6220_thermal_get_temperature(data->regs); 298 290 } 299 291 300 - static int hi3660_thermal_get_temp(struct hisi_thermal_data *data) 292 + static int hi3660_thermal_get_temp(struct hisi_thermal_sensor *sensor) 301 293 { 302 - return hi3660_thermal_get_temperature(data->regs, data->sensor.id); 294 + struct hisi_thermal_data *data = sensor->data; 295 + 296 + return hi3660_thermal_get_temperature(data->regs, sensor->id); 303 297 } 304 298 305 - static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) 299 + static int hi6220_thermal_disable_sensor(struct hisi_thermal_sensor *sensor) 306 300 { 301 + struct hisi_thermal_data *data = sensor->data; 302 + 307 303 /* disable sensor module */ 308 304 hi6220_thermal_enable(data->regs, 0); 309 305 hi6220_thermal_alarm_enable(data->regs, 0); ··· 324 300 return 0; 325 301 } 326 302 327 - static int hi3660_thermal_disable_sensor(struct hisi_thermal_data *data) 303 + static int hi3660_thermal_disable_sensor(struct hisi_thermal_sensor *sensor) 328 304 { 305 + struct hisi_thermal_data *data = sensor->data; 306 + 329 307 /* disable sensor module */ 330 - hi3660_thermal_alarm_enable(data->regs, data->sensor.id, 0); 308 + hi3660_thermal_alarm_enable(data->regs, sensor->id, 0); 331 309 return 0; 332 310 } 333 311 334 - static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) 312 + static int hi6220_thermal_enable_sensor(struct hisi_thermal_sensor *sensor) 335 313 { 336 - struct hisi_thermal_sensor *sensor = &data->sensor; 314 + struct hisi_thermal_data *data = sensor->data; 337 315 int ret; 338 316 339 317 /* enable clock for tsensor */ ··· 371 345 return 0; 372 346 } 373 347 374 - static int hi3660_thermal_enable_sensor(struct hisi_thermal_data *data) 348 + static int hi3660_thermal_enable_sensor(struct hisi_thermal_sensor *sensor) 375 349 { 376 350 unsigned int value; 377 - struct hisi_thermal_sensor *sensor = &data->sensor; 351 + struct hisi_thermal_data *data = sensor->data; 378 352 379 353 /* disable interrupt */ 380 354 hi3660_thermal_alarm_enable(data->regs, sensor->id, 0); ··· 397 371 { 398 372 struct platform_device *pdev = data->pdev; 399 373 struct device *dev = &pdev->dev; 400 - struct resource *res; 401 374 int ret; 402 - 403 - data->get_temp = hi6220_thermal_get_temp; 404 - data->enable_sensor = hi6220_thermal_enable_sensor; 405 - data->disable_sensor = hi6220_thermal_disable_sensor; 406 - data->irq_handler = hi6220_thermal_irq_handler; 407 - 408 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 409 - data->regs = devm_ioremap_resource(dev, res); 410 - if (IS_ERR(data->regs)) { 411 - dev_err(dev, "failed to get io address\n"); 412 - return PTR_ERR(data->regs); 413 - } 414 375 415 376 data->clk = devm_clk_get(dev, "thermal_clk"); 416 377 if (IS_ERR(data->clk)) { ··· 407 394 return ret; 408 395 } 409 396 410 - data->irq = platform_get_irq(pdev, 0); 411 - if (data->irq < 0) 412 - return data->irq; 397 + data->sensor = devm_kzalloc(dev, sizeof(*data->sensor), GFP_KERNEL); 398 + if (!data->sensor) 399 + return -ENOMEM; 413 400 414 - data->sensor.id = HI6220_DEFAULT_SENSOR; 401 + data->sensor[0].id = HI6220_CLUSTER0_SENSOR; 402 + data->sensor[0].irq_name = "tsensor_intr"; 403 + data->sensor[0].data = data; 404 + data->nr_sensors = 1; 415 405 416 406 return 0; 417 407 } ··· 423 407 { 424 408 struct platform_device *pdev = data->pdev; 425 409 struct device *dev = &pdev->dev; 426 - struct resource *res; 427 410 428 - data->get_temp = hi3660_thermal_get_temp; 429 - data->enable_sensor = hi3660_thermal_enable_sensor; 430 - data->disable_sensor = hi3660_thermal_disable_sensor; 431 - data->irq_handler = hi3660_thermal_irq_handler; 411 + data->nr_sensors = 2; 432 412 433 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 434 - data->regs = devm_ioremap_resource(dev, res); 435 - if (IS_ERR(data->regs)) { 436 - dev_err(dev, "failed to get io address\n"); 437 - return PTR_ERR(data->regs); 438 - } 413 + data->sensor = devm_kzalloc(dev, sizeof(*data->sensor) * 414 + data->nr_sensors, GFP_KERNEL); 415 + if (!data->sensor) 416 + return -ENOMEM; 439 417 440 - data->irq = platform_get_irq(pdev, 0); 441 - if (data->irq < 0) 442 - return data->irq; 418 + data->sensor[0].id = HI3660_BIG_SENSOR; 419 + data->sensor[0].irq_name = "tsensor_a73"; 420 + data->sensor[0].data = data; 443 421 444 - data->sensor.id = HI3660_DEFAULT_SENSOR; 422 + data->sensor[1].id = HI3660_LITTLE_SENSOR; 423 + data->sensor[1].irq_name = "tsensor_a53"; 424 + data->sensor[1].data = data; 445 425 446 426 return 0; 447 427 } 448 428 449 429 static int hisi_thermal_get_temp(void *__data, int *temp) 450 430 { 451 - struct hisi_thermal_data *data = __data; 452 - struct hisi_thermal_sensor *sensor = &data->sensor; 431 + struct hisi_thermal_sensor *sensor = __data; 432 + struct hisi_thermal_data *data = sensor->data; 453 433 454 - *temp = data->get_temp(data); 434 + *temp = data->ops->get_temp(sensor); 455 435 456 - dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n", 457 - sensor->id, *temp, sensor->thres_temp); 436 + dev_dbg(&data->pdev->dev, "tzd=%p, id=%d, temp=%d, thres=%d\n", 437 + sensor->tzd, sensor->id, *temp, sensor->thres_temp); 458 438 459 439 return 0; 460 440 } ··· 461 449 462 450 static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) 463 451 { 464 - struct hisi_thermal_data *data = dev; 465 - struct hisi_thermal_sensor *sensor = &data->sensor; 452 + struct hisi_thermal_sensor *sensor = dev; 453 + struct hisi_thermal_data *data = sensor->data; 466 454 int temp = 0; 467 455 468 - data->irq_handler(data); 456 + data->ops->irq_handler(sensor); 469 457 470 - hisi_thermal_get_temp(data, &temp); 458 + hisi_thermal_get_temp(sensor, &temp); 471 459 472 460 if (temp >= sensor->thres_temp) { 473 - dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n", 474 - temp, sensor->thres_temp); 461 + dev_crit(&data->pdev->dev, 462 + "sensor <%d> THERMAL ALARM: %d > %d\n", 463 + sensor->id, temp, sensor->thres_temp); 475 464 476 - thermal_zone_device_update(data->sensor.tzd, 465 + thermal_zone_device_update(sensor->tzd, 477 466 THERMAL_EVENT_UNSPECIFIED); 478 467 479 468 } else { 480 - dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n", 481 - temp, sensor->thres_temp); 469 + dev_crit(&data->pdev->dev, 470 + "sensor <%d> THERMAL ALARM stopped: %d < %d\n", 471 + sensor->id, temp, sensor->thres_temp); 482 472 } 483 473 484 474 return IRQ_HANDLED; 485 475 } 486 476 487 477 static int hisi_thermal_register_sensor(struct platform_device *pdev, 488 - struct hisi_thermal_data *data, 489 478 struct hisi_thermal_sensor *sensor) 490 479 { 491 480 int ret, i; 492 481 const struct thermal_trip *trip; 493 482 494 483 sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 495 - sensor->id, data, 484 + sensor->id, sensor, 496 485 &hisi_of_thermal_ops); 497 486 if (IS_ERR(sensor->tzd)) { 498 487 ret = PTR_ERR(sensor->tzd); ··· 515 502 return 0; 516 503 } 517 504 505 + static const struct hisi_thermal_ops hi6220_ops = { 506 + .get_temp = hi6220_thermal_get_temp, 507 + .enable_sensor = hi6220_thermal_enable_sensor, 508 + .disable_sensor = hi6220_thermal_disable_sensor, 509 + .irq_handler = hi6220_thermal_irq_handler, 510 + .probe = hi6220_thermal_probe, 511 + }; 512 + 513 + static const struct hisi_thermal_ops hi3660_ops = { 514 + .get_temp = hi3660_thermal_get_temp, 515 + .enable_sensor = hi3660_thermal_enable_sensor, 516 + .disable_sensor = hi3660_thermal_disable_sensor, 517 + .irq_handler = hi3660_thermal_irq_handler, 518 + .probe = hi3660_thermal_probe, 519 + }; 520 + 518 521 static const struct of_device_id of_hisi_thermal_match[] = { 519 522 { 520 523 .compatible = "hisilicon,tsensor", 521 - .data = hi6220_thermal_probe 524 + .data = &hi6220_ops, 522 525 }, 523 526 { 524 527 .compatible = "hisilicon,hi3660-tsensor", 525 - .data = hi3660_thermal_probe 528 + .data = &hi3660_ops, 526 529 }, 527 530 { /* end */ } 528 531 }; ··· 556 527 static int hisi_thermal_probe(struct platform_device *pdev) 557 528 { 558 529 struct hisi_thermal_data *data; 559 - int (*platform_probe)(struct hisi_thermal_data *); 560 530 struct device *dev = &pdev->dev; 561 - int ret; 531 + struct resource *res; 532 + int i, ret; 562 533 563 534 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 564 535 if (!data) ··· 566 537 567 538 data->pdev = pdev; 568 539 platform_set_drvdata(pdev, data); 540 + data->ops = of_device_get_match_data(dev); 569 541 570 - platform_probe = of_device_get_match_data(dev); 571 - if (!platform_probe) { 572 - dev_err(dev, "failed to get probe func\n"); 573 - return -EINVAL; 542 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 543 + data->regs = devm_ioremap_resource(dev, res); 544 + if (IS_ERR(data->regs)) { 545 + dev_err(dev, "failed to get io address\n"); 546 + return PTR_ERR(data->regs); 574 547 } 575 548 576 - ret = platform_probe(data); 549 + ret = data->ops->probe(data); 577 550 if (ret) 578 551 return ret; 579 552 580 - ret = hisi_thermal_register_sensor(pdev, data, 581 - &data->sensor); 582 - if (ret) { 583 - dev_err(dev, "failed to register thermal sensor: %d\n", ret); 584 - return ret; 585 - } 553 + for (i = 0; i < data->nr_sensors; i++) { 554 + struct hisi_thermal_sensor *sensor = &data->sensor[i]; 586 555 587 - ret = data->enable_sensor(data); 588 - if (ret) { 589 - dev_err(dev, "Failed to setup the sensor: %d\n", ret); 590 - return ret; 591 - } 592 - 593 - if (data->irq) { 594 - ret = devm_request_threaded_irq(dev, data->irq, NULL, 595 - hisi_thermal_alarm_irq_thread, 596 - IRQF_ONESHOT, "hisi_thermal", data); 597 - if (ret < 0) { 598 - dev_err(dev, "failed to request alarm irq: %d\n", ret); 556 + ret = hisi_thermal_register_sensor(pdev, sensor); 557 + if (ret) { 558 + dev_err(dev, "failed to register thermal sensor: %d\n", 559 + ret); 599 560 return ret; 600 561 } 601 - } 602 562 603 - hisi_thermal_toggle_sensor(&data->sensor, true); 563 + ret = platform_get_irq_byname(pdev, sensor->irq_name); 564 + if (ret < 0) 565 + return ret; 566 + 567 + ret = devm_request_threaded_irq(dev, ret, NULL, 568 + hisi_thermal_alarm_irq_thread, 569 + IRQF_ONESHOT, sensor->irq_name, 570 + sensor); 571 + if (ret < 0) { 572 + dev_err(dev, "Failed to request alarm irq: %d\n", ret); 573 + return ret; 574 + } 575 + 576 + ret = data->ops->enable_sensor(sensor); 577 + if (ret) { 578 + dev_err(dev, "Failed to setup the sensor: %d\n", ret); 579 + return ret; 580 + } 581 + 582 + hisi_thermal_toggle_sensor(sensor, true); 583 + } 604 584 605 585 return 0; 606 586 } ··· 617 579 static int hisi_thermal_remove(struct platform_device *pdev) 618 580 { 619 581 struct hisi_thermal_data *data = platform_get_drvdata(pdev); 620 - struct hisi_thermal_sensor *sensor = &data->sensor; 582 + int i; 621 583 622 - hisi_thermal_toggle_sensor(sensor, false); 584 + for (i = 0; i < data->nr_sensors; i++) { 585 + struct hisi_thermal_sensor *sensor = &data->sensor[i]; 623 586 624 - data->disable_sensor(data); 587 + hisi_thermal_toggle_sensor(sensor, false); 588 + data->ops->disable_sensor(sensor); 589 + } 625 590 626 591 return 0; 627 592 } ··· 633 592 static int hisi_thermal_suspend(struct device *dev) 634 593 { 635 594 struct hisi_thermal_data *data = dev_get_drvdata(dev); 595 + int i; 636 596 637 - data->disable_sensor(data); 597 + for (i = 0; i < data->nr_sensors; i++) 598 + data->ops->disable_sensor(&data->sensor[i]); 638 599 639 600 return 0; 640 601 } ··· 644 601 static int hisi_thermal_resume(struct device *dev) 645 602 { 646 603 struct hisi_thermal_data *data = dev_get_drvdata(dev); 604 + int i, ret = 0; 647 605 648 - return data->enable_sensor(data); 606 + for (i = 0; i < data->nr_sensors; i++) 607 + ret |= data->ops->enable_sensor(&data->sensor[i]); 608 + 609 + return ret; 649 610 } 650 611 #endif 651 612
+15 -16
drivers/thermal/imx_thermal.c
··· 725 725 } else { 726 726 ret = imx_init_from_tempmon_data(pdev); 727 727 if (ret) { 728 - dev_err(&pdev->dev, "failed to init from from fsl,tempmon-data\n"); 728 + dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n"); 729 729 return ret; 730 730 } 731 731 } ··· 762 762 if (ret != -EPROBE_DEFER) 763 763 dev_err(&pdev->dev, 764 764 "failed to get thermal clk: %d\n", ret); 765 - cpufreq_cooling_unregister(data->cdev); 766 - cpufreq_cpu_put(data->policy); 767 - return ret; 765 + goto cpufreq_put; 768 766 } 769 767 770 768 /* ··· 775 777 ret = clk_prepare_enable(data->thermal_clk); 776 778 if (ret) { 777 779 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 778 - cpufreq_cooling_unregister(data->cdev); 779 - cpufreq_cpu_put(data->policy); 780 - return ret; 780 + goto cpufreq_put; 781 781 } 782 782 783 783 data->tz = thermal_zone_device_register("imx_thermal_zone", ··· 788 792 ret = PTR_ERR(data->tz); 789 793 dev_err(&pdev->dev, 790 794 "failed to register thermal zone device %d\n", ret); 791 - clk_disable_unprepare(data->thermal_clk); 792 - cpufreq_cooling_unregister(data->cdev); 793 - cpufreq_cpu_put(data->policy); 794 - return ret; 795 + goto clk_disable; 795 796 } 796 797 797 798 dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" ··· 820 827 0, "imx_thermal", data); 821 828 if (ret < 0) { 822 829 dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); 823 - clk_disable_unprepare(data->thermal_clk); 824 - thermal_zone_device_unregister(data->tz); 825 - cpufreq_cooling_unregister(data->cdev); 826 - cpufreq_cpu_put(data->policy); 827 - return ret; 830 + goto thermal_zone_unregister; 828 831 } 829 832 830 833 return 0; 834 + 835 + thermal_zone_unregister: 836 + thermal_zone_device_unregister(data->tz); 837 + clk_disable: 838 + clk_disable_unprepare(data->thermal_clk); 839 + cpufreq_put: 840 + cpufreq_cooling_unregister(data->cdev); 841 + cpufreq_cpu_put(data->policy); 842 + 843 + return ret; 831 844 } 832 845 833 846 static int imx_thermal_remove(struct platform_device *pdev)
+108 -44
drivers/thermal/of-thermal.c
··· 19 19 /*** Private data structures to represent thermal device tree data ***/ 20 20 21 21 /** 22 - * struct __thermal_bind_param - a match between trip and cooling device 22 + * struct __thermal_cooling_bind_param - a cooling device for a trip point 23 23 * @cooling_device: a pointer to identify the referred cooling device 24 - * @trip_id: the trip point index 25 - * @usage: the percentage (from 0 to 100) of cooling contribution 26 24 * @min: minimum cooling state used at this trip point 27 25 * @max: maximum cooling state used at this trip point 28 26 */ 29 27 30 - struct __thermal_bind_params { 28 + struct __thermal_cooling_bind_param { 31 29 struct device_node *cooling_device; 32 - unsigned int trip_id; 33 - unsigned int usage; 34 30 unsigned long min; 35 31 unsigned long max; 32 + }; 33 + 34 + /** 35 + * struct __thermal_bind_param - a match between trip and cooling device 36 + * @tcbp: a pointer to an array of cooling devices 37 + * @count: number of elements in array 38 + * @trip_id: the trip point index 39 + * @usage: the percentage (from 0 to 100) of cooling contribution 40 + */ 41 + 42 + struct __thermal_bind_params { 43 + struct __thermal_cooling_bind_param *tcbp; 44 + unsigned int count; 45 + unsigned int trip_id; 46 + unsigned int usage; 36 47 }; 37 48 38 49 /** ··· 203 192 struct thermal_cooling_device *cdev) 204 193 { 205 194 struct __thermal_zone *data = thermal->devdata; 206 - int i; 195 + struct __thermal_bind_params *tbp; 196 + struct __thermal_cooling_bind_param *tcbp; 197 + int i, j; 207 198 208 199 if (!data || IS_ERR(data)) 209 200 return -ENODEV; 210 201 211 202 /* find where to bind */ 212 203 for (i = 0; i < data->num_tbps; i++) { 213 - struct __thermal_bind_params *tbp = data->tbps + i; 204 + tbp = data->tbps + i; 214 205 215 - if (tbp->cooling_device == cdev->np) { 216 - int ret; 206 + for (j = 0; j < tbp->count; j++) { 207 + tcbp = tbp->tcbp + j; 217 208 218 - ret = thermal_zone_bind_cooling_device(thermal, 209 + if (tcbp->cooling_device == cdev->np) { 210 + int ret; 211 + 212 + ret = thermal_zone_bind_cooling_device(thermal, 219 213 tbp->trip_id, cdev, 220 - tbp->max, 221 - tbp->min, 214 + tcbp->max, 215 + tcbp->min, 222 216 tbp->usage); 223 - if (ret) 224 - return ret; 217 + if (ret) 218 + return ret; 219 + } 225 220 } 226 221 } 227 222 ··· 238 221 struct thermal_cooling_device *cdev) 239 222 { 240 223 struct __thermal_zone *data = thermal->devdata; 241 - int i; 224 + struct __thermal_bind_params *tbp; 225 + struct __thermal_cooling_bind_param *tcbp; 226 + int i, j; 242 227 243 228 if (!data || IS_ERR(data)) 244 229 return -ENODEV; 245 230 246 231 /* find where to unbind */ 247 232 for (i = 0; i < data->num_tbps; i++) { 248 - struct __thermal_bind_params *tbp = data->tbps + i; 233 + tbp = data->tbps + i; 249 234 250 - if (tbp->cooling_device == cdev->np) { 251 - int ret; 235 + for (j = 0; j < tbp->count; j++) { 236 + tcbp = tbp->tcbp + j; 252 237 253 - ret = thermal_zone_unbind_cooling_device(thermal, 254 - tbp->trip_id, cdev); 255 - if (ret) 256 - return ret; 238 + if (tcbp->cooling_device == cdev->np) { 239 + int ret; 240 + 241 + ret = thermal_zone_unbind_cooling_device(thermal, 242 + tbp->trip_id, cdev); 243 + if (ret) 244 + return ret; 245 + } 257 246 } 258 247 } 259 248 ··· 509 486 if (sensor_specs.args_count >= 1) { 510 487 id = sensor_specs.args[0]; 511 488 WARN(sensor_specs.args_count > 1, 512 - "%s: too many cells in sensor specifier %d\n", 513 - sensor_specs.np->name, sensor_specs.args_count); 489 + "%pOFn: too many cells in sensor specifier %d\n", 490 + sensor_specs.np, sensor_specs.args_count); 514 491 } else { 515 492 id = 0; 516 493 } ··· 678 655 int ntrips) 679 656 { 680 657 struct of_phandle_args cooling_spec; 658 + struct __thermal_cooling_bind_param *__tcbp; 681 659 struct device_node *trip; 682 - int ret, i; 660 + int ret, i, count; 683 661 u32 prop; 684 662 685 663 /* Default weight. Usage is optional */ ··· 707 683 goto end; 708 684 } 709 685 710 - ret = of_parse_phandle_with_args(np, "cooling-device", "#cooling-cells", 711 - 0, &cooling_spec); 712 - if (ret < 0) { 713 - pr_err("missing cooling_device property\n"); 686 + count = of_count_phandle_with_args(np, "cooling-device", 687 + "#cooling-cells"); 688 + if (!count) { 689 + pr_err("Add a cooling_device property with at least one device\n"); 714 690 goto end; 715 691 } 716 - __tbp->cooling_device = cooling_spec.np; 717 - if (cooling_spec.args_count >= 2) { /* at least min and max */ 718 - __tbp->min = cooling_spec.args[0]; 719 - __tbp->max = cooling_spec.args[1]; 720 - } else { 721 - pr_err("wrong reference to cooling device, missing limits\n"); 692 + 693 + __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL); 694 + if (!__tcbp) 695 + goto end; 696 + 697 + for (i = 0; i < count; i++) { 698 + ret = of_parse_phandle_with_args(np, "cooling-device", 699 + "#cooling-cells", i, &cooling_spec); 700 + if (ret < 0) { 701 + pr_err("Invalid cooling-device entry\n"); 702 + goto free_tcbp; 703 + } 704 + 705 + __tcbp[i].cooling_device = cooling_spec.np; 706 + 707 + if (cooling_spec.args_count >= 2) { /* at least min and max */ 708 + __tcbp[i].min = cooling_spec.args[0]; 709 + __tcbp[i].max = cooling_spec.args[1]; 710 + } else { 711 + pr_err("wrong reference to cooling device, missing limits\n"); 712 + } 722 713 } 723 714 715 + __tbp->tcbp = __tcbp; 716 + __tbp->count = count; 717 + 718 + goto end; 719 + 720 + free_tcbp: 721 + for (i = i - 1; i >= 0; i--) 722 + of_node_put(__tcbp[i].cooling_device); 723 + kfree(__tcbp); 724 724 end: 725 725 of_node_put(trip); 726 726 ··· 951 903 return tz; 952 904 953 905 free_tbps: 954 - for (i = i - 1; i >= 0; i--) 955 - of_node_put(tz->tbps[i].cooling_device); 906 + for (i = i - 1; i >= 0; i--) { 907 + struct __thermal_bind_params *tbp = tz->tbps + i; 908 + int j; 909 + 910 + for (j = 0; j < tbp->count; j++) 911 + of_node_put(tbp->tcbp[j].cooling_device); 912 + 913 + kfree(tbp->tcbp); 914 + } 915 + 956 916 kfree(tz->tbps); 957 917 free_trips: 958 918 for (i = 0; i < tz->ntrips; i++) ··· 976 920 977 921 static inline void of_thermal_free_zone(struct __thermal_zone *tz) 978 922 { 979 - int i; 923 + struct __thermal_bind_params *tbp; 924 + int i, j; 980 925 981 - for (i = 0; i < tz->num_tbps; i++) 982 - of_node_put(tz->tbps[i].cooling_device); 926 + for (i = 0; i < tz->num_tbps; i++) { 927 + tbp = tz->tbps + i; 928 + 929 + for (j = 0; j < tbp->count; j++) 930 + of_node_put(tbp->tcbp[j].cooling_device); 931 + 932 + kfree(tbp->tcbp); 933 + } 934 + 983 935 kfree(tz->tbps); 984 936 for (i = 0; i < tz->ntrips; i++) 985 937 of_node_put(tz->trips[i].np); ··· 1027 963 1028 964 tz = thermal_of_build_thermal_zone(child); 1029 965 if (IS_ERR(tz)) { 1030 - pr_err("failed to build thermal zone %s: %ld\n", 1031 - child->name, 966 + pr_err("failed to build thermal zone %pOFn: %ld\n", 967 + child, 1032 968 PTR_ERR(tz)); 1033 969 continue; 1034 970 } ··· 1062 998 tz->passive_delay, 1063 999 tz->polling_delay); 1064 1000 if (IS_ERR(zone)) { 1065 - pr_err("Failed to build %s zone %ld\n", child->name, 1001 + pr_err("Failed to build %pOFn zone %ld\n", child, 1066 1002 PTR_ERR(zone)); 1067 1003 kfree(tzp); 1068 1004 kfree(ops);
+140 -18
drivers/thermal/qcom-spmi-temp-alarm.c
··· 23 23 #include <linux/regmap.h> 24 24 #include <linux/thermal.h> 25 25 26 + #include "thermal_core.h" 27 + 26 28 #define QPNP_TM_REG_TYPE 0x04 27 29 #define QPNP_TM_REG_SUBTYPE 0x05 28 30 #define QPNP_TM_REG_STATUS 0x08 ··· 39 37 #define STATUS_GEN2_STATE_MASK GENMASK(6, 4) 40 38 #define STATUS_GEN2_STATE_SHIFT 4 41 39 42 - #define SHUTDOWN_CTRL1_OVERRIDE_MASK GENMASK(7, 6) 40 + #define SHUTDOWN_CTRL1_OVERRIDE_S2 BIT(6) 43 41 #define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0) 42 + 43 + #define SHUTDOWN_CTRL1_RATE_25HZ BIT(3) 44 44 45 45 #define ALARM_CTRL_FORCE_ENABLE BIT(7) 46 46 ··· 60 56 #define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ 61 57 62 58 #define THRESH_MIN 0 59 + #define THRESH_MAX 3 60 + 61 + /* Stage 2 Threshold Min: 125 C */ 62 + #define STAGE2_THRESHOLD_MIN 125000 63 + /* Stage 2 Threshold Max: 140 C */ 64 + #define STAGE2_THRESHOLD_MAX 140000 63 65 64 66 /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ 65 67 #define DEFAULT_TEMP 37000 66 68 67 69 struct qpnp_tm_chip { 68 70 struct regmap *map; 71 + struct device *dev; 69 72 struct thermal_zone_device *tz_dev; 70 73 unsigned int subtype; 71 74 long temp; ··· 80 69 unsigned int stage; 81 70 unsigned int prev_stage; 82 71 unsigned int base; 72 + /* protects .thresh, .stage and chip registers */ 73 + struct mutex lock; 74 + bool initialized; 75 + 83 76 struct iio_channel *adc; 84 77 }; 85 78 ··· 140 125 unsigned int stage, stage_new, stage_old; 141 126 int ret; 142 127 128 + WARN_ON(!mutex_is_locked(&chip->lock)); 129 + 143 130 ret = qpnp_tm_get_temp_stage(chip); 144 131 if (ret < 0) 145 132 return ret; ··· 180 163 if (!temp) 181 164 return -EINVAL; 182 165 166 + if (!chip->initialized) { 167 + *temp = DEFAULT_TEMP; 168 + return 0; 169 + } 170 + 183 171 if (!chip->adc) { 172 + mutex_lock(&chip->lock); 184 173 ret = qpnp_tm_update_temp_no_adc(chip); 174 + mutex_unlock(&chip->lock); 185 175 if (ret < 0) 186 176 return ret; 187 177 } else { ··· 204 180 return 0; 205 181 } 206 182 183 + static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, 184 + int temp) 185 + { 186 + u8 reg; 187 + bool disable_s2_shutdown = false; 188 + 189 + WARN_ON(!mutex_is_locked(&chip->lock)); 190 + 191 + /* 192 + * Default: S2 and S3 shutdown enabled, thresholds at 193 + * 105C/125C/145C, monitoring at 25Hz 194 + */ 195 + reg = SHUTDOWN_CTRL1_RATE_25HZ; 196 + 197 + if (temp == THERMAL_TEMP_INVALID || 198 + temp < STAGE2_THRESHOLD_MIN) { 199 + chip->thresh = THRESH_MIN; 200 + goto skip; 201 + } 202 + 203 + if (temp <= STAGE2_THRESHOLD_MAX) { 204 + chip->thresh = THRESH_MAX - 205 + ((STAGE2_THRESHOLD_MAX - temp) / 206 + TEMP_THRESH_STEP); 207 + disable_s2_shutdown = true; 208 + } else { 209 + chip->thresh = THRESH_MAX; 210 + 211 + if (chip->adc) 212 + disable_s2_shutdown = true; 213 + else 214 + dev_warn(chip->dev, 215 + "No ADC is configured and critical temperature is above the maximum stage 2 threshold of 140 C! Configuring stage 2 shutdown at 140 C.\n"); 216 + } 217 + 218 + skip: 219 + reg |= chip->thresh; 220 + if (disable_s2_shutdown) 221 + reg |= SHUTDOWN_CTRL1_OVERRIDE_S2; 222 + 223 + return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); 224 + } 225 + 226 + static int qpnp_tm_set_trip_temp(void *data, int trip, int temp) 227 + { 228 + struct qpnp_tm_chip *chip = data; 229 + const struct thermal_trip *trip_points; 230 + int ret; 231 + 232 + trip_points = of_thermal_get_trip_points(chip->tz_dev); 233 + if (!trip_points) 234 + return -EINVAL; 235 + 236 + if (trip_points[trip].type != THERMAL_TRIP_CRITICAL) 237 + return 0; 238 + 239 + mutex_lock(&chip->lock); 240 + ret = qpnp_tm_update_critical_trip_temp(chip, temp); 241 + mutex_unlock(&chip->lock); 242 + 243 + return ret; 244 + } 245 + 207 246 static const struct thermal_zone_of_device_ops qpnp_tm_sensor_ops = { 208 247 .get_temp = qpnp_tm_get_temp, 248 + .set_trip_temp = qpnp_tm_set_trip_temp, 209 249 }; 210 250 211 251 static irqreturn_t qpnp_tm_isr(int irq, void *data) ··· 279 191 thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED); 280 192 281 193 return IRQ_HANDLED; 194 + } 195 + 196 + static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip) 197 + { 198 + int ntrips; 199 + const struct thermal_trip *trips; 200 + int i; 201 + 202 + ntrips = of_thermal_get_ntrips(chip->tz_dev); 203 + if (ntrips <= 0) 204 + return THERMAL_TEMP_INVALID; 205 + 206 + trips = of_thermal_get_trip_points(chip->tz_dev); 207 + if (!trips) 208 + return THERMAL_TEMP_INVALID; 209 + 210 + for (i = 0; i < ntrips; i++) { 211 + if (of_thermal_is_trip_valid(chip->tz_dev, i) && 212 + trips[i].type == THERMAL_TRIP_CRITICAL) 213 + return trips[i].temperature; 214 + } 215 + 216 + return THERMAL_TEMP_INVALID; 282 217 } 283 218 284 219 /* ··· 314 203 unsigned int stage; 315 204 int ret; 316 205 u8 reg = 0; 206 + int crit_temp; 207 + 208 + mutex_lock(&chip->lock); 317 209 318 210 ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, &reg); 319 211 if (ret < 0) 320 - return ret; 212 + goto out; 321 213 322 214 chip->thresh = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK; 323 215 chip->temp = DEFAULT_TEMP; 324 216 325 217 ret = qpnp_tm_get_temp_stage(chip); 326 218 if (ret < 0) 327 - return ret; 219 + goto out; 328 220 chip->stage = ret; 329 221 330 222 stage = chip->subtype == QPNP_TM_SUBTYPE_GEN1 ··· 338 224 (stage - 1) * TEMP_STAGE_STEP + 339 225 TEMP_THRESH_MIN; 340 226 341 - /* 342 - * Set threshold and disable software override of stage 2 and 3 343 - * shutdowns. 344 - */ 345 - chip->thresh = THRESH_MIN; 346 - reg &= ~(SHUTDOWN_CTRL1_OVERRIDE_MASK | SHUTDOWN_CTRL1_THRESHOLD_MASK); 347 - reg |= chip->thresh & SHUTDOWN_CTRL1_THRESHOLD_MASK; 348 - ret = qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); 227 + crit_temp = qpnp_tm_get_critical_trip_temp(chip); 228 + ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); 349 229 if (ret < 0) 350 - return ret; 230 + goto out; 351 231 352 232 /* Enable the thermal alarm PMIC module in always-on mode. */ 353 233 reg = ALARM_CTRL_FORCE_ENABLE; 354 234 ret = qpnp_tm_write(chip, QPNP_TM_REG_ALARM_CTRL, reg); 355 235 236 + chip->initialized = true; 237 + 238 + out: 239 + mutex_unlock(&chip->lock); 356 240 return ret; 357 241 } 358 242 ··· 369 257 return -ENOMEM; 370 258 371 259 dev_set_drvdata(&pdev->dev, chip); 260 + chip->dev = &pdev->dev; 261 + 262 + mutex_init(&chip->lock); 372 263 373 264 chip->map = dev_get_regmap(pdev->dev.parent, NULL); 374 265 if (!chip->map) ··· 417 302 418 303 chip->subtype = subtype; 419 304 305 + /* 306 + * Register the sensor before initializing the hardware to be able to 307 + * read the trip points. get_temp() returns the default temperature 308 + * before the hardware initialization is completed. 309 + */ 310 + chip->tz_dev = devm_thermal_zone_of_sensor_register( 311 + &pdev->dev, 0, chip, &qpnp_tm_sensor_ops); 312 + if (IS_ERR(chip->tz_dev)) { 313 + dev_err(&pdev->dev, "failed to register sensor\n"); 314 + return PTR_ERR(chip->tz_dev); 315 + } 316 + 420 317 ret = qpnp_tm_init(chip); 421 318 if (ret < 0) { 422 319 dev_err(&pdev->dev, "init failed\n"); ··· 440 313 if (ret < 0) 441 314 return ret; 442 315 443 - chip->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, chip, 444 - &qpnp_tm_sensor_ops); 445 - if (IS_ERR(chip->tz_dev)) { 446 - dev_err(&pdev->dev, "failed to register sensor\n"); 447 - return PTR_ERR(chip->tz_dev); 448 - } 316 + thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED); 449 317 450 318 return 0; 451 319 }
+2 -10
drivers/thermal/qcom/tsens-8916.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 and 6 - * only version 2 as published by the Free Software Foundation. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - * 13 4 */ 14 5 15 6 #include <linux/platform_device.h> ··· 100 109 const struct tsens_data data_8916 = { 101 110 .num_sensors = 5, 102 111 .ops = &ops_8916, 112 + .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 }, 103 113 .hw_ids = (unsigned int []){0, 1, 2, 4, 5 }, 104 114 };
+16 -25
drivers/thermal/qcom/tsens-8960.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 and 6 - * only version 2 as published by the Free Software Foundation. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - * 13 4 */ 14 5 15 6 #include <linux/platform_device.h> ··· 60 69 { 61 70 int ret; 62 71 unsigned int mask; 63 - struct regmap *map = tmdev->map; 72 + struct regmap *map = tmdev->tm_map; 64 73 65 74 ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold); 66 75 if (ret) ··· 85 94 static int resume_8960(struct tsens_device *tmdev) 86 95 { 87 96 int ret; 88 - struct regmap *map = tmdev->map; 97 + struct regmap *map = tmdev->tm_map; 89 98 90 99 ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST); 91 100 if (ret) ··· 117 126 int ret; 118 127 u32 reg, mask; 119 128 120 - ret = regmap_read(tmdev->map, CNTL_ADDR, &reg); 129 + ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg); 121 130 if (ret) 122 131 return ret; 123 132 124 133 mask = BIT(id + SENSOR0_SHIFT); 125 - ret = regmap_write(tmdev->map, CNTL_ADDR, reg | SW_RST); 134 + ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg | SW_RST); 126 135 if (ret) 127 136 return ret; 128 137 ··· 131 140 else 132 141 reg |= mask | SLP_CLK_ENA_8660 | EN; 133 142 134 - ret = regmap_write(tmdev->map, CNTL_ADDR, reg); 143 + ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg); 135 144 if (ret) 136 145 return ret; 137 146 ··· 148 157 mask <<= SENSOR0_SHIFT; 149 158 mask |= EN; 150 159 151 - ret = regmap_read(tmdev->map, CNTL_ADDR, &reg_cntl); 160 + ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg_cntl); 152 161 if (ret) 153 162 return; 154 163 ··· 159 168 else 160 169 reg_cntl &= ~SLP_CLK_ENA_8660; 161 170 162 - regmap_write(tmdev->map, CNTL_ADDR, reg_cntl); 171 + regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl); 163 172 } 164 173 165 174 static int init_8960(struct tsens_device *tmdev) ··· 167 176 int ret, i; 168 177 u32 reg_cntl; 169 178 170 - tmdev->map = dev_get_regmap(tmdev->dev, NULL); 171 - if (!tmdev->map) 179 + tmdev->tm_map = dev_get_regmap(tmdev->dev, NULL); 180 + if (!tmdev->tm_map) 172 181 return -ENODEV; 173 182 174 183 /* ··· 184 193 } 185 194 186 195 reg_cntl = SW_RST; 187 - ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl); 196 + ret = regmap_update_bits(tmdev->tm_map, CNTL_ADDR, SW_RST, reg_cntl); 188 197 if (ret) 189 198 return ret; 190 199 191 200 if (tmdev->num_sensors > 1) { 192 201 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); 193 202 reg_cntl &= ~SW_RST; 194 - ret = regmap_update_bits(tmdev->map, CONFIG_ADDR, 203 + ret = regmap_update_bits(tmdev->tm_map, CONFIG_ADDR, 195 204 CONFIG_MASK, CONFIG); 196 205 } else { 197 206 reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16); ··· 200 209 } 201 210 202 211 reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT; 203 - ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl); 212 + ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl); 204 213 if (ret) 205 214 return ret; 206 215 207 216 reg_cntl |= EN; 208 - ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl); 217 + ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl); 209 218 if (ret) 210 219 return ret; 211 220 ··· 252 261 253 262 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); 254 263 do { 255 - ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy); 264 + ret = regmap_read(tmdev->tm_map, INT_STATUS_ADDR, &trdy); 256 265 if (ret) 257 266 return ret; 258 267 if (!(trdy & TRDY_MASK)) 259 268 continue; 260 - ret = regmap_read(tmdev->map, s->status, &code); 269 + ret = regmap_read(tmdev->tm_map, s->status, &code); 261 270 if (ret) 262 271 return ret; 263 272 *temp = code_to_mdegC(code, s);
+2 -10
drivers/thermal/qcom/tsens-8974.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 and 6 - * only version 2 as published by the Free Software Foundation. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - * 13 4 */ 14 5 15 6 #include <linux/platform_device.h> ··· 232 241 const struct tsens_data data_8974 = { 233 242 .num_sensors = 11, 234 243 .ops = &ops_8974, 244 + .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 }, 235 245 };
+39 -21
drivers/thermal/qcom/tsens-common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 and 6 - * only version 2 as published by the Free Software Foundation. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - * 13 4 */ 14 5 15 6 #include <linux/err.h> ··· 12 21 #include <linux/regmap.h> 13 22 #include "tsens.h" 14 23 15 - #define S0_ST_ADDR 0x1030 24 + /* SROT */ 25 + #define TSENS_EN BIT(0) 26 + 27 + /* TM */ 28 + #define STATUS_OFFSET 0x30 16 29 #define SN_ADDR_OFFSET 0x4 17 30 #define SN_ST_TEMP_MASK 0x3ff 18 31 #define CAL_DEGC_PT1 30 ··· 102 107 unsigned int status_reg; 103 108 int last_temp = 0, ret; 104 109 105 - status_reg = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET; 106 - ret = regmap_read(tmdev->map, status_reg, &code); 110 + status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * SN_ADDR_OFFSET; 111 + ret = regmap_read(tmdev->tm_map, status_reg, &code); 107 112 if (ret) 108 113 return ret; 109 114 last_temp = code & SN_ST_TEMP_MASK; ··· 121 126 122 127 int __init init_common(struct tsens_device *tmdev) 123 128 { 124 - void __iomem *base; 129 + void __iomem *tm_base, *srot_base; 125 130 struct resource *res; 131 + u32 code; 132 + int ret; 126 133 struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node); 134 + u16 ctrl_offset = tmdev->reg_offsets[SROT_CTRL_OFFSET]; 127 135 128 136 if (!op) 129 137 return -EINVAL; 130 138 131 - /* The driver only uses the TM register address space for now */ 132 139 if (op->num_resources > 1) { 140 + /* DT with separate SROT and TM address space */ 133 141 tmdev->tm_offset = 0; 142 + res = platform_get_resource(op, IORESOURCE_MEM, 1); 143 + srot_base = devm_ioremap_resource(&op->dev, res); 144 + if (IS_ERR(srot_base)) 145 + return PTR_ERR(srot_base); 146 + 147 + tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, 148 + srot_base, &tsens_config); 149 + if (IS_ERR(tmdev->srot_map)) 150 + return PTR_ERR(tmdev->srot_map); 151 + 134 152 } else { 135 153 /* old DTs where SROT and TM were in a contiguous 2K block */ 136 154 tmdev->tm_offset = 0x1000; 137 155 } 138 156 139 157 res = platform_get_resource(op, IORESOURCE_MEM, 0); 140 - base = devm_ioremap_resource(&op->dev, res); 141 - if (IS_ERR(base)) 142 - return PTR_ERR(base); 158 + tm_base = devm_ioremap_resource(&op->dev, res); 159 + if (IS_ERR(tm_base)) 160 + return PTR_ERR(tm_base); 143 161 144 - tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config); 145 - if (IS_ERR(tmdev->map)) 146 - return PTR_ERR(tmdev->map); 162 + tmdev->tm_map = devm_regmap_init_mmio(tmdev->dev, tm_base, &tsens_config); 163 + if (IS_ERR(tmdev->tm_map)) 164 + return PTR_ERR(tmdev->tm_map); 165 + 166 + if (tmdev->srot_map) { 167 + ret = regmap_read(tmdev->srot_map, ctrl_offset, &code); 168 + if (ret) 169 + return ret; 170 + if (!(code & TSENS_EN)) { 171 + dev_err(tmdev->dev, "tsens device is not enabled\n"); 172 + return -ENODEV; 173 + } 174 + } 147 175 148 176 return 0; 149 177 }
+5 -3
drivers/thermal/qcom/tsens-v2.c
··· 21 21 int ret; 22 22 23 23 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4; 24 - ret = regmap_read(tmdev->map, status_reg, &code); 24 + ret = regmap_read(tmdev->tm_map, status_reg, &code); 25 25 if (ret) 26 26 return ret; 27 27 last_temp = code & LAST_TEMP_MASK; ··· 29 29 goto done; 30 30 31 31 /* Try a second time */ 32 - ret = regmap_read(tmdev->map, status_reg, &code); 32 + ret = regmap_read(tmdev->tm_map, status_reg, &code); 33 33 if (ret) 34 34 return ret; 35 35 if (code & STATUS_VALID_BIT) { ··· 40 40 } 41 41 42 42 /* Try a third/last time */ 43 - ret = regmap_read(tmdev->map, status_reg, &code); 43 + ret = regmap_read(tmdev->tm_map, status_reg, &code); 44 44 if (ret) 45 45 return ret; 46 46 if (code & STATUS_VALID_BIT) { ··· 68 68 69 69 const struct tsens_data data_tsens_v2 = { 70 70 .ops = &ops_generic_v2, 71 + .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 }, 71 72 }; 72 73 73 74 /* Kept around for backward compatibility with old msm8996.dtsi */ 74 75 const struct tsens_data data_8996 = { 75 76 .num_sensors = 13, 76 77 .ops = &ops_generic_v2, 78 + .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 }, 77 79 };
+4 -15
drivers/thermal/qcom/tsens.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 and 6 - * only version 2 as published by the Free Software Foundation. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - * 13 4 */ 14 5 15 6 #include <linux/err.h> ··· 80 89 { 81 90 int i; 82 91 struct thermal_zone_device *tzd; 83 - u32 *hw_id, n = tmdev->num_sensors; 84 - 85 - hw_id = devm_kcalloc(tmdev->dev, n, sizeof(u32), GFP_KERNEL); 86 - if (!hw_id) 87 - return -ENOMEM; 88 92 89 93 for (i = 0; i < tmdev->num_sensors; i++) { 90 94 tmdev->sensor[i].tmdev = tmdev; ··· 143 157 tmdev->sensor[i].hw_id = data->hw_ids[i]; 144 158 else 145 159 tmdev->sensor[i].hw_id = i; 160 + } 161 + for (i = 0; i < REG_ARRAY_SIZE; i++) { 162 + tmdev->reg_offsets[i] = data->reg_offsets[i]; 146 163 } 147 164 148 165 if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp)
+13 -10
drivers/thermal/qcom/tsens.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 1 2 /* 2 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 4 */ 5 + 13 6 #ifndef __QCOM_TSENS_H__ 14 7 #define __QCOM_TSENS_H__ 15 8 ··· 48 55 int (*get_trend)(struct tsens_device *, int, enum thermal_trend *); 49 56 }; 50 57 58 + enum reg_list { 59 + SROT_CTRL_OFFSET, 60 + 61 + REG_ARRAY_SIZE, 62 + }; 63 + 51 64 /** 52 65 * struct tsens_data - tsens instance specific data 53 66 * @num_sensors: Max number of sensors supported by platform 54 67 * @ops: operations the tsens instance supports 55 68 * @hw_ids: Subset of sensors ids supported by platform, if not the first n 69 + * @reg_offsets: Register offsets for commonly used registers 56 70 */ 57 71 struct tsens_data { 58 72 const u32 num_sensors; 59 73 const struct tsens_ops *ops; 74 + const u16 reg_offsets[REG_ARRAY_SIZE]; 60 75 unsigned int *hw_ids; 61 76 }; 62 77 ··· 77 76 struct tsens_device { 78 77 struct device *dev; 79 78 u32 num_sensors; 80 - struct regmap *map; 79 + struct regmap *tm_map; 80 + struct regmap *srot_map; 81 81 u32 tm_offset; 82 + u16 reg_offsets[REG_ARRAY_SIZE]; 82 83 struct tsens_context ctx; 83 84 const struct tsens_ops *ops; 84 85 struct tsens_sensor sensor[0];
+3 -2
drivers/thermal/qoriq_thermal.c
··· 119 119 if (sensor_specs.args_count >= 1) { 120 120 id = sensor_specs.args[0]; 121 121 WARN(sensor_specs.args_count > 1, 122 - "%s: too many cells in sensor specifier %d\n", 123 - sensor_specs.np->name, sensor_specs.args_count); 122 + "%pOFn: too many cells in sensor specifier %d\n", 123 + sensor_specs.np, sensor_specs.args_count); 124 124 } else { 125 125 id = 0; 126 126 } ··· 294 294 295 295 static const struct of_device_id qoriq_tmu_match[] = { 296 296 { .compatible = "fsl,qoriq-tmu", }, 297 + { .compatible = "fsl,imx8mq-tmu", }, 297 298 {}, 298 299 }; 299 300 MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
+2
drivers/thermal/rcar_gen3_thermal.c
··· 318 318 } 319 319 320 320 static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { 321 + { .compatible = "renesas,r8a774a1-thermal", }, 321 322 { .compatible = "renesas,r8a7795-thermal", }, 322 323 { .compatible = "renesas,r8a7796-thermal", }, 323 324 { .compatible = "renesas,r8a77965-thermal", }, 325 + { .compatible = "renesas,r8a77980-thermal", }, 324 326 {}, 325 327 }; 326 328 MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
+8 -3
drivers/thermal/rcar_thermal.c
··· 113 113 .data = &rcar_gen2_thermal, 114 114 }, 115 115 { 116 + .compatible = "renesas,thermal-r8a77970", 117 + .data = &rcar_gen3_thermal, 118 + }, 119 + { 116 120 .compatible = "renesas,thermal-r8a77995", 117 121 .data = &rcar_gen3_thermal, 118 122 }, ··· 438 434 rcar_thermal_for_each_priv(priv, common) { 439 435 if (rcar_thermal_had_changed(priv, status)) { 440 436 rcar_thermal_irq_disable(priv); 441 - schedule_delayed_work(&priv->work, 442 - msecs_to_jiffies(300)); 437 + queue_delayed_work(system_freezable_wq, &priv->work, 438 + msecs_to_jiffies(300)); 443 439 } 444 440 } 445 441 ··· 457 453 458 454 rcar_thermal_for_each_priv(priv, common) { 459 455 rcar_thermal_irq_disable(priv); 456 + cancel_delayed_work_sync(&priv->work); 460 457 if (priv->chip->use_of_thermal) 461 458 thermal_remove_hwmon_sysfs(priv->zone); 462 459 else ··· 497 492 pm_runtime_get_sync(dev); 498 493 499 494 for (i = 0; i < chip->nirqs; i++) { 500 - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 495 + irq = platform_get_resource(pdev, IORESOURCE_IRQ, i); 501 496 if (!irq) 502 497 continue; 503 498 if (!common->base) {
+14
drivers/thermal/st/Kconfig
··· 1 + # 2 + # STMicroelectronics thermal drivers configuration 3 + # 4 + 1 5 config ST_THERMAL 2 6 tristate "Thermal sensors on STMicroelectronics STi series of SoCs" 3 7 help ··· 14 10 config ST_THERMAL_MEMMAP 15 11 select ST_THERMAL 16 12 tristate "STi series memory mapped access based thermal sensors" 13 + 14 + config STM32_THERMAL 15 + tristate "Thermal framework support on STMicroelectronics STM32 series of SoCs" 16 + depends on MACH_STM32MP157 17 + default y 18 + help 19 + Support for thermal framework on STMicroelectronics STM32 series of 20 + SoCs. This thermal driver allows to access to general thermal framework 21 + functionalities and to acces to SoC sensor functionalities. This 22 + configuration is fully dependent of MACH_STM32MP157.
+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
+760
drivers/thermal/st/stm_thermal.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) STMicroelectronics 2018 - All Rights Reserved 4 + * Author: David Hernandez Sanchez <david.hernandezsanchez@st.com> for 5 + * STMicroelectronics. 6 + */ 7 + 8 + #include <linux/clk.h> 9 + #include <linux/clk-provider.h> 10 + #include <linux/delay.h> 11 + #include <linux/err.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/io.h> 14 + #include <linux/iopoll.h> 15 + #include <linux/module.h> 16 + #include <linux/of.h> 17 + #include <linux/of_address.h> 18 + #include <linux/of_device.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/thermal.h> 21 + 22 + #include "../thermal_core.h" 23 + #include "../thermal_hwmon.h" 24 + 25 + /* DTS register offsets */ 26 + #define DTS_CFGR1_OFFSET 0x0 27 + #define DTS_T0VALR1_OFFSET 0x8 28 + #define DTS_RAMPVALR_OFFSET 0X10 29 + #define DTS_ITR1_OFFSET 0x14 30 + #define DTS_DR_OFFSET 0x1C 31 + #define DTS_SR_OFFSET 0x20 32 + #define DTS_ITENR_OFFSET 0x24 33 + #define DTS_CIFR_OFFSET 0x28 34 + 35 + /* DTS_CFGR1 register mask definitions */ 36 + #define HSREF_CLK_DIV_MASK GENMASK(30, 24) 37 + #define TS1_SMP_TIME_MASK GENMASK(19, 16) 38 + #define TS1_INTRIG_SEL_MASK GENMASK(11, 8) 39 + 40 + /* DTS_T0VALR1 register mask definitions */ 41 + #define TS1_T0_MASK GENMASK(17, 16) 42 + #define TS1_FMT0_MASK GENMASK(15, 0) 43 + 44 + /* DTS_RAMPVALR register mask definitions */ 45 + #define TS1_RAMP_COEFF_MASK GENMASK(15, 0) 46 + 47 + /* DTS_ITR1 register mask definitions */ 48 + #define TS1_HITTHD_MASK GENMASK(31, 16) 49 + #define TS1_LITTHD_MASK GENMASK(15, 0) 50 + 51 + /* DTS_DR register mask definitions */ 52 + #define TS1_MFREQ_MASK GENMASK(15, 0) 53 + 54 + /* Less significant bit position definitions */ 55 + #define TS1_T0_POS 16 56 + #define TS1_SMP_TIME_POS 16 57 + #define TS1_HITTHD_POS 16 58 + #define HSREF_CLK_DIV_POS 24 59 + 60 + /* DTS_CFGR1 bit definitions */ 61 + #define TS1_EN BIT(0) 62 + #define TS1_START BIT(4) 63 + #define REFCLK_SEL BIT(20) 64 + #define REFCLK_LSE REFCLK_SEL 65 + #define Q_MEAS_OPT BIT(21) 66 + #define CALIBRATION_CONTROL Q_MEAS_OPT 67 + 68 + /* DTS_SR bit definitions */ 69 + #define TS_RDY BIT(15) 70 + /* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */ 71 + #define HIGH_THRESHOLD BIT(2) 72 + #define LOW_THRESHOLD BIT(1) 73 + 74 + /* Constants */ 75 + #define ADJUST 100 76 + #define ONE_MHZ 1000000 77 + #define POLL_TIMEOUT 5000 78 + #define STARTUP_TIME 40 79 + #define TS1_T0_VAL0 30 80 + #define TS1_T0_VAL1 130 81 + #define NO_HW_TRIG 0 82 + 83 + /* The Thermal Framework expects millidegrees */ 84 + #define mcelsius(temp) ((temp) * 1000) 85 + 86 + /* The Sensor expects oC degrees */ 87 + #define celsius(temp) ((temp) / 1000) 88 + 89 + struct stm_thermal_sensor { 90 + struct device *dev; 91 + struct thermal_zone_device *th_dev; 92 + enum thermal_device_mode mode; 93 + struct clk *clk; 94 + int high_temp; 95 + int low_temp; 96 + int temp_critical; 97 + int temp_passive; 98 + unsigned int low_temp_enabled; 99 + int num_trips; 100 + int irq; 101 + unsigned int irq_enabled; 102 + void __iomem *base; 103 + int t0, fmt0, ramp_coeff; 104 + }; 105 + 106 + static irqreturn_t stm_thermal_alarm_irq(int irq, void *sdata) 107 + { 108 + struct stm_thermal_sensor *sensor = sdata; 109 + 110 + disable_irq_nosync(irq); 111 + sensor->irq_enabled = false; 112 + 113 + return IRQ_WAKE_THREAD; 114 + } 115 + 116 + static irqreturn_t stm_thermal_alarm_irq_thread(int irq, void *sdata) 117 + { 118 + u32 value; 119 + struct stm_thermal_sensor *sensor = sdata; 120 + 121 + /* read IT reason in SR and clear flags */ 122 + value = readl_relaxed(sensor->base + DTS_SR_OFFSET); 123 + 124 + if ((value & LOW_THRESHOLD) == LOW_THRESHOLD) 125 + writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET); 126 + 127 + if ((value & HIGH_THRESHOLD) == HIGH_THRESHOLD) 128 + writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET); 129 + 130 + thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED); 131 + 132 + return IRQ_HANDLED; 133 + } 134 + 135 + static int stm_sensor_power_on(struct stm_thermal_sensor *sensor) 136 + { 137 + int ret; 138 + u32 value; 139 + 140 + /* Enable sensor */ 141 + value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); 142 + value |= TS1_EN; 143 + writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); 144 + 145 + /* 146 + * The DTS block can be enabled by setting TSx_EN bit in 147 + * DTS_CFGRx register. It requires a startup time of 148 + * 40μs. Use 5 ms as arbitrary timeout. 149 + */ 150 + ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET, 151 + value, (value & TS_RDY), 152 + STARTUP_TIME, POLL_TIMEOUT); 153 + if (ret) 154 + return ret; 155 + 156 + /* Start continuous measuring */ 157 + value = readl_relaxed(sensor->base + 158 + DTS_CFGR1_OFFSET); 159 + value |= TS1_START; 160 + writel_relaxed(value, sensor->base + 161 + DTS_CFGR1_OFFSET); 162 + 163 + return 0; 164 + } 165 + 166 + static int stm_sensor_power_off(struct stm_thermal_sensor *sensor) 167 + { 168 + u32 value; 169 + 170 + /* Stop measuring */ 171 + value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); 172 + value &= ~TS1_START; 173 + writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); 174 + 175 + /* Ensure stop is taken into account */ 176 + usleep_range(STARTUP_TIME, POLL_TIMEOUT); 177 + 178 + /* Disable sensor */ 179 + value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); 180 + value &= ~TS1_EN; 181 + writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); 182 + 183 + /* Ensure disable is taken into account */ 184 + return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value, 185 + !(value & TS_RDY), 186 + STARTUP_TIME, POLL_TIMEOUT); 187 + } 188 + 189 + static int stm_thermal_calibration(struct stm_thermal_sensor *sensor) 190 + { 191 + u32 value, clk_freq; 192 + u32 prescaler; 193 + 194 + /* Figure out prescaler value for PCLK during calibration */ 195 + clk_freq = clk_get_rate(sensor->clk); 196 + if (!clk_freq) 197 + return -EINVAL; 198 + 199 + prescaler = 0; 200 + clk_freq /= ONE_MHZ; 201 + if (clk_freq) { 202 + while (prescaler <= clk_freq) 203 + prescaler++; 204 + } 205 + 206 + value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); 207 + 208 + /* Clear prescaler */ 209 + value &= ~HSREF_CLK_DIV_MASK; 210 + 211 + /* Set prescaler. pclk_freq/prescaler < 1MHz */ 212 + value |= (prescaler << HSREF_CLK_DIV_POS); 213 + 214 + /* Select PCLK as reference clock */ 215 + value &= ~REFCLK_SEL; 216 + 217 + /* Set maximal sampling time for better precision */ 218 + value |= TS1_SMP_TIME_MASK; 219 + 220 + /* Measure with calibration */ 221 + value &= ~CALIBRATION_CONTROL; 222 + 223 + /* select trigger */ 224 + value &= ~TS1_INTRIG_SEL_MASK; 225 + value |= NO_HW_TRIG; 226 + 227 + writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); 228 + 229 + return 0; 230 + } 231 + 232 + /* Fill in DTS structure with factory sensor values */ 233 + static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor) 234 + { 235 + /* Retrieve engineering calibration temperature */ 236 + sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) & 237 + TS1_T0_MASK; 238 + if (!sensor->t0) 239 + sensor->t0 = TS1_T0_VAL0; 240 + else 241 + sensor->t0 = TS1_T0_VAL1; 242 + 243 + /* Retrieve fmt0 and put it on Hz */ 244 + sensor->fmt0 = ADJUST * readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) 245 + & TS1_FMT0_MASK; 246 + 247 + /* Retrieve ramp coefficient */ 248 + sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) & 249 + TS1_RAMP_COEFF_MASK; 250 + 251 + if (!sensor->fmt0 || !sensor->ramp_coeff) { 252 + dev_err(sensor->dev, "%s: wrong setting\n", __func__); 253 + return -EINVAL; 254 + } 255 + 256 + dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC", 257 + __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff); 258 + 259 + return 0; 260 + } 261 + 262 + static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor, 263 + int temp, u32 *th) 264 + { 265 + int freqM; 266 + u32 sampling_time; 267 + 268 + /* Retrieve the number of periods to sample */ 269 + sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) & 270 + TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS; 271 + 272 + /* Figure out the CLK_PTAT frequency for a given temperature */ 273 + freqM = ((temp - sensor->t0) * sensor->ramp_coeff) 274 + + sensor->fmt0; 275 + 276 + dev_dbg(sensor->dev, "%s: freqM for threshold = %d Hz", 277 + __func__, freqM); 278 + 279 + /* Figure out the threshold sample number */ 280 + *th = clk_get_rate(sensor->clk); 281 + if (!*th) 282 + return -EINVAL; 283 + 284 + *th = *th / freqM; 285 + 286 + *th *= sampling_time; 287 + 288 + return 0; 289 + } 290 + 291 + static int stm_thermal_set_threshold(struct stm_thermal_sensor *sensor) 292 + { 293 + u32 value, th; 294 + int ret; 295 + 296 + value = readl_relaxed(sensor->base + DTS_ITR1_OFFSET); 297 + 298 + /* Erase threshold content */ 299 + value &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK); 300 + 301 + /* Retrieve the sample threshold number th for a given temperature */ 302 + ret = stm_thermal_calculate_threshold(sensor, sensor->high_temp, &th); 303 + if (ret) 304 + return ret; 305 + 306 + value |= th & TS1_LITTHD_MASK; 307 + 308 + if (sensor->low_temp_enabled) { 309 + /* Retrieve the sample threshold */ 310 + ret = stm_thermal_calculate_threshold(sensor, sensor->low_temp, 311 + &th); 312 + if (ret) 313 + return ret; 314 + 315 + value |= (TS1_HITTHD_MASK & (th << TS1_HITTHD_POS)); 316 + } 317 + 318 + /* Write value on the Low interrupt threshold */ 319 + writel_relaxed(value, sensor->base + DTS_ITR1_OFFSET); 320 + 321 + return 0; 322 + } 323 + 324 + /* Disable temperature interrupt */ 325 + static int stm_disable_irq(struct stm_thermal_sensor *sensor) 326 + { 327 + u32 value; 328 + 329 + /* Disable IT generation for low and high thresholds */ 330 + value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET); 331 + writel_relaxed(value & ~(LOW_THRESHOLD | HIGH_THRESHOLD), 332 + sensor->base + DTS_ITENR_OFFSET); 333 + 334 + dev_dbg(sensor->dev, "%s: IT disabled on sensor side", __func__); 335 + 336 + return 0; 337 + } 338 + 339 + /* Enable temperature interrupt */ 340 + static int stm_enable_irq(struct stm_thermal_sensor *sensor) 341 + { 342 + u32 value; 343 + 344 + /* 345 + * Code below enables High temperature threshold using a low threshold 346 + * sampling value 347 + */ 348 + 349 + /* Make sure LOW_THRESHOLD IT is clear before enabling */ 350 + writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET); 351 + 352 + /* Enable IT generation for low threshold */ 353 + value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET); 354 + value |= LOW_THRESHOLD; 355 + 356 + /* Enable the low temperature threshold if needed */ 357 + if (sensor->low_temp_enabled) { 358 + /* Make sure HIGH_THRESHOLD IT is clear before enabling */ 359 + writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET); 360 + 361 + /* Enable IT generation for high threshold */ 362 + value |= HIGH_THRESHOLD; 363 + } 364 + 365 + /* Enable thresholds */ 366 + writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET); 367 + 368 + dev_dbg(sensor->dev, "%s: IT enabled on sensor side", __func__); 369 + 370 + return 0; 371 + } 372 + 373 + static int stm_thermal_update_threshold(struct stm_thermal_sensor *sensor) 374 + { 375 + int ret; 376 + 377 + sensor->mode = THERMAL_DEVICE_DISABLED; 378 + 379 + ret = stm_sensor_power_off(sensor); 380 + if (ret) 381 + return ret; 382 + 383 + ret = stm_disable_irq(sensor); 384 + if (ret) 385 + return ret; 386 + 387 + ret = stm_thermal_set_threshold(sensor); 388 + if (ret) 389 + return ret; 390 + 391 + ret = stm_enable_irq(sensor); 392 + if (ret) 393 + return ret; 394 + 395 + ret = stm_sensor_power_on(sensor); 396 + if (ret) 397 + return ret; 398 + 399 + sensor->mode = THERMAL_DEVICE_ENABLED; 400 + 401 + return 0; 402 + } 403 + 404 + /* Callback to get temperature from HW */ 405 + static int stm_thermal_get_temp(void *data, int *temp) 406 + { 407 + struct stm_thermal_sensor *sensor = data; 408 + u32 sampling_time; 409 + int freqM, ret; 410 + 411 + if (sensor->mode != THERMAL_DEVICE_ENABLED) 412 + return -EAGAIN; 413 + 414 + /* Retrieve the number of samples */ 415 + ret = readl_poll_timeout(sensor->base + DTS_DR_OFFSET, freqM, 416 + (freqM & TS1_MFREQ_MASK), STARTUP_TIME, 417 + POLL_TIMEOUT); 418 + 419 + if (ret) 420 + return ret; 421 + 422 + if (!freqM) 423 + return -ENODATA; 424 + 425 + /* Retrieve the number of periods sampled */ 426 + sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) & 427 + TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS; 428 + 429 + /* Figure out the number of samples per period */ 430 + freqM /= sampling_time; 431 + 432 + /* Figure out the CLK_PTAT frequency */ 433 + freqM = clk_get_rate(sensor->clk) / freqM; 434 + if (!freqM) 435 + return -EINVAL; 436 + 437 + dev_dbg(sensor->dev, "%s: freqM=%d\n", __func__, freqM); 438 + 439 + /* Figure out the temperature in mili celsius */ 440 + *temp = mcelsius(sensor->t0 + ((freqM - sensor->fmt0) / 441 + sensor->ramp_coeff)); 442 + 443 + dev_dbg(sensor->dev, "%s: temperature = %d millicelsius", 444 + __func__, *temp); 445 + 446 + /* Update thresholds */ 447 + if (sensor->num_trips > 1) { 448 + /* Update alarm threshold value to next higher trip point */ 449 + if (sensor->high_temp == sensor->temp_passive && 450 + celsius(*temp) >= sensor->temp_passive) { 451 + sensor->high_temp = sensor->temp_critical; 452 + sensor->low_temp = sensor->temp_passive; 453 + sensor->low_temp_enabled = true; 454 + ret = stm_thermal_update_threshold(sensor); 455 + if (ret) 456 + return ret; 457 + } 458 + 459 + if (sensor->high_temp == sensor->temp_critical && 460 + celsius(*temp) < sensor->temp_passive) { 461 + sensor->high_temp = sensor->temp_passive; 462 + sensor->low_temp_enabled = false; 463 + ret = stm_thermal_update_threshold(sensor); 464 + if (ret) 465 + return ret; 466 + } 467 + 468 + /* 469 + * Re-enable alarm IRQ if temperature below critical 470 + * temperature 471 + */ 472 + if (!sensor->irq_enabled && 473 + (celsius(*temp) < sensor->temp_critical)) { 474 + sensor->irq_enabled = true; 475 + enable_irq(sensor->irq); 476 + } 477 + } 478 + 479 + return 0; 480 + } 481 + 482 + /* Registers DTS irq to be visible by GIC */ 483 + static int stm_register_irq(struct stm_thermal_sensor *sensor) 484 + { 485 + struct device *dev = sensor->dev; 486 + struct platform_device *pdev = to_platform_device(dev); 487 + int ret; 488 + 489 + sensor->irq = platform_get_irq(pdev, 0); 490 + if (sensor->irq < 0) { 491 + dev_err(dev, "%s: Unable to find IRQ\n", __func__); 492 + return sensor->irq; 493 + } 494 + 495 + ret = devm_request_threaded_irq(dev, sensor->irq, 496 + stm_thermal_alarm_irq, 497 + stm_thermal_alarm_irq_thread, 498 + IRQF_ONESHOT, 499 + dev->driver->name, sensor); 500 + if (ret) { 501 + dev_err(dev, "%s: Failed to register IRQ %d\n", __func__, 502 + sensor->irq); 503 + return ret; 504 + } 505 + 506 + sensor->irq_enabled = true; 507 + 508 + dev_dbg(dev, "%s: thermal IRQ registered", __func__); 509 + 510 + return 0; 511 + } 512 + 513 + static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor) 514 + { 515 + int ret; 516 + 517 + ret = stm_sensor_power_off(sensor); 518 + if (ret) 519 + return ret; 520 + 521 + clk_disable_unprepare(sensor->clk); 522 + 523 + return 0; 524 + } 525 + 526 + static int stm_thermal_prepare(struct stm_thermal_sensor *sensor) 527 + { 528 + int ret; 529 + struct device *dev = sensor->dev; 530 + 531 + ret = clk_prepare_enable(sensor->clk); 532 + if (ret) 533 + return ret; 534 + 535 + ret = stm_thermal_calibration(sensor); 536 + if (ret) 537 + goto thermal_unprepare; 538 + 539 + /* Set threshold(s) for IRQ */ 540 + ret = stm_thermal_set_threshold(sensor); 541 + if (ret) 542 + goto thermal_unprepare; 543 + 544 + ret = stm_enable_irq(sensor); 545 + if (ret) 546 + goto thermal_unprepare; 547 + 548 + ret = stm_sensor_power_on(sensor); 549 + if (ret) { 550 + dev_err(dev, "%s: failed to power on sensor\n", __func__); 551 + goto irq_disable; 552 + } 553 + 554 + return 0; 555 + 556 + irq_disable: 557 + stm_disable_irq(sensor); 558 + 559 + thermal_unprepare: 560 + clk_disable_unprepare(sensor->clk); 561 + 562 + return ret; 563 + } 564 + 565 + #ifdef CONFIG_PM_SLEEP 566 + static int stm_thermal_suspend(struct device *dev) 567 + { 568 + int ret; 569 + struct platform_device *pdev = to_platform_device(dev); 570 + struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev); 571 + 572 + ret = stm_thermal_sensor_off(sensor); 573 + if (ret) 574 + return ret; 575 + 576 + sensor->mode = THERMAL_DEVICE_DISABLED; 577 + 578 + return 0; 579 + } 580 + 581 + static int stm_thermal_resume(struct device *dev) 582 + { 583 + int ret; 584 + struct platform_device *pdev = to_platform_device(dev); 585 + struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev); 586 + 587 + ret = stm_thermal_prepare(sensor); 588 + if (ret) 589 + return ret; 590 + 591 + sensor->mode = THERMAL_DEVICE_ENABLED; 592 + 593 + return 0; 594 + } 595 + #endif /* CONFIG_PM_SLEEP */ 596 + 597 + SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops, stm_thermal_suspend, stm_thermal_resume); 598 + 599 + static const struct thermal_zone_of_device_ops stm_tz_ops = { 600 + .get_temp = stm_thermal_get_temp, 601 + }; 602 + 603 + static const struct of_device_id stm_thermal_of_match[] = { 604 + { .compatible = "st,stm32-thermal"}, 605 + { /* sentinel */ } 606 + }; 607 + MODULE_DEVICE_TABLE(of, stm_thermal_of_match); 608 + 609 + static int stm_thermal_probe(struct platform_device *pdev) 610 + { 611 + struct stm_thermal_sensor *sensor; 612 + struct resource *res; 613 + const struct thermal_trip *trip; 614 + void __iomem *base; 615 + int ret, i; 616 + 617 + if (!pdev->dev.of_node) { 618 + dev_err(&pdev->dev, "%s: device tree node not found\n", 619 + __func__); 620 + return -EINVAL; 621 + } 622 + 623 + sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL); 624 + if (!sensor) 625 + return -ENOMEM; 626 + 627 + platform_set_drvdata(pdev, sensor); 628 + 629 + sensor->dev = &pdev->dev; 630 + 631 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 632 + base = devm_ioremap_resource(&pdev->dev, res); 633 + if (IS_ERR(base)) 634 + return PTR_ERR(base); 635 + 636 + /* Populate sensor */ 637 + sensor->base = base; 638 + 639 + ret = stm_thermal_read_factory_settings(sensor); 640 + if (ret) 641 + return ret; 642 + 643 + sensor->clk = devm_clk_get(&pdev->dev, "pclk"); 644 + if (IS_ERR(sensor->clk)) { 645 + dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n", 646 + __func__); 647 + return PTR_ERR(sensor->clk); 648 + } 649 + 650 + /* Register IRQ into GIC */ 651 + ret = stm_register_irq(sensor); 652 + if (ret) 653 + return ret; 654 + 655 + sensor->th_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, 656 + sensor, 657 + &stm_tz_ops); 658 + 659 + if (IS_ERR(sensor->th_dev)) { 660 + dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n", 661 + __func__); 662 + ret = PTR_ERR(sensor->th_dev); 663 + return ret; 664 + } 665 + 666 + if (!sensor->th_dev->ops->get_crit_temp) { 667 + /* Critical point must be provided */ 668 + ret = -EINVAL; 669 + goto err_tz; 670 + } 671 + 672 + ret = sensor->th_dev->ops->get_crit_temp(sensor->th_dev, 673 + &sensor->temp_critical); 674 + if (ret) { 675 + dev_err(&pdev->dev, 676 + "Not able to read critical_temp: %d\n", ret); 677 + goto err_tz; 678 + } 679 + 680 + sensor->temp_critical = celsius(sensor->temp_critical); 681 + 682 + /* Set thresholds for IRQ */ 683 + sensor->high_temp = sensor->temp_critical; 684 + 685 + trip = of_thermal_get_trip_points(sensor->th_dev); 686 + sensor->num_trips = of_thermal_get_ntrips(sensor->th_dev); 687 + 688 + /* Find out passive temperature if it exists */ 689 + for (i = (sensor->num_trips - 1); i >= 0; i--) { 690 + if (trip[i].type == THERMAL_TRIP_PASSIVE) { 691 + sensor->temp_passive = celsius(trip[i].temperature); 692 + /* Update high temperature threshold */ 693 + sensor->high_temp = sensor->temp_passive; 694 + } 695 + } 696 + 697 + /* 698 + * Ensure low_temp_enabled flag is disabled. 699 + * By disabling low_temp_enabled, low threshold IT will not be 700 + * configured neither enabled because it is not needed as high 701 + * threshold is set on the lowest temperature trip point after 702 + * probe. 703 + */ 704 + sensor->low_temp_enabled = false; 705 + 706 + /* Configure and enable HW sensor */ 707 + ret = stm_thermal_prepare(sensor); 708 + if (ret) { 709 + dev_err(&pdev->dev, 710 + "Not able to enable sensor: %d\n", ret); 711 + goto err_tz; 712 + } 713 + 714 + /* 715 + * Thermal_zone doesn't enable hwmon as default, 716 + * enable it here 717 + */ 718 + sensor->th_dev->tzp->no_hwmon = false; 719 + ret = thermal_add_hwmon_sysfs(sensor->th_dev); 720 + if (ret) 721 + goto err_tz; 722 + 723 + sensor->mode = THERMAL_DEVICE_ENABLED; 724 + 725 + dev_info(&pdev->dev, "%s: Driver initialized successfully\n", 726 + __func__); 727 + 728 + return 0; 729 + 730 + err_tz: 731 + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev); 732 + return ret; 733 + } 734 + 735 + static int stm_thermal_remove(struct platform_device *pdev) 736 + { 737 + struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev); 738 + 739 + stm_thermal_sensor_off(sensor); 740 + thermal_remove_hwmon_sysfs(sensor->th_dev); 741 + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev); 742 + 743 + return 0; 744 + } 745 + 746 + static struct platform_driver stm_thermal_driver = { 747 + .driver = { 748 + .name = "stm_thermal", 749 + .pm = &stm_thermal_pm_ops, 750 + .of_match_table = stm_thermal_of_match, 751 + }, 752 + .probe = stm_thermal_probe, 753 + .remove = stm_thermal_remove, 754 + }; 755 + module_platform_driver(stm_thermal_driver); 756 + 757 + MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver"); 758 + MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>"); 759 + MODULE_LICENSE("GPL v2"); 760 + MODULE_ALIAS("platform:stm_thermal");