diff options
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); |