summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-thermal259
-rw-r--r--Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml149
-rw-r--r--Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml23
-rw-r--r--Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml1
-rw-r--r--Documentation/driver-api/thermal/sysfs-api.rst225
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/thermal/gov_user_space.c9
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3400_thermal.c9
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3401_thermal.c8
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device.c36
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device.h1
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c18
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c8
-rw-r--r--drivers/thermal/intel/intel_powerclamp.c8
-rw-r--r--drivers/thermal/qcom/Kconfig2
-rw-r--r--drivers/thermal/qcom/qcom-spmi-adc-tm5.c41
-rw-r--r--drivers/thermal/qcom/tsens.c29
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c113
-rw-r--r--drivers/thermal/rockchip_thermal.c2
-rw-r--r--drivers/thermal/thermal_core.c22
-rw-r--r--drivers/thermal/thermal_mmio.c2
-rw-r--r--drivers/thermal/thermal_netlink.c11
-rw-r--r--drivers/thermal/thermal_netlink.h8
-rw-r--r--drivers/thermal/thermal_sysfs.c3
-rw-r--r--drivers/thermal/uniphier_thermal.c4
25 files changed, 679 insertions, 314 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-thermal b/Documentation/ABI/testing/sysfs-class-thermal
new file mode 100644
index 000000000000..2c52bb1f864c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-thermal
@@ -0,0 +1,259 @@
+What: /sys/class/thermal/thermal_zoneX/type
+Description:
+ Strings which represent the thermal zone type.
+ This is given by thermal zone driver as part of registration.
+ E.g: "acpitz" indicates it's an ACPI thermal device.
+ In order to keep it consistent with hwmon sys attribute; this
+ shouldbe a short, lowercase string, not containing spaces nor
+ dashes.
+
+ RO, Required
+
+What: /sys/class/thermal/thermal_zoneX/temp
+Description:
+ Current temperature as reported by thermal zone (sensor).
+
+ Unit: millidegree Celsius
+
+ RO, Required
+
+What: /sys/class/thermal/thermal_zoneX/mode
+Description:
+ One of the predefined values in [enabled, disabled].
+ This file gives information about the algorithm that is
+ currently managing the thermal zone. It can be either default
+ kernel based algorithm or user space application.
+
+ enabled
+ enable Kernel Thermal management.
+ disabled
+ Preventing kernel thermal zone driver actions upon
+ trip points so that user application can take full
+ charge of the thermal management.
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/policy
+Description:
+ One of the various thermal governors used for a particular zone.
+
+ RW, Required
+
+What: /sys/class/thermal/thermal_zoneX/available_policies
+Description:
+ Available thermal governors which can be used for a
+ particular zone.
+
+ RO, Required
+
+What: /sys/class/thermal/thermal_zoneX/trip_point_Y_temp
+Description:
+ The temperature above which trip point will be fired.
+
+ Unit: millidegree Celsius
+
+ RO, Optional
+
+What: /sys/class/thermal/thermal_zoneX/trip_point_Y_type
+Description:
+ Strings which indicate the type of the trip point.
+
+ E.g. it can be one of critical, hot, passive, `active[0-*]`
+ for ACPI thermal zone.
+
+ RO, Optional
+
+What: /sys/class/thermal/thermal_zoneX/trip_point_Y_hyst
+Description:
+ The hysteresis value for a trip point, represented as an
+ integer.
+
+ Unit: Celsius
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/cdevY
+Description:
+ Sysfs link to the thermal cooling device node where the sys I/F
+ for cooling device throttling control represents.
+
+ RO, Optional
+
+What: /sys/class/thermal/thermal_zoneX/cdevY_trip_point
+Description:
+ The trip point in this thermal zone which `cdev[0-*]` is
+ associated with; -1 means the cooling device is not
+ associated with any trip point.
+
+ RO, Optional
+
+What: /sys/class/thermal/thermal_zoneX/cdevY_weight
+Description:
+ The influence of `cdev[0-*]` in this thermal zone. This value
+ is relative to the rest of cooling devices in the thermal
+ zone. For example, if a cooling device has a weight double
+ than that of other, it's twice as effective in cooling the
+ thermal zone.
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/emul_temp
+Description:
+ Interface to set the emulated temperature method in thermal zone
+ (sensor). After setting this temperature, the thermal zone may
+ pass this temperature to platform emulation function if
+ registered or cache it locally. This is useful in debugging
+ different temperature threshold and its associated cooling
+ action. This is write only node and writing 0 on this node
+ should disable emulation.
+
+ Unit: millidegree Celsius
+
+ WO, Optional
+
+ WARNING:
+ Be careful while enabling this option on production systems,
+ because userland can easily disable the thermal policy by simply
+ flooding this sysfs node with low temperature values.
+
+
+What: /sys/class/thermal/thermal_zoneX/k_d
+Description:
+ The derivative term of the power allocator governor's PID
+ controller. For more information see
+ Documentation/driver-api/thermal/power_allocator.rst
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/k_i
+Description:
+ The integral term of the power allocator governor's PID
+ controller. This term allows the PID controller to compensate
+ for long term drift. For more information see
+ Documentation/driver-api/thermal/power_allocator.rst
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/k_po
+Description:
+ The proportional term of the power allocator governor's PID
+ controller during temperature overshoot. Temperature overshoot
+ is when the current temperature is above the "desired
+ temperature" trip point. For more information see
+ Documentation/driver-api/thermal/power_allocator.rst
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/k_pu
+Description:
+ The proportional term of the power allocator governor's PID
+ controller during temperature undershoot. Temperature undershoot
+ is when the current temperature is below the "desired
+ temperature" trip point. For more information see
+ Documentation/driver-api/thermal/power_allocator.rst
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/integral_cutoff
+Description:
+ Temperature offset from the desired temperature trip point
+ above which the integral term of the power allocator
+ governor's PID controller starts accumulating errors. For
+ example, if integral_cutoff is 0, then the integral term only
+ accumulates error when temperature is above the desired
+ temperature trip point. For more information see
+ Documentation/driver-api/thermal/power_allocator.rst
+
+ Unit: millidegree Celsius
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/slope
+Description:
+ The slope constant used in a linear extrapolation model
+ to determine a hotspot temperature based off the sensor's
+ raw readings. It is up to the device driver to determine
+ the usage of these values.
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/offset
+Description:
+ The offset constant used in a linear extrapolation model
+ to determine a hotspot temperature based off the sensor's
+ raw readings. It is up to the device driver to determine
+ the usage of these values.
+
+ RW, Optional
+
+What: /sys/class/thermal/thermal_zoneX/sustainable_power
+Description:
+ An estimate of the sustained power that can be dissipated by
+ the thermal zone. Used by the power allocator governor. For
+ more information see
+ Documentation/driver-api/thermal/power_allocator.rst
+
+ Unit: milliwatts
+
+ RW, Optional
+
+What: /sys/class/thermal/cooling_deviceX/type
+Description:
+ String which represents the type of device, e.g:
+
+ - for generic ACPI: should be "Fan", "Processor" or "LCD"
+ - for memory controller device on intel_menlow platform:
+ should be "Memory controller".
+
+ RO, Required
+
+What: /sys/class/thermal/cooling_deviceX/max_state
+Description:
+ The maximum permissible cooling state of this cooling device.
+
+ RO, Required
+
+What: /sys/class/thermal/cooling_deviceX/cur_state
+Description:
+ The current cooling state of this cooling device.
+ The value can any integer numbers between 0 and max_state:
+
+ - cur_state == 0 means no cooling
+ - cur_state == max_state means the maximum cooling.
+
+ RW, Required
+
+What: /sys/class/thermal/cooling_deviceX/stats/reset
+Description:
+ Writing any value resets the cooling device's statistics.
+
+ WO, Required
+
+What: /sys/class/thermal/cooling_deviceX/stats/time_in_state_ms:
+Description:
+ The amount of time spent by the cooling device in various
+ cooling states. The output will have "<state> <time>" pair
+ in each line, which will mean this cooling device spent <time>
+ msec of time at <state>.
+
+ Output will have one line for each of the supported states.
+
+ RO, Required
+
+What: /sys/class/thermal/cooling_deviceX/stats/total_trans
+Description:
+ A single positive value showing the total number of times
+ the state of a cooling device is changed.
+
+ RO, Required
+
+What: /sys/class/thermal/cooling_deviceX/stats/trans_table
+Description:
+ This gives fine grained information about all the cooling state
+ transitions. The cat output here is a two dimensional matrix,
+ where an entry <i,j> (row i, column j) represents the number
+ of transitions from State_i to State_j. If the transition
+ table is bigger than PAGE_SIZE, reading this will return
+ an -EFBIG error.
+
+ RO, Required
diff --git a/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml b/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml
new file mode 100644
index 000000000000..8273ac55b63f
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml
@@ -0,0 +1,149 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/qcom-spmi-adc-tm-hc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm's SPMI PMIC ADC HC Thermal Monitoring
+maintainers:
+ - Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+properties:
+ compatible:
+ const: qcom,spmi-adc-tm-hc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ "#thermal-sensor-cells":
+ const: 1
+ description:
+ Number of cells required to uniquely identify the thermal sensors. Since
+ we have multiple sensors this is set to 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ qcom,avg-samples:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of samples to be used for measurement.
+ enum:
+ - 1
+ - 2
+ - 4
+ - 8
+ - 16
+ default: 1
+
+ qcom,decimation:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: This parameter is used to decrease ADC sampling rate.
+ Quicker measurements can be made by reducing decimation ratio.
+ enum:
+ - 256
+ - 512
+ - 1024
+ default: 1024
+
+patternProperties:
+ "^([-a-z0-9]*)@[0-7]$":
+ type: object
+ description:
+ Represent one thermal sensor.
+
+ properties:
+ reg:
+ description: Specify the sensor channel. There are 8 channels in PMIC5's ADC TM
+ minimum: 0
+ maximum: 7
+
+ io-channels:
+ description:
+ From common IIO binding. Used to pipe PMIC ADC channel to thermal monitor
+
+ qcom,ratiometric:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description:
+ Channel calibration type.
+ If this property is specified VADC will use the VDD reference
+ (1.875V) and GND for channel calibration. If property is not found,
+ channel will be calibrated with 0V and 1.25V reference channels,
+ also known as absolute calibration.
+
+ qcom,hw-settle-time-us:
+ description: Time between AMUX getting configured and the ADC starting conversion.
+ enum: [0, 100, 200, 300, 400, 500, 600, 700, 1000, 2000, 4000, 6000, 8000, 10000]
+
+ qcom,pre-scaling:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: Used for scaling the channel input signal before the
+ signal is fed to VADC. The configuration for this node is to know the
+ pre-determined ratio and use it for post scaling. It is a pair of
+ integers, denoting the numerator and denominator of the fraction by
+ which input signal is multiplied. For example, <1 3> indicates the
+ signal is scaled down to 1/3 of its value before ADC measurement. If
+ property is not found default value depending on chip will be used.
+ items:
+ - const: 1
+ - enum: [ 1, 3, 4, 6, 20, 8, 10 ]
+
+ required:
+ - reg
+ - io-channels
+
+ additionalProperties:
+ false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - "#address-cells"
+ - "#size-cells"
+ - "#thermal-sensor-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/iio/qcom,spmi-vadc.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ spmi_bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pm8998_adc: adc@3100 {
+ reg = <0x3100>;
+ compatible = "qcom,spmi-adc-rev2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #io-channel-cells = <1>;
+
+ /* Other propreties are omitted */
+ adc-chan@4c {
+ reg = <ADC5_XO_THERM_100K_PU>;
+ };
+ };
+
+ pm8998_adc_tm: adc-tm@3400 {
+ compatible = "qcom,spmi-adc-tm-hc";
+ reg = <0x3400>;
+ interrupts = <0x2 0x34 0x0 IRQ_TYPE_EDGE_RISING>;
+ #thermal-sensor-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ thermistor@1 {
+ reg = <1>;
+ io-channels = <&pm8998_adc ADC5_XO_THERM_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml
index b96ea277b558..f6c1be226aaa 100644
--- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml
@@ -12,14 +12,14 @@ maintainers:
properties:
compatible:
enum:
- - rockchip,px30-tsadc # PX30 SoCs
- - rockchip,rv1108-tsadc # RV1108 SoCs
- - rockchip,rk3228-tsadc # RK3228 SoCs
- - rockchip,rk3288-tsadc # RK3288 SoCs
- - rockchip,rk3328-tsadc # RK3328 SoCs
- - rockchip,rk3368-tsadc # RK3368 SoCs
- - rockchip,rk3399-tsadc # RK3399 SoCs
- - rockchip,rk3568-tsadc # RK3568 SoCs
+ - rockchip,px30-tsadc
+ - rockchip,rk3228-tsadc
+ - rockchip,rk3288-tsadc
+ - rockchip,rk3328-tsadc
+ - rockchip,rk3368-tsadc
+ - rockchip,rk3399-tsadc
+ - rockchip,rk3568-tsadc
+ - rockchip,rv1108-tsadc
reg:
maxItems: 1
@@ -37,11 +37,15 @@ properties:
- const: apb_pclk
resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 3
reset-names:
+ minItems: 1
items:
- const: tsadc-apb
+ - const: tsadc
+ - const: tsadc-phy
"#thermal-sensor-cells":
const: 1
@@ -71,7 +75,6 @@ required:
- clocks
- clock-names
- resets
- - reset-names
- "#thermal-sensor-cells"
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml b/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml
index 553c9dcdaeeb..c5b25ce44956 100644
--- a/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml
@@ -20,6 +20,7 @@ properties:
- socionext,uniphier-pxs2-thermal
- socionext,uniphier-ld20-thermal
- socionext,uniphier-pxs3-thermal
+ - socionext,uniphier-nx1-thermal
interrupts:
maxItems: 1
diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst
index c93fa5e961a0..2e0f79a9e2ee 100644
--- a/Documentation/driver-api/thermal/sysfs-api.rst
+++ b/Documentation/driver-api/thermal/sysfs-api.rst
@@ -428,6 +428,9 @@ of thermal zone device. E.g. the generic thermal driver registers one hwmon
class device and build the associated hwmon sysfs I/F for all the registered
ACPI thermal zones.
+Please read Documentation/ABI/testing/sysfs-class-thermal for thermal
+zone and cooling device attribute details.
+
::
/sys/class/hwmon/hwmon[0-*]:
@@ -437,228 +440,6 @@ ACPI thermal zones.
Please read Documentation/hwmon/sysfs-interface.rst for additional information.
-Thermal zone attributes
------------------------
-
-type
- Strings which represent the thermal zone type.
- This is given by thermal zone driver as part of registration.
- E.g: "acpitz" indicates it's an ACPI thermal device.
- In order to keep it consistent with hwmon sys attribute; this should
- be a short, lowercase string, not containing spaces nor dashes.
- RO, Required
-
-temp
- Current temperature as reported by thermal zone (sensor).
- Unit: millidegree Celsius
- RO, Required
-
-mode
- One of the predefined values in [enabled, disabled].
- This file gives information about the algorithm that is currently
- managing the thermal zone. It can be either default kernel based
- algorithm or user space application.
-
- enabled
- enable Kernel Thermal management.
- disabled
- Preventing kernel thermal zone driver actions upon
- trip points so that user application can take full
- charge of the thermal management.
-
- RW, Optional
-
-policy
- One of the various thermal governors used for a particular zone.
-
- RW, Required
-
-available_policies
- Available thermal governors which can be used for a particular zone.
-
- RO, Required
-
-`trip_point_[0-*]_temp`
- The temperature above which trip point will be fired.
-
- Unit: millidegree Celsius
-
- RO, Optional
-
-`trip_point_[0-*]_type`
- Strings which indicate the type of the trip point.
-
- E.g. it can be one of critical, hot, passive, `active[0-*]` for ACPI
- thermal zone.
-
- RO, Optional
-
-`trip_point_[0-*]_hyst`
- The hysteresis value for a trip point, represented as an integer
- Unit: Celsius
- RW, Optional
-
-`cdev[0-*]`
- Sysfs link to the thermal cooling device node where the sys I/F
- for cooling device throttling control represents.
-
- RO, Optional
-
-`cdev[0-*]_trip_point`
- The trip point in this thermal zone which `cdev[0-*]` is associated
- with; -1 means the cooling device is not associated with any trip
- point.
-
- RO, Optional
-
-`cdev[0-*]_weight`
- The influence of `cdev[0-*]` in this thermal zone. This value
- is relative to the rest of cooling devices in the thermal
- zone. For example, if a cooling device has a weight double
- than that of other, it's twice as effective in cooling the
- thermal zone.
-
- RW, Optional
-
-emul_temp
- Interface to set the emulated temperature method in thermal zone
- (sensor). After setting this temperature, the thermal zone may pass
- this temperature to platform emulation function if registered or
- cache it locally. This is useful in debugging different temperature
- threshold and its associated cooling action. This is write only node
- and writing 0 on this node should disable emulation.
- Unit: millidegree Celsius
-
- WO, Optional
-
- WARNING:
- Be careful while enabling this option on production systems,
- because userland can easily disable the thermal policy by simply
- flooding this sysfs node with low temperature values.
-
-sustainable_power
- An estimate of the sustained power that can be dissipated by
- the thermal zone. Used by the power allocator governor. For
- more information see Documentation/driver-api/thermal/power_allocator.rst
-
- Unit: milliwatts
-
- RW, Optional
-
-k_po
- The proportional term of the power allocator governor's PID
- controller during temperature overshoot. Temperature overshoot
- is when the current temperature is above the "desired
- temperature" trip point. For more information see
- Documentation/driver-api/thermal/power_allocator.rst
-
- RW, Optional
-
-k_pu
- The proportional term of the power allocator governor's PID
- controller during temperature undershoot. Temperature undershoot
- is when the current temperature is below the "desired
- temperature" trip point. For more information see
- Documentation/driver-api/thermal/power_allocator.rst
-
- RW, Optional
-
-k_i
- The integral term of the power allocator governor's PID
- controller. This term allows the PID controller to compensate
- for long term drift. For more information see
- Documentation/driver-api/thermal/power_allocator.rst
-
- RW, Optional
-
-k_d
- The derivative term of the power allocator governor's PID
- controller. For more information see
- Documentation/driver-api/thermal/power_allocator.rst
-
- RW, Optional
-
-integral_cutoff
- Temperature offset from the desired temperature trip point
- above which the integral term of the power allocator
- governor's PID controller starts accumulating errors. For
- example, if integral_cutoff is 0, then the integral term only
- accumulates error when temperature is above the desired
- temperature trip point. For more information see
- Documentation/driver-api/thermal/power_allocator.rst
-
- Unit: millidegree Celsius
-
- RW, Optional
-
-slope
- The slope constant used in a linear extrapolation model
- to determine a hotspot temperature based off the sensor's
- raw readings. It is up to the device driver to determine
- the usage of these values.
-
- RW, Optional
-
-offset
- The offset constant used in a linear extrapolation model
- to determine a hotspot temperature based off the sensor's
- raw readings. It is up to the device driver to determine
- the usage of these values.
-
- RW, Optional
-
-Cooling device attributes
--------------------------
-
-type
- String which represents the type of device, e.g:
-
- - for generic ACPI: should be "Fan", "Processor" or "LCD"
- - for memory controller device on intel_menlow platform:
- should be "Memory controller".
-
- RO, Required
-
-max_state
- The maximum permissible cooling state of this cooling device.
-
- RO, Required
-
-cur_state
- The current cooling state of this cooling device.
- The value can any integer numbers between 0 and max_state:
-
- - cur_state == 0 means no cooling
- - cur_state == max_state means the maximum cooling.
-
- RW, Required
-
-stats/reset
- Writing any value resets the cooling device's statistics.
- WO, Required
-
-stats/time_in_state_ms:
- The amount of time spent by the cooling device in various cooling
- states. The output will have "<state> <time>" pair in each line, which
- will mean this cooling device spent <time> msec of time at <state>.
- Output will have one line for each of the supported states.
- RO, Required
-
-
-stats/total_trans:
- A single positive value showing the total number of times the state of a
- cooling device is changed.
-
- RO, Required
-
-stats/trans_table:
- This gives fine grained information about all the cooling state
- transitions. The cat output here is a two dimensional matrix, where an
- entry <i,j> (row i, column j) represents the number of transitions from
- State_i to State_j. If the transition table is bigger than PAGE_SIZE,
- reading this will return an -EFBIG error.
- RO, Required
-
3. A simple implementation
==========================
diff --git a/MAINTAINERS b/MAINTAINERS
index fe347675fb5c..16ba1cf37072 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18649,7 +18649,9 @@ L: linux-pm@vger.kernel.org
S: Supported
Q: https://patchwork.kernel.org/project/linux-pm/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
+F: Documentation/ABI/testing/sysfs-class-thermal
F: Documentation/devicetree/bindings/thermal/
+F: Documentation/driver-api/thermal/
F: drivers/thermal/
F: include/linux/cpu_cooling.h
F: include/linux/thermal.h
diff --git a/drivers/thermal/gov_user_space.c b/drivers/thermal/gov_user_space.c
index 82a7198bbe71..f4fe050e1cbc 100644
--- a/drivers/thermal/gov_user_space.c
+++ b/drivers/thermal/gov_user_space.c
@@ -15,6 +15,14 @@
#include "thermal_core.h"
+static int user_space_bind(struct thermal_zone_device *tz)
+{
+ pr_warn("Userspace governor deprecated: use thermal netlink " \
+ "notification instead\n");
+
+ return 0;
+}
+
/**
* notify_user_space - Notifies user space about thermal events
* @tz: thermal_zone_device
@@ -43,5 +51,6 @@ static int notify_user_space(struct thermal_zone_device *tz, int trip)
static struct thermal_governor thermal_gov_user_space = {
.name = "user_space",
.throttle = notify_user_space,
+ .bind_to_tz = user_space_bind,
};
THERMAL_GOVERNOR_DECLARE(thermal_gov_user_space);
diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
index 19926beeb3b7..8502b7d8df89 100644
--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
@@ -129,11 +129,10 @@ static ssize_t available_uuids_show(struct device *dev,
for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) {
if (priv->uuid_bitmap & (1 << i))
- if (PAGE_SIZE - length > 0)
- length += scnprintf(&buf[length],
- PAGE_SIZE - length,
- "%s\n",
- int3400_thermal_uuids[i]);
+ length += scnprintf(&buf[length],
+ PAGE_SIZE - length,
+ "%s\n",
+ int3400_thermal_uuids[i]);
}
return length;
diff --git a/drivers/thermal/intel/int340x_thermal/int3401_thermal.c b/drivers/thermal/intel/int340x_thermal/int3401_thermal.c
index acebc8ba94e2..217786fba185 100644
--- a/drivers/thermal/intel/int340x_thermal/int3401_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3401_thermal.c
@@ -44,15 +44,21 @@ static int int3401_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM_SLEEP
+static int int3401_thermal_suspend(struct device *dev)
+{
+ return proc_thermal_suspend(dev);
+}
static int int3401_thermal_resume(struct device *dev)
{
return proc_thermal_resume(dev);
}
#else
+#define int3401_thermal_suspend NULL
#define int3401_thermal_resume NULL
#endif
-static SIMPLE_DEV_PM_OPS(int3401_proc_thermal_pm, NULL, int3401_thermal_resume);
+static SIMPLE_DEV_PM_OPS(int3401_proc_thermal_pm, int3401_thermal_suspend,
+ int3401_thermal_resume);
static struct platform_driver int3401_driver = {
.probe = int3401_add,
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index fb64acfd5e07..a8d98f1bd6c6 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -68,8 +68,7 @@ static const struct attribute_group power_limit_attribute_group = {
.name = "power_limits"
};
-static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static int tcc_get_offset(void)
{
u64 val;
int err;
@@ -78,8 +77,20 @@ static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
if (err)
return err;
- val = (val >> 24) & 0x3f;
- return sprintf(buf, "%d\n", (int)val);
+ return (val >> 24) & 0x3f;
+}
+
+static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int tcc;
+
+ tcc = tcc_get_offset();
+ if (tcc < 0)
+ return tcc;
+
+ return sprintf(buf, "%d\n", tcc);
}
static int tcc_offset_update(unsigned int tcc)
@@ -107,8 +118,6 @@ static int tcc_offset_update(unsigned int tcc)
return 0;
}
-static int tcc_offset_save = -1;
-
static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
@@ -131,8 +140,6 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
if (err)
return err;
- tcc_offset_save = tcc;
-
return count;
}
@@ -345,6 +352,18 @@ void proc_thermal_remove(struct proc_thermal_device *proc_priv)
}
EXPORT_SYMBOL_GPL(proc_thermal_remove);
+static int tcc_offset_save = -1;
+
+int proc_thermal_suspend(struct device *dev)
+{
+ tcc_offset_save = tcc_get_offset();
+ if (tcc_offset_save < 0)
+ dev_warn(dev, "failed to save offset (%d)\n", tcc_offset_save);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(proc_thermal_suspend);
+
int proc_thermal_resume(struct device *dev)
{
struct proc_thermal_device *proc_dev;
@@ -352,6 +371,7 @@ int proc_thermal_resume(struct device *dev)
proc_dev = dev_get_drvdata(dev);
proc_thermal_read_ppcc(proc_dev);
+ /* Do not update if saving failed */
if (tcc_offset_save >= 0)
tcc_offset_update(tcc_offset_save);
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
index 5a1cfe4864f1..c1d8de6dc3d1 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
@@ -83,6 +83,7 @@ void proc_thermal_mbox_remove(struct pci_dev *pdev);
int processor_thermal_send_mbox_cmd(struct pci_dev *pdev, u16 cmd_id, u32 cmd_data, u32 *cmd_resp);
int proc_thermal_add(struct device *dev, struct proc_thermal_device *priv);
void proc_thermal_remove(struct proc_thermal_device *proc_priv);
+int proc_thermal_suspend(struct device *dev);
int proc_thermal_resume(struct device *dev);
int proc_thermal_mmio_add(struct pci_dev *pdev,
struct proc_thermal_device *proc_priv,
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
index 11dd2e825f4f..b4bcd3fe9eb2 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -314,6 +314,20 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM_SLEEP
+static int proc_thermal_pci_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct proc_thermal_device *proc_priv;
+ struct proc_thermal_pci *pci_info;
+
+ proc_priv = pci_get_drvdata(pdev);
+ pci_info = proc_priv->priv_data;
+
+ if (!pci_info->no_legacy)
+ return proc_thermal_suspend(dev);
+
+ return 0;
+}
static int proc_thermal_pci_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -335,10 +349,12 @@ static int proc_thermal_pci_resume(struct device *dev)
return 0;
}
#else
+#define proc_thermal_pci_suspend NULL
#define proc_thermal_pci_resume NULL
#endif
-static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, NULL, proc_thermal_pci_resume);
+static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
+ proc_thermal_pci_resume);
static const struct pci_device_id proc_thermal_pci_ids[] = {
{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
index f5fc1791b11e..4571a1a53b84 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
@@ -107,15 +107,21 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM_SLEEP
+static int proc_thermal_pci_suspend(struct device *dev)
+{
+ return proc_thermal_suspend(dev);
+}
static int proc_thermal_pci_resume(struct device *dev)
{
return proc_thermal_resume(dev);
}
#else
+#define proc_thermal_pci_suspend NULL
#define proc_thermal_pci_resume NULL
#endif
-static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, NULL, proc_thermal_pci_resume);
+static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
+ proc_thermal_pci_resume);
static const struct pci_device_id proc_thermal_pci_ids[] = {
{ PCI_DEVICE_DATA(INTEL, BDW_THERMAL, 0) },
diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
index a5b58ea89cc6..9b68489a2356 100644
--- a/drivers/thermal/intel/intel_powerclamp.c
+++ b/drivers/thermal/intel/intel_powerclamp.c
@@ -705,10 +705,8 @@ static enum cpuhp_state hp_state;
static int __init powerclamp_init(void)
{
int retval;
- int bitmap_size;
- bitmap_size = BITS_TO_LONGS(num_possible_cpus()) * sizeof(long);
- cpu_clamping_mask = kzalloc(bitmap_size, GFP_KERNEL);
+ cpu_clamping_mask = bitmap_zalloc(num_possible_cpus(), GFP_KERNEL);
if (!cpu_clamping_mask)
return -ENOMEM;
@@ -753,7 +751,7 @@ exit_free_thread:
exit_unregister:
cpuhp_remove_state_nocalls(hp_state);
exit_free:
- kfree(cpu_clamping_mask);
+ bitmap_free(cpu_clamping_mask);
return retval;
}
module_init(powerclamp_init);
@@ -764,7 +762,7 @@ static void __exit powerclamp_exit(void)
cpuhp_remove_state_nocalls(hp_state);
free_percpu(worker_data);
thermal_cooling_device_unregister(cooling_dev);
- kfree(cpu_clamping_mask);
+ bitmap_free(cpu_clamping_mask);
cancel_delayed_work_sync(&poll_pkg_cstate_work);
debugfs_remove_recursive(debug_dir);
diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig
index 7d942f71e532..bfd889422dd3 100644
--- a/drivers/thermal/qcom/Kconfig
+++ b/drivers/thermal/qcom/Kconfig
@@ -34,7 +34,7 @@ config QCOM_SPMI_TEMP_ALARM
config QCOM_LMH
tristate "Qualcomm Limits Management Hardware"
- depends on ARCH_QCOM
+ depends on ARCH_QCOM && QCOM_SCM
help
This enables initialization of Qualcomm limits management
hardware(LMh). LMh allows for hardware-enforced mitigation for cpus based on
diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
index 8494cc04aa21..824671cf494a 100644
--- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
+++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
@@ -82,6 +82,7 @@ struct adc_tm5_data {
const u32 full_scale_code_volt;
unsigned int *decimation;
unsigned int *hw_settle;
+ bool is_hc;
};
enum adc_tm5_cal_method {
@@ -146,6 +147,14 @@ static const struct adc_tm5_data adc_tm5_data_pmic = {
64000, 128000 },
};
+static const struct adc_tm5_data adc_tm_hc_data_pmic = {
+ .full_scale_code_volt = 0x70e4,
+ .decimation = (unsigned int []) { 256, 512, 1024 },
+ .hw_settle = (unsigned int []) { 0, 100, 200, 300, 400, 500, 600, 700,
+ 1000, 2000, 4000, 6000, 8000, 10000 },
+ .is_hc = true,
+};
+
static int adc_tm5_read(struct adc_tm5_chip *adc_tm, u16 offset, u8 *data, int len)
{
return regmap_bulk_read(adc_tm->regmap, adc_tm->base + offset, data, len);
@@ -375,6 +384,29 @@ static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm)
return 0;
}
+static int adc_tm_hc_init(struct adc_tm5_chip *chip)
+{
+ unsigned int i;
+ u8 buf[2];
+ int ret;
+
+ for (i = 0; i < chip->nchannels; i++) {
+ if (chip->channels[i].channel >= ADC_TM5_NUM_CHANNELS) {
+ dev_err(chip->dev, "Invalid channel %d\n", chip->channels[i].channel);
+ return -EINVAL;
+ }
+ }
+
+ buf[0] = chip->decimation;
+ buf[1] = chip->avg_samples | ADC_TM5_FAST_AVG_EN;
+
+ ret = adc_tm5_write(chip, ADC_TM5_ADC_DIG_PARAM, buf, sizeof(buf));
+ if (ret)
+ dev_err(chip->dev, "block write failed: %d\n", ret);
+
+ return ret;
+}
+
static int adc_tm5_init(struct adc_tm5_chip *chip)
{
u8 buf[4], channels_available;
@@ -591,7 +623,10 @@ static int adc_tm5_probe(struct platform_device *pdev)
return ret;
}
- ret = adc_tm5_init(adc_tm);
+ if (adc_tm->data->is_hc)
+ ret = adc_tm_hc_init(adc_tm);
+ else
+ ret = adc_tm5_init(adc_tm);
if (ret) {
dev_err(dev, "adc-tm init failed\n");
return ret;
@@ -612,6 +647,10 @@ static const struct of_device_id adc_tm5_match_table[] = {
.compatible = "qcom,spmi-adc-tm5",
.data = &adc_tm5_data_pmic,
},
+ {
+ .compatible = "qcom,spmi-adc-tm-hc",
+ .data = &adc_tm_hc_data_pmic,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, adc_tm5_match_table);
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index b1162e566a70..99a8d9f3e03c 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -603,22 +603,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
int ret;
/* VER_0 doesn't have VALID bit */
- if (tsens_version(priv) >= VER_0_1) {
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- while (!valid) {
- /* Valid bit is 0 for 6 AHB clock cycles.
- * At 19.2MHz, 1 AHB clock is ~60ns.
- * We should enter this loop very, very rarely.
- */
- ndelay(400);
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- }
- }
+ if (tsens_version(priv) == VER_0)
+ goto get_temp;
+
+ /* Valid bit is 0 for 6 AHB clock cycles.
+ * At 19.2MHz, 1 AHB clock is ~60ns.
+ * We should enter this loop very, very rarely.
+ * Wait 1 us since it's the min of poll_timeout macro.
+ * Old value was 400 ns.
+ */
+ ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid,
+ valid, 1, 20 * USEC_PER_MSEC);
+ if (ret)
+ return ret;
+get_temp:
/* Valid bit is set, OK to read the temperature */
*temp = tsens_hw_to_mC(s, temp_idx);
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 85228d308dd3..43eb25b167bc 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -34,6 +34,10 @@
#define REG_GEN3_THCODE1 0x50
#define REG_GEN3_THCODE2 0x54
#define REG_GEN3_THCODE3 0x58
+#define REG_GEN3_PTAT1 0x5c
+#define REG_GEN3_PTAT2 0x60
+#define REG_GEN3_PTAT3 0x64
+#define REG_GEN3_THSCP 0x68
/* IRQ{STR,MSK,EN} bits */
#define IRQ_TEMP1 BIT(0)
@@ -55,6 +59,9 @@
#define THCTR_PONM BIT(6)
#define THCTR_THSST BIT(0)
+/* THSCP bits */
+#define THSCP_COR_PARA_VLD (BIT(15) | BIT(14))
+
#define CTEMP_MASK 0xFFF
#define MCELSIUS(temp) ((temp) * 1000)
@@ -62,15 +69,6 @@
#define TSC_MAX_NUM 5
-/* default THCODE values if FUSEs are missing */
-static const int thcodes[TSC_MAX_NUM][3] = {
- { 3397, 2800, 2221 },
- { 3393, 2795, 2216 },
- { 3389, 2805, 2237 },
- { 3415, 2694, 2195 },
- { 3356, 2724, 2244 },
-};
-
/* Structure for thermal temperature calculation */
struct equation_coefs {
int a1;
@@ -84,13 +82,14 @@ struct rcar_gen3_thermal_tsc {
struct thermal_zone_device *zone;
struct equation_coefs coef;
int tj_t;
- unsigned int id; /* thermal channel id */
+ int thcode[3];
};
struct rcar_gen3_thermal_priv {
struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
unsigned int num_tscs;
void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc);
+ int ptat[3];
};
static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc,
@@ -133,8 +132,8 @@ static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
/* no idea where these constants come from */
#define TJ_3 -41
-static void rcar_gen3_thermal_calc_coefs(struct rcar_gen3_thermal_tsc *tsc,
- int *ptat, const int *thcode,
+static void rcar_gen3_thermal_calc_coefs(struct rcar_gen3_thermal_priv *priv,
+ struct rcar_gen3_thermal_tsc *tsc,
int ths_tj_1)
{
/* TODO: Find documentation and document constant calculation formula */
@@ -143,16 +142,16 @@ static void rcar_gen3_thermal_calc_coefs(struct rcar_gen3_thermal_tsc *tsc,
* Division is not scaled in BSP and if scaled it might overflow
* the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
*/
- tsc->tj_t = (FIXPT_INT((ptat[1] - ptat[2]) * (ths_tj_1 - TJ_3))
- / (ptat[0] - ptat[2])) + FIXPT_INT(TJ_3);
+ tsc->tj_t = (FIXPT_INT((priv->ptat[1] - priv->ptat[2]) * (ths_tj_1 - TJ_3))
+ / (priv->ptat[0] - priv->ptat[2])) + FIXPT_INT(TJ_3);
- tsc->coef.a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]),
+ tsc->coef.a1 = FIXPT_DIV(FIXPT_INT(tsc->thcode[1] - tsc->thcode[2]),
tsc->tj_t - FIXPT_INT(TJ_3));
- tsc->coef.b1 = FIXPT_INT(thcode[2]) - tsc->coef.a1 * TJ_3;
+ tsc->coef.b1 = FIXPT_INT(tsc->thcode[2]) - tsc->coef.a1 * TJ_3;
- tsc->coef.a2 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[0]),
+ tsc->coef.a2 = FIXPT_DIV(FIXPT_INT(tsc->thcode[1] - tsc->thcode[0]),
tsc->tj_t - FIXPT_INT(ths_tj_1));
- tsc->coef.b2 = FIXPT_INT(thcode[0]) - tsc->coef.a2 * ths_tj_1;
+ tsc->coef.b2 = FIXPT_INT(tsc->thcode[0]) - tsc->coef.a2 * ths_tj_1;
}
static int rcar_gen3_thermal_round(int temp)
@@ -174,7 +173,7 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
/* Read register and convert to mili Celsius */
reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK;
- if (reg <= thcodes[tsc->id][1])
+ if (reg <= tsc->thcode[1])
val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1,
tsc->coef.a1);
else
@@ -253,6 +252,64 @@ static const struct soc_device_attribute r8a7795es1[] = {
{ /* sentinel */ }
};
+static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
+{
+ unsigned int i;
+ u32 thscp;
+
+ /* If fuses are not set, fallback to pseudo values. */
+ thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP);
+ if ((thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) {
+ /* Default THCODE values in case FUSEs are not set. */
+ static const int thcodes[TSC_MAX_NUM][3] = {
+ { 3397, 2800, 2221 },
+ { 3393, 2795, 2216 },
+ { 3389, 2805, 2237 },
+ { 3415, 2694, 2195 },
+ { 3356, 2724, 2244 },
+ };
+
+ priv->ptat[0] = 2631;
+ priv->ptat[1] = 1509;
+ priv->ptat[2] = 435;
+
+ for (i = 0; i < priv->num_tscs; i++) {
+ struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
+
+ tsc->thcode[0] = thcodes[i][0];
+ tsc->thcode[1] = thcodes[i][1];
+ tsc->thcode[2] = thcodes[i][2];
+ }
+
+ return false;
+ }
+
+ /*
+ * Set the pseudo calibration points with fused values.
+ * PTAT is shared between all TSCs but only fused for the first
+ * TSC while THCODEs are fused for each TSC.
+ */
+ priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
+ GEN3_FUSE_MASK;
+ priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
+ GEN3_FUSE_MASK;
+ priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
+ GEN3_FUSE_MASK;
+
+ for (i = 0; i < priv->num_tscs; i++) {
+ struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
+
+ tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
+ GEN3_FUSE_MASK;
+ tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
+ GEN3_FUSE_MASK;
+ tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
+ GEN3_FUSE_MASK;
+ }
+
+ return true;
+}
+
static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc)
{
rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR);
@@ -401,10 +458,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
unsigned int i;
int ret;
- /* default values if FUSEs are missing */
- /* TODO: Read values from hardware on supported platforms */
- int ptat[3] = { 2631, 1509, 435 };
-
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -439,9 +492,17 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(tsc->base);
goto error_unregister;
}
- tsc->id = i;
priv->tscs[i] = tsc;
+ }
+
+ priv->num_tscs = i;
+
+ if (!rcar_gen3_thermal_read_fuses(priv))
+ dev_info(dev, "No calibration values fused, fallback to driver values\n");
+
+ for (i = 0; i < priv->num_tscs; i++) {
+ struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
&rcar_gen3_tz_of_ops);
@@ -453,7 +514,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
tsc->zone = zone;
priv->thermal_init(tsc);
- rcar_gen3_thermal_calc_coefs(tsc, ptat, thcodes[i], *ths_tj_1);
+ rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1);
tsc->zone->tzp->no_hwmon = false;
ret = thermal_add_hwmon_sysfs(tsc->zone);
@@ -471,8 +532,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
dev_info(dev, "TSC%u: Loaded %d trip points\n", i, ret);
}
- priv->num_tscs = i;
-
if (!priv->num_tscs) {
ret = -ENODEV;
goto error_unregister;
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 657d84b9963e..dc3a9c276a09 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1383,7 +1383,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
if (IS_ERR(thermal->regs))
return PTR_ERR(thermal->regs);
- thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb");
+ thermal->reset = devm_reset_control_array_get(&pdev->dev, false, false);
if (IS_ERR(thermal->reset)) {
error = PTR_ERR(thermal->reset);
dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error);
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 51374f4e1cca..648829ab79ff 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -375,10 +375,12 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
if (tz->last_temperature != THERMAL_TEMP_INVALID) {
if (tz->last_temperature < trip_temp &&
tz->temperature >= trip_temp)
- thermal_notify_tz_trip_up(tz->id, trip);
+ thermal_notify_tz_trip_up(tz->id, trip,
+ tz->temperature);
if (tz->last_temperature >= trip_temp &&
tz->temperature < (trip_temp - hyst))
- thermal_notify_tz_trip_down(tz->id, trip);
+ thermal_notify_tz_trip_down(tz->id, trip,
+ tz->temperature);
}
if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
@@ -887,7 +889,7 @@ __thermal_cooling_device_register(struct device_node *np,
{
struct thermal_cooling_device *cdev;
struct thermal_zone_device *pos = NULL;
- int ret;
+ int id, ret;
if (!ops || !ops->get_max_state || !ops->get_cur_state ||
!ops->set_cur_state)
@@ -901,6 +903,11 @@ __thermal_cooling_device_register(struct device_node *np,
if (ret < 0)
goto out_kfree_cdev;
cdev->id = ret;
+ id = ret;
+
+ ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
+ if (ret)
+ goto out_ida_remove;
cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
if (!cdev->type) {
@@ -916,7 +923,6 @@ __thermal_cooling_device_register(struct device_node *np,
cdev->device.class = &thermal_class;
cdev->devdata = devdata;
thermal_cooling_device_setup_sysfs(cdev);
- dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
ret = device_register(&cdev->device);
if (ret)
goto out_kfree_type;
@@ -941,8 +947,9 @@ __thermal_cooling_device_register(struct device_node *np,
out_kfree_type:
kfree(cdev->type);
put_device(&cdev->device);
+ cdev = NULL;
out_ida_remove:
- ida_simple_remove(&thermal_cdev_ida, cdev->id);
+ ida_simple_remove(&thermal_cdev_ida, id);
out_kfree_cdev:
kfree(cdev);
return ERR_PTR(ret);
@@ -1227,6 +1234,10 @@ thermal_zone_device_register(const char *type, int trips, int mask,
tz->id = id;
strlcpy(tz->type, type, sizeof(tz->type));
+ result = dev_set_name(&tz->device, "thermal_zone%d", tz->id);
+ if (result)
+ goto remove_id;
+
if (!ops->critical)
ops->critical = thermal_zone_device_critical;
@@ -1248,7 +1259,6 @@ thermal_zone_device_register(const char *type, int trips, int mask,
/* A new thermal zone needs to be updated anyway. */
atomic_set(&tz->need_update, 1);
- dev_set_name(&tz->device, "thermal_zone%d", tz->id);
result = device_register(&tz->device);
if (result)
goto release_device;
diff --git a/drivers/thermal/thermal_mmio.c b/drivers/thermal/thermal_mmio.c
index ded1dd0d4ef7..360b0dfdc3b0 100644
--- a/drivers/thermal/thermal_mmio.c
+++ b/drivers/thermal/thermal_mmio.c
@@ -34,7 +34,7 @@ static int thermal_mmio_get_temperature(void *private, int *temp)
return 0;
}
-static struct thermal_zone_of_device_ops thermal_mmio_ops = {
+static const struct thermal_zone_of_device_ops thermal_mmio_ops = {
.get_temp = thermal_mmio_get_temperature,
};
diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c
index 1234dbe95895..a16dd4d5d710 100644
--- a/drivers/thermal/thermal_netlink.c
+++ b/drivers/thermal/thermal_netlink.c
@@ -121,7 +121,8 @@ static int thermal_genl_event_tz(struct param *p)
static int thermal_genl_event_tz_trip_up(struct param *p)
{
if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
- nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, p->trip_id))
+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, p->trip_id) ||
+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TEMP, p->temp))
return -EMSGSIZE;
return 0;
@@ -285,16 +286,16 @@ int thermal_notify_tz_disable(int tz_id)
return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_DISABLE, &p);
}
-int thermal_notify_tz_trip_down(int tz_id, int trip_id)
+int thermal_notify_tz_trip_down(int tz_id, int trip_id, int temp)
{
- struct param p = { .tz_id = tz_id, .trip_id = trip_id };
+ struct param p = { .tz_id = tz_id, .trip_id = trip_id, .temp = temp };
return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_DOWN, &p);
}
-int thermal_notify_tz_trip_up(int tz_id, int trip_id)
+int thermal_notify_tz_trip_up(int tz_id, int trip_id, int temp)
{
- struct param p = { .tz_id = tz_id, .trip_id = trip_id };
+ struct param p = { .tz_id = tz_id, .trip_id = trip_id, .temp = temp };
return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_UP, &p);
}
diff --git a/drivers/thermal/thermal_netlink.h b/drivers/thermal/thermal_netlink.h
index 828d1dddfa98..e554f76291f4 100644
--- a/drivers/thermal/thermal_netlink.h
+++ b/drivers/thermal/thermal_netlink.h
@@ -11,8 +11,8 @@ int thermal_notify_tz_create(int tz_id, const char *name);
int thermal_notify_tz_delete(int tz_id);
int thermal_notify_tz_enable(int tz_id);
int thermal_notify_tz_disable(int tz_id);
-int thermal_notify_tz_trip_down(int tz_id, int id);
-int thermal_notify_tz_trip_up(int tz_id, int id);
+int thermal_notify_tz_trip_down(int tz_id, int id, int temp);
+int thermal_notify_tz_trip_up(int tz_id, int id, int temp);
int thermal_notify_tz_trip_delete(int tz_id, int id);
int thermal_notify_tz_trip_add(int tz_id, int id, int type,
int temp, int hyst);
@@ -49,12 +49,12 @@ static inline int thermal_notify_tz_disable(int tz_id)
return 0;
}
-static inline int thermal_notify_tz_trip_down(int tz_id, int id)
+static inline int thermal_notify_tz_trip_down(int tz_id, int id, int temp)
{
return 0;
}
-static inline int thermal_notify_tz_trip_up(int tz_id, int id)
+static inline int thermal_notify_tz_trip_up(int tz_id, int id, int temp)
{
return 0;
}
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 1c4aac8464a7..f154bada2906 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -610,6 +610,9 @@ cur_state_store(struct device *dev, struct device_attribute *attr,
unsigned long state;
int result;
+ dev_warn_once(&cdev->device,
+ "Setting cooling device state is deprecated\n");
+
if (sscanf(buf, "%ld\n", &state) != 1)
return -EINVAL;
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index bba2284412d3..4cae5561a2a3 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -358,6 +358,10 @@ static const struct of_device_id uniphier_tm_dt_ids[] = {
.compatible = "socionext,uniphier-pxs3-thermal",
.data = &uniphier_ld20_tm_data,
},
+ {
+ .compatible = "socionext,uniphier-nx1-thermal",
+ .data = &uniphier_ld20_tm_data,
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_tm_dt_ids);