Commit 96e3f3c1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'thermal-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux

Pull thermal updates from Daniel Lezcano:

 - Add support to enable/disable the thermal zones resulting on core
   code and drivers cleanup (Andrzej Pietrasiewicz)

 - Add generic netlink support for userspace notifications: events,
   temperature and discovery commands (Daniel Lezcano)

 - Fix redundant initialization for a ret variable (Colin Ian King)

 - Remove the clock cooling code as it is used nowhere (Amit Kucheria)

 - Add the rcar_gen3_thermal's r8a774e1 support (Marian-Cristian
   Rotariu)

 - Replace all references to thermal.txt in the documentation to the
   corresponding yaml files (Amit Kucheria)

 - Add maintainer entry for the IPA (Lukasz Luba)

 - Add support for MSM8939 for the tsens (Shawn Guo)

 - Update power allocator and devfreq cooling to SPDX licensing (Lukasz
   Luba)

 - Add Cannon Lake Low Power PCH support (Sumeet Pawnikar)

 - Add tsensor support for V2 mediatek thermal system (Henry Yen)

 - Fix thermal zone lookup by ID for the core code (Thierry Reding)

* tag 'thermal-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (40 commits)
  thermal: intel: intel_pch_thermal: Add Cannon Lake Low Power PCH support
  thermal: mediatek: Add tsensor support for V2 thermal system
  thermal: mediatek: Prepare to add support for other platforms
  thermal: Update power allocator and devfreq cooling to SPDX licensing
  MAINTAINERS: update entry to thermal governors file name prefixing
  thermal: core: Add thermal zone enable/disable notification
  thermal: qcom: tsens-v0_1: Add support for MSM8939
  dt-bindings: tsens: qcom: Document MSM8939 compatible
  thermal: core: Fix thermal zone lookup by ID
  thermal: int340x: processor_thermal: fix: update Jasper Lake PCI id
  thermal: imx8mm: Support module autoloading
  thermal: ti-soc-thermal: Fix reversed condition in ti_thermal_expose_sensor()
  MAINTAINERS: Add maintenance information for IPA
  thermal: rcar_gen3_thermal: Do not shadow thcode variable
  dt-bindings: thermal: Get rid of thermal.txt and replace references
  thermal: core: Move initialization after core initcall
  thermal: netlink: Improve the initcall ordering
  net: genetlink: Move initialization to core_initcall
  thermal: rcar_gen3_thermal: Add r8a774e1 support
  thermal/drivers/clock_cooling: Remove clock_cooling code
  ...
parents ed358326 c569e805
......@@ -102,7 +102,7 @@ Required sub-node properties:
[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/power/power-domain.yaml
[3] Documentation/devicetree/bindings/thermal/thermal.txt
[3] Documentation/devicetree/bindings/thermal/thermal*.yaml
[4] Documentation/devicetree/bindings/sram/sram.yaml
[5] Documentation/devicetree/bindings/reset/reset.txt
......
......@@ -108,7 +108,7 @@ Required properties:
[0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/thermal/thermal.txt
[2] Documentation/devicetree/bindings/thermal/thermal*.yaml
[3] Documentation/devicetree/bindings/sram/sram.yaml
[4] Documentation/devicetree/bindings/power/power-domain.yaml
......
......@@ -176,7 +176,7 @@ Required properties:
"fsl,imx8qxp-sc-thermal"
followed by "fsl,imx-sc-thermal";
- #thermal-sensor-cells: See Documentation/devicetree/bindings/thermal/thermal.txt
- #thermal-sensor-cells: See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml
for a description.
Example (imx8qxp):
......
......@@ -111,7 +111,7 @@ Thermal:
--------
For common binding part and usage, refer to
Documentation/devicetree/bindings/thermal/thermal.txt
Documentation/devicetree/bindings/thermal/thermal*.yaml
The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor.
......
......@@ -203,7 +203,7 @@ It is possible to setup an overheat interrupt by giving at least one
critical point to any subnode of the thermal-zone node.
For common binding part and usage, refer to
Documentation/devicetree/bindings/thermal/thermal.txt
Documentation/devicetree/bindings/thermal/thermal*.yaml
Required properties:
- compatible: must be one of:
......
......@@ -18,7 +18,8 @@ Optional properties:
in unit of nanoseconds.
- voltage-tolerance: Specify the CPU voltage tolerance in percentage.
- #cooling-cells:
Please refer to Documentation/devicetree/bindings/thermal/thermal.txt.
Please refer to
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml.
Examples:
......
......@@ -21,8 +21,8 @@ Optional properties:
flow is handled by hardware, hence no software "voltage tracking" is
needed.
- #cooling-cells:
Please refer to Documentation/devicetree/bindings/thermal/thermal.txt
for detail.
For details, please refer to
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
Example 1 (MT7623 SoC):
......
......@@ -5,7 +5,7 @@ Required properties:
- clocks: Must contain an entry for the CPU clock.
See ../clocks/clock-bindings.txt for details.
- operating-points-v2: See ../bindings/opp/opp.txt for details.
- #cooling-cells: Should be 2. See ../thermal/thermal.txt for details.
- #cooling-cells: Should be 2. See ../thermal/thermal-cooling-devices.yaml for details.
For each opp entry in 'operating-points-v2' table:
- opp-supported-hw: Two bitfields indicating:
......
......@@ -12,7 +12,8 @@ Optional properties:
- alarm-gpios: This pin going active indicates something is wrong with
the fan, and a udev event will be fired.
- #cooling-cells: If used as a cooling device, must be <2>
Also see: Documentation/devicetree/bindings/thermal/thermal.txt
Also see:
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
min and max states are derived from the speed-map of the fan.
Note: At least one the "gpios" or "alarm-gpios" properties must be set.
......
......@@ -34,8 +34,8 @@ Optional properties:
LM90 "-ALERT" pin output.
See interrupt-controller/interrupts.txt for the format.
- #thermal-sensor-cells: should be set to 1. See thermal/thermal.txt for
details. See <include/dt-bindings/thermal/lm90.h> for the
- #thermal-sensor-cells: should be set to 1. See thermal/thermal-sensor.yaml
for details. See <include/dt-bindings/thermal/lm90.h> for the
definition of the local, remote and 2nd remote sensor index
constants.
......
......@@ -50,7 +50,7 @@ properties:
nvmem-cell-names:
const: calibration
# See ./thermal.txt for details
# See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details
"#thermal-sensor-cells":
enum:
- 0
......
......@@ -6,7 +6,7 @@ transaction.
Required properties:
- compatible: "amazon,al-thermal".
- reg: The physical base address and length of the sensor's registers.
- #thermal-sensor-cells: Must be 1. See ./thermal.txt for a description.
- #thermal-sensor-cells: Must be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
Example:
thermal: thermal {
......
......@@ -23,7 +23,7 @@ properties:
compatible:
const: brcm,bcm2711-thermal
# See ./thermal.txt for details
# See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details
"#thermal-sensor-cells":
const: 0
......
......@@ -7,7 +7,7 @@ compatible: should be one of: "brcm,bcm2835-thermal",
"brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
reg: Address range of the thermal registers.
clocks: Phandle of the clock used by the thermal sensor.
#thermal-sensor-cells: should be 0 (see thermal.txt)
#thermal-sensor-cells: should be 0 (see Documentation/devicetree/bindings/thermal/thermal-sensor.yaml)
Example:
......
......@@ -9,7 +9,7 @@
by /SOCTHERM/tsensor.
- clock-names: Input clock name, should be 'thermal_clk'.
- clocks: phandles for clock specified in "clock-names" property.
- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description.
- #thermal-sensor-cells: Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
Example :
......
......@@ -8,12 +8,12 @@ below threshold level.
Required properties:
-------------------
#thermal-sensor-cells: Please refer <devicetree/bindings/thermal/thermal.txt>
for more details.
#thermal-sensor-cells: For more details, please refer to
<devicetree/bindings/thermal/thermal-sensor.yaml>
The value must be 0.
For more details, please refer generic thermal DT binding document
<devicetree/bindings/thermal/thermal.txt>.
<devicetree/bindings/thermal/thermal*.yaml>.
Please refer <devicetree/bindings/mfd/max77620.txt> for mfd DT binding
document for the MAX77620.
......
......@@ -23,7 +23,7 @@ Required properties:
- resets: Reference to the reset controller controlling the thermal controller.
- mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses
- mediatek,apmixedsys: A phandle to the APMIXEDSYS controller.
- #thermal-sensor-cells : Should be 0. See ./thermal.txt for a description.
- #thermal-sensor-cells : Should be 0. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
Optional properties:
- nvmem-cells: A phandle to the calibration data provided by a nvmem device. If
......
......@@ -28,9 +28,10 @@ Required properties :
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- soctherm
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description
of this property. See <dt-bindings/thermal/tegra124-soctherm.h> for a
list of valid values when referring to thermal sensors.
- #thermal-sensor-cells : Should be 1. For a description of this property, see
Documentation/devicetree/bindings/thermal/thermal-sensor.yaml.
See <dt-bindings/thermal/tegra124-soctherm.h> for a list of valid values
when referring to thermal sensors.
- throttle-cfgs: A sub-node which is a container of configuration for each
hardware throttle events. These events can be set as cooling devices.
* throttle events: Sub-nodes must be named as "light" or "heavy".
......@@ -62,7 +63,8 @@ Required properties :
TEGRA_SOCTHERM_THROT_LEVEL_MED (75%),
TEGRA_SOCTHERM_THROT_LEVEL_HIGH (85%).
- #cooling-cells: Should be 1. This cooling device only support on/off state.
See ./thermal.txt for a description of this property.
For a description of this property see:
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
Optional properties: The following properties are T210 specific and
valid only for OCx throttle events.
......
......@@ -8,7 +8,7 @@ exposed by BPMP.
The BPMP thermal node must be located directly inside the main BPMP node. See
../firmware/nvidia,tegra186-bpmp.txt for details of the BPMP binding.
This node represents a thermal sensor. See thermal.txt for details of the
This node represents a thermal sensor. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details of the
core thermal binding.
Required properties:
......
......@@ -8,7 +8,7 @@ Required properties:
- compatible: Should contain "qcom,spmi-temp-alarm".
- reg: Specifies the SPMI address.
- interrupts: PMIC temperature alarm interrupt.
- #thermal-sensor-cells: Should be 0. See thermal.txt for a description.
- #thermal-sensor-cells: Should be 0. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
Optional properties:
- io-channels: Should contain IIO channel specifier for the ADC channel,
......
......@@ -23,6 +23,7 @@ properties:
items:
- enum:
- qcom,msm8916-tsens
- qcom,msm8939-tsens
- qcom,msm8974-tsens
- const: qcom,tsens-v0_1
......
......@@ -24,7 +24,7 @@ Required properties:
- pinctrl-1 : The "default" pinctrl state, it will be set after reset the
TSADC controller.
- pinctrl-2 : The "sleep" pinctrl state, it will be in for suspend.
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
- #thermal-sensor-cells : Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
Optional properties:
- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
......
......@@ -4,7 +4,7 @@ The SMP8758 SoC includes 3 instances of this temperature sensor
(in the CPU, video decoder, and PCIe controller).
Required properties:
- #thermal-sensor-cells: Should be 0 (see thermal.txt)
- #thermal-sensor-cells: Should be 0 (see Documentation/devicetree/bindings/thermal/thermal-sensor.yaml)
- compatible: "sigma,smp8758-thermal"
- reg: Address range of the thermal registers
......
......@@ -8,7 +8,7 @@ temperature using voltage-temperature lookup table.
Required properties:
===================
- compatible: Must be "generic-adc-thermal".
- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description
- #thermal-sensor-cells: Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description
of this property.
Optional properties:
===================
......
This diff is collapsed.
......@@ -17086,6 +17086,14 @@ F: drivers/thermal/cpufreq_cooling.c
F: drivers/thermal/cpuidle_cooling.c
F: include/linux/cpu_cooling.h
THERMAL/POWER_ALLOCATOR
M: Lukasz Luba <lukasz.luba@arm.com>
L: linux-pm@vger.kernel.org
S: Maintained
F: Documentation/driver-api/thermal/power_allocator.rst
F: drivers/thermal/gov_power_allocator.c
F: include/trace/events/thermal_power_allocator.h
THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net
......
......@@ -172,7 +172,6 @@ struct acpi_thermal {
struct acpi_thermal_trips trips;
struct acpi_handle_list devices;
struct thermal_zone_device *thermal_zone;
int tz_enabled;
int kelvin_offset; /* in millidegrees */
struct work_struct thermal_check_work;
};
......@@ -500,9 +499,6 @@ static void acpi_thermal_check(void *data)
{
struct acpi_thermal *tz = data;
if (!tz->tz_enabled)
return;
thermal_zone_device_update(tz->thermal_zone,
THERMAL_EVENT_UNSPECIFIED);
}
......@@ -526,50 +522,6 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp)
return 0;
}
static int thermal_get_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode *mode)
{
struct acpi_thermal *tz = thermal->devdata;
if (!tz)
return -EINVAL;
*mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
THERMAL_DEVICE_DISABLED;
return 0;
}
static int thermal_set_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode mode)
{
struct acpi_thermal *tz = thermal->devdata;
int enable;
if (!tz)
return -EINVAL;
/*
* enable/disable thermal management from ACPI thermal driver
*/
if (mode == THERMAL_DEVICE_ENABLED)
enable = 1;
else if (mode == THERMAL_DEVICE_DISABLED) {
enable = 0;
pr_warn("thermal zone will be disabled\n");
} else
return -EINVAL;
if (enable != tz->tz_enabled) {
tz->tz_enabled = enable;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"%s kernel ACPI thermal control\n",
tz->tz_enabled ? "Enable" : "Disable"));
acpi_thermal_check(tz);
}
return 0;
}
static int thermal_get_trip_type(struct thermal_zone_device *thermal,
int trip, enum thermal_trip_type *type)
{
......@@ -856,8 +808,6 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
.bind = acpi_thermal_bind_cooling_device,
.unbind = acpi_thermal_unbind_cooling_device,
.get_temp = thermal_get_temp,
.get_mode = thermal_get_mode,
.set_mode = thermal_set_mode,
.get_trip_type = thermal_get_trip_type,
.get_trip_temp = thermal_get_trip_temp,
.get_crit_temp = thermal_get_crit_temp,
......@@ -901,23 +851,39 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
result = sysfs_create_link(&tz->device->dev.kobj,
&tz->thermal_zone->device.kobj, "thermal_zone");
if (result)
return result;
goto unregister_tzd;
result = sysfs_create_link(&tz->thermal_zone->device.kobj,
&tz->device->dev.kobj, "device");
if (result)
return result;
goto remove_tz_link;
status = acpi_bus_attach_private_data(tz->device->handle,
tz->thermal_zone);
if (ACPI_FAILURE(status))
return -ENODEV;
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto remove_dev_link;
}
tz->tz_enabled = 1;
result = thermal_zone_device_enable(tz->thermal_zone);
if (result)
goto acpi_bus_detach;
dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
tz->thermal_zone->id);
return 0;
acpi_bus_detach:
acpi_bus_detach_private_data(tz->device->handle);
remove_dev_link:
sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
remove_tz_link:
sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
unregister_tzd:
thermal_zone_device_unregister(tz->thermal_zone);
return result;
}
static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
......
......@@ -92,6 +92,14 @@ int cxgb4_thermal_init(struct adapter *adap)
ch_thermal->tzdev = NULL;
return ret;
}
ret = thermal_zone_device_enable(ch_thermal->tzdev);
if (ret) {
dev_err(adap->pdev_dev, "Failed to enable thermal zone\n");
thermal_zone_device_unregister(adap->ch_thermal.tzdev);
return ret;
}
return 0;
}
......
......@@ -98,7 +98,6 @@ struct mlxsw_thermal_module {
struct mlxsw_thermal *parent;
struct thermal_zone_device *tzdev;
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
enum thermal_device_mode mode;
int module; /* Module or gearbox number */
};
......@@ -110,7 +109,6 @@ struct mlxsw_thermal {
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
enum thermal_device_mode mode;
struct mlxsw_thermal_module *tz_module_arr;
u8 tz_module_num;
struct mlxsw_thermal_module *tz_gearbox_arr;
......@@ -277,36 +275,6 @@ static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev,
return 0;
}
static int mlxsw_thermal_get_mode(struct thermal_zone_device *tzdev,
enum thermal_device_mode *mode)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
*mode = thermal->mode;
return 0;
}
static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
enum thermal_device_mode mode)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
mutex_lock(&tzdev->lock);
if (mode == THERMAL_DEVICE_ENABLED)
tzdev->polling_delay = thermal->polling_delay;
else
tzdev->polling_delay = 0;
mutex_unlock(&tzdev->lock);
thermal->mode = mode;
thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
return 0;
}
static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
int *p_temp)
{
......@@ -406,8 +374,6 @@ static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev,
static struct thermal_zone_device_ops mlxsw_thermal_ops = {
.bind = mlxsw_thermal_bind,
.unbind = mlxsw_thermal_unbind,
.get_mode = mlxsw_thermal_get_mode,
.set_mode = mlxsw_thermal_set_mode,
.get_temp = mlxsw_thermal_get_temp,
.get_trip_type = mlxsw_thermal_get_trip_type,
.get_trip_temp = mlxsw_thermal_get_trip_temp,
......@@ -465,37 +431,6 @@ static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
return err;
}
static int mlxsw_thermal_module_mode_get(struct thermal_zone_device *tzdev,
enum thermal_device_mode *mode)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
*mode = tz->mode;
return 0;
}
static int mlxsw_thermal_module_mode_set(struct thermal_zone_device *tzdev,
enum thermal_device_mode mode)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
mutex_lock(&tzdev->lock);
if (mode == THERMAL_DEVICE_ENABLED)
tzdev->polling_delay = thermal->polling_delay;
else
tzdev->polling_delay = 0;
mutex_unlock(&tzdev->lock);
tz->mode = mode;
thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
return 0;
}
static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
int *p_temp)
{
......@@ -611,8 +546,6 @@ static int mlxsw_thermal_module_trend_get(struct thermal_zone_device *tzdev,
static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
.bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind,
.get_mode = mlxsw_thermal_module_mode_get,
.set_mode = mlxsw_thermal_module_mode_set,
.get_temp = mlxsw_thermal_module_temp_get,
.get_trip_type = mlxsw_thermal_module_trip_type_get,
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
......@@ -650,8 +583,6 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
.bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind,
.get_mode = mlxsw_thermal_module_mode_get,
.set_mode = mlxsw_thermal_module_mode_set,
.get_temp = mlxsw_thermal_gearbox_temp_get,
.get_trip_type = mlxsw_thermal_module_trip_type_get,
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
......@@ -780,8 +711,11 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
return err;
}
module_tz->mode = THERMAL_DEVICE_ENABLED;
return 0;
err = thermal_zone_device_enable(module_tz->tzdev);
if (err)
thermal_zone_device_unregister(module_tz->tzdev);
return err;
}
static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev)
......@@ -884,6 +818,7 @@ static int
mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
{
char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
int ret;
snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
gearbox_tz->module + 1);
......@@ -896,8 +831,11 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
if (IS_ERR(gearbox_tz->tzdev))
return PTR_ERR(gearbox_tz->tzdev);
gearbox_tz->mode = THERMAL_DEVICE_ENABLED;
return 0;
ret = thermal_zone_device_enable(gearbox_tz->tzdev);
if (ret)
thermal_zone_device_unregister(gearbox_tz->tzdev);
return ret;
}
static void
......@@ -1065,10 +1003,15 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
if (err)
goto err_unreg_modules_tzdev;
thermal->mode = THERMAL_DEVICE_ENABLED;
err = thermal_zone_device_enable(thermal->tzdev);
if (err)
goto err_unreg_gearboxes;
*p_thermal = thermal;
return 0;
err_unreg_gearboxes:
mlxsw_thermal_gearboxes_fini(thermal);
err_unreg_modules_tzdev:
mlxsw_thermal_modules_fini(thermal);
err_unreg_tzdev:
......
......@@ -733,7 +733,7 @@ static struct thermal_zone_device_ops tzone_ops = {
static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
{
int i;
int i, ret;
char name[16];
static atomic_t counter = ATOMIC_INIT(0);
......@@ -759,6 +759,13 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
return;
}
ret = thermal_zone_device_enable(mvm->tz_device.tzone);
if (ret) {
IWL_DEBUG_TEMP(mvm, "Failed to enable thermal zone\n");
thermal_zone_device_unregister(mvm->tz_device.tzone);
return;
}
/* 0 is a valid temperature,
* so initialize the array with S16_MIN which invalid temperature
*/
......
......@@ -397,38 +397,23 @@ static inline void acerhdf_revert_to_bios_mode(void)
{
acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
kernelmode = 0;
if (thz_dev)
thz_dev->polling_delay = 0;
pr_notice("kernel mode fan control OFF\n");
}
static inline void acerhdf_enable_kernelmode(void)
{
kernelmode = 1;
thz_dev->polling_delay = interval*1000;
thermal_zone_device_update(thz_dev, THERMAL_EVENT_UNSPECIFIED);
pr_notice("kernel mode fan control ON\n");
}
static int acerhdf_get_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode *mode)
{
if (verbose)
pr_notice("kernel mode fan control %d\n", kernelmode);
*mode = (kernelmode) ? THERMAL_DEVICE_ENABLED
: THERMAL_DEVICE_DISABLED;
return 0;
}
/*
* set operation mode;
* enabled: the thermal layer of the kernel takes care about
* the temperature and the fan.
* disabled: the BIOS takes control of the fan.
*/
static int acerhdf_set_mode(struct thermal_zone_device *thermal,
static int acerhdf_change_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode mode)
{
if (mode == THERMAL_DEVICE_DISABLED && kernelmode)
......@@ -488,8 +473,7 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = {
.bind = acerhdf_bind,
.unbind = acerhdf_unbind,
.get_temp = acerhdf_get_ec_temp,
.get_mode = acerhdf_get_mode,
.set_mode = acerhdf_set_mode,
.change_mode = acerhdf_change_mode,
.get_trip_type = acerhdf_get_trip_type,
.get_trip_hyst = acerhdf_get_trip_hyst,
.get_trip_temp = acerhdf_get_trip_temp,
......@@ -733,6 +717,8 @@ static void acerhdf_unregister_platform(void)
static int __init acerhdf_register_thermal(void)
{
int ret;
cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL,
&acerhdf_cooling_ops);
......@@ -746,6 +732,13 @@ static int __init acerhdf_register_thermal(void)
if (IS_ERR(thz_dev))
return -EINVAL;
if (kernelmode)
ret = thermal_zone_device_enable(thz_dev);
else
ret = thermal_zone_device_disable(thz_dev);
if (ret)
return ret;
if (strcmp(thz_dev->governor->name,
acerhdf_zone_params.governor_name)) {
pr_err("Didn't get thermal governor %s, perhaps not compiled into thermal subsystem.\n",
......
......@@ -493,6 +493,12 @@ static int mid_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(pinfo->tzd[i]);
goto err;
}
ret = thermal_zone_device_enable(pinfo->tzd[i]);
if (ret) {
kfree(td_info);
thermal_zone_device_unregister(pinfo->tzd[i]);
goto err;
}
}
pinfo->pdev = pdev;
......
......@@ -939,7 +939,7 @@ static struct thermal_zone_device_ops psy_tzd_ops = {
static int psy_register_thermal(struct power_supply *psy)
{
int i;
int i, ret;
if (psy->desc->no_thermal)
return 0;
......@@ -949,7 +949,12 @@ static int psy_register_thermal(struct power_supply *psy)
if (psy->desc->properties[i] == POWER_SUPPLY_PROP_TEMP) {
psy->tzd = thermal_zone_device_register(psy->desc->name,
0, 0, psy, &psy_tzd_ops, NULL, 0, 0);
return PTR_ERR_OR_ZERO(psy->tzd);
if (IS_ERR(psy->tzd))
return PTR_ERR(psy->tzd);
ret = thermal_zone_device_enable(psy->tzd);
if (ret)
thermal_zone_device_unregister(psy->tzd);
return ret;
}
}
return 0;
......
......@@ -17,6 +17,16 @@ menuconfig THERMAL
if THERMAL
config THERMAL_NETLINK
bool "Thermal netlink management"
depends on NET
default y
help
The thermal framework has a netlink interface to do thermal
zones discovery, temperature readings and events such as
trip point crossed, cooling device update or governor
change. It is recommended to enable the feature.
config THERMAL_STATISTICS
bool "Thermal state transition statistics"
help
......@@ -180,16 +190,6 @@ config CPU_IDLE_THERMAL
idle cycle.
endif
config CLOCK_THERMAL
bool "Generic clock cooling support"
depends on COMMON_CLK
depends on PM_OPP
help
This entry implements the generic clock cooling mechanism through
frequency clipping. Typically used to cool off co-processors. The
device that is configured to use this cooling mechanism will be
controlled to reduce clock frequency whenever temperature is high.
config DEVFREQ_THERMAL
bool "Generic device cooling support"
depends on PM_DEVFREQ
......
......@@ -7,6 +7,9 @@ obj-$(CONFIG_THERMAL) += thermal_sys.o
thermal_sys-y += thermal_core.o thermal_sysfs.o \
thermal_helpers.o
# netlink interface to manage the thermal framework
thermal_sys-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o
# interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o
......@@ -22,9 +25,6 @@ thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += gov_power_allocator.o
thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpufreq_cooling.o
thermal_sys-$(CONFIG_CPU_IDLE_THERMAL) += cpuidle_cooling.o
# clock cooling
thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
# devfreq cooling
thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
......
......@@ -874,6 +874,12 @@ static int armada_thermal_probe(struct platform_device *pdev)
return PTR_ERR(tz);
}
ret = thermal_zone_device_enable(tz);
if (ret) {
thermal_zone_device_unregister(tz);
return ret;
}
drvdata->type = LEGACY;
drvdata->data.tz = tz;
platform_set_drvdata(pdev, drvdata);
......
This diff is collapsed.
......@@ -49,7 +49,6 @@ struct da9062_thermal {
struct da9062 *hw;
struct delayed_work work;
struct thermal_zone_device *zone;
enum thermal_device_mode mode;
struct mutex lock; /* protection for da9062_thermal temperature */
int temperature;
int irq;
......@@ -121,14 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
static int da9062_thermal_get_mode(struct thermal_zone_device *z,
enum thermal_device_mode *mode)
{
struct da9062_thermal *thermal = z->devdata;
*mode = thermal->mode;
return 0;
}
static int da9062_thermal_get_trip_type(struct thermal_zone_device *z,
int trip,
enum thermal_trip_type *type)
......@@ -181,7 +172,6 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z,
static struct thermal_zone_device_ops da9062_thermal_ops = {
.get_temp = da9062_thermal_get_temp,
.get_mode = da9062_thermal_get_mode,
.get_trip_type = da9062_thermal_get_trip_type,
.get_trip_temp = da9062_thermal_get_trip_temp,
};
......@@ -233,7 +223,6 @@ static int da9062_thermal_probe(struct platform_device *pdev)
thermal->config = match->data;
thermal->hw = chip;
thermal->mode = THERMAL_DEVICE_ENABLED;
thermal->dev = &pdev->dev;
INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
......@@ -248,6 +237,11 @@ static int da9062_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(thermal->zone);
goto err;
}
ret = thermal_zone_device_enable(thermal->zone);
if (ret) {
dev_err(&pdev->dev, "Cannot enable thermal zone device\n");
goto err_zone;
}
dev_dbg(&pdev->dev,
"TJUNC temperature polling period set at %d ms\n",
......
// SPDX-License-Identifier: GPL-2.0
/*
* devfreq_cooling: Thermal cooling device implementation for devices using
* devfreq
*
* Copyright (C) 2014-2015 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* TODO:
* - If OPPs are added or removed after devfreq cooling has
* registered, the devfreq cooling won't react to it.
......
......@@ -153,6 +153,12 @@ static int dove_thermal_probe(struct platform_device *pdev)
return PTR_ERR(thermal);
}
ret = thermal_zone_device_enable(thermal);
if (ret) {
thermal_zone_device_unregister(thermal);
return ret;
}
platform_set_drvdata(pdev, thermal);
return 0;
......
// SPDX-License-Identifier: GPL-2.0
/*
* A power allocator to manage temperature
*
* Copyright (C) 2014 ARM Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) "Power allocator: " fmt
......
......@@ -549,8 +549,10 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
{
struct thermal_zone_device *tzd = sensor->tzd;
tzd->ops->set_mode(tzd,
on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
if (on)
thermal_zone_device_enable(tzd);
else
thermal_zone_device_disable(tzd);
}
static int hisi_thermal_probe(struct platform_device *pdev)
......
......@@ -220,6 +220,7 @@ static const struct of_device_id imx8mm_tmu_table[] = {
{ .compatible = "fsl,imx8mp-tmu", .data = &imx8mp_tmu_data, },
{ },
};
MODULE_DEVICE_TABLE(of, imx8mm_tmu_table);
static struct platform_driver imx8mm_tmu = {
.driver = {
......
......@@ -197,7 +197,6 @@ struct imx_thermal_data {
struct cpufreq_policy *policy;
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
enum thermal_device_mode mode;
struct regmap *tempmon;
u32 c1, c2; /* See formula in imx_init_calib() */
int temp_passive;
......@@ -253,10 +252,11 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
const struct thermal_soc_data *soc_data = data->socdata;
struct regmap *map = data->tempmon;
unsigned int n_meas;
bool wait;
bool wait, run_measurement;
u32 val;
if (data->mode == THERMAL_DEVICE_ENABLED) {
run_measurement = !data->irq_enabled;
if (!run_measurement) {
/* Check if a measurement is currently in progress */
regmap_read(map, soc_data->temp_data, &val);
wait = !(val & soc_data->temp_valid_mask);
......@@ -283,7 +283,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
regmap_read(map, soc_data->temp_data, &val);
if (data->mode != THERMAL_DEVICE_ENABLED) {
if (run_measurement) {
regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
soc_data->measure_temp_mask);
regmap_write(map, soc_data->sensor_ctrl + REG_SET,
......@@ -331,17 +331,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
return 0;
}
static int imx_get_mode(struct thermal_zone_device *tz,
enum thermal_device_mode *mode)
{
struct imx_thermal_data *data = tz->devdata;
*mode = data->mode;
return 0;
}
static int imx_set_mode(struct thermal_zone_device *tz,
static int imx_change_mode(struct thermal_zone_device *tz,
enum thermal_device_mode mode)
{
struct imx_thermal_data *data = tz->devdata;
......@@ -349,9 +339,6 @@ static int imx_set_mode(struct thermal_zone_device *tz,
const struct thermal_soc_data *soc_data = data->socdata;
if (mode == THERMAL_DEVICE_ENABLED) {
tz->polling_delay = IMX_POLLING_DELAY;
tz->passive_delay = IMX_PASSIVE_DELAY;
regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
soc_data->power_down_mask);
regmap_write(map, soc_data->sensor_ctrl + REG_SET,
......@@ -367,18 +354,12 @@ static int imx_set_mode(struct thermal_zone_device *tz,
regmap_write(map, soc_data->sensor_ctrl + REG_SET,
soc_data->power_down_mask);
tz->polling_delay = 0;
tz->passive_delay = 0;
if (data->irq_enabled) {
disable_irq(data->irq);
data->irq_enabled = false;
}
}
data->mode = mode;
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
return 0;
}
......@@ -467,8 +448,7 @@ static struct thermal_zone_device_ops imx_tz_ops = {
.bind = imx_bind,
.unbind = imx_unbind,
.get_temp = imx_get_temp,
.get_mode = imx_get_mode,
.set_mode = imx_set_mode,
.change_mode = imx_change_mode,
.get_trip_type = imx_get_trip_type,
.get_trip_temp = imx_get_trip_temp,
.get_crit_temp = imx_get_crit_temp,
......@@ -832,7 +812,9 @@ static int imx_thermal_probe(struct platform_device *pdev)
data->socdata->measure_temp_mask);
data->irq_enabled = true;
data->mode = THERMAL_DEVICE_ENABLED;
ret = thermal_zone_device_enable(data->tz);
if (ret)
goto thermal_zone_unregister;
ret = devm_request_threaded_irq(&pdev->dev, data->irq,
imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
......@@ -874,19 +856,18 @@ static int imx_thermal_remove(struct platform_device *pdev)
static int __maybe_unused imx_thermal_suspend(struct device *dev)
{
struct imx_thermal_data *data = dev_get_drvdata(dev);
struct regmap *map = data->tempmon;
int ret;
/*
* Need to disable thermal sensor, otherwise, when thermal core
* try to get temperature before thermal sensor resume, a wrong
* temperature will be read as the thermal sensor is powered
* down.
* down. This is done in change_mode() operation called from
* thermal_zone_device_disable()
*/
regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
data->socdata->measure_temp_mask);
regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
data->socdata->power_down_mask);
data->mode = THERMAL_DEVICE_DISABLED;
ret = thermal_zone_device_disable(data->tz);
if (ret)
return ret;
clk_disable_unprepare(data->thermal_clk);
return 0;
......@@ -895,18 +876,15 @@ static int __maybe_unused imx_thermal_suspend(struct device *dev)
static int __maybe_unused imx_thermal_resume(struct device *dev)
{
struct imx_thermal_data *data = dev_get_drvdata(dev);
struct regmap *map = data->tempmon;
int ret;
ret = clk_prepare_enable(data->thermal_clk);
if (ret)
return ret;
/* Enabled thermal sensor after resume */
regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
data->socdata->power_down_mask);
regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
data->socdata->measure_temp_mask);
data->mode = THERMAL_DEVICE_ENABLED;
ret = thermal_zone_device_enable(data->tz);
if (ret)
return ret;
return 0;
}
......
......@@ -48,7 +48,6 @@ struct int3400_thermal_priv {
struct acpi_device *adev;
struct platform_device *pdev;
struct thermal_zone_device *thermal;
int mode;
int art_count;
struct art *arts;
int trt_count;
......@@ -383,42 +382,20 @@ static int int3400_thermal_get_temp(struct thermal_zone_device *thermal,
return 0;
}
static int int3400_thermal_get_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode *mode)
{
struct int3400_thermal_priv *priv = thermal->devdata;
if (!priv)
return -EINVAL;
*mode = priv->mode;
return 0;
}
static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
static int int3400_thermal_change_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode mode)
{
struct int3400_thermal_priv *priv = thermal->devdata;
bool enable;
int result = 0;
if (!priv)
return -EINVAL;
if (mode == THERMAL_DEVICE_ENABLED)
enable = true;
else if (mode == THERMAL_DEVICE_DISABLED)
enable = false;
else
return -EINVAL;
if (enable != priv->mode) {
priv->mode = enable;
if (mode != thermal->mode)
result = int3400_thermal_run_osc(priv->adev->handle,
priv->current_uuid_index,
enable);
}
mode == THERMAL_DEVICE_ENABLED);
evaluate_odvp(priv);
......@@ -427,8 +404,7 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
static struct thermal_zone_device_ops int3400_thermal_ops = {
.get_temp = int3400_thermal_get_temp,
.get_mode = int3400_thermal_get_mode,
.set_mode = int3400_thermal_set_mode,
.change_mode = int3400_thermal_change_mode,
};
static struct thermal_zone_params int3400_thermal_params = {
......
......@@ -259,9 +259,14 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
ret = PTR_ERR(int34x_thermal_zone->zone);
goto err_thermal_zone;
}
ret = thermal_zone_device_enable(int34x_thermal_zone->zone);
if (ret)
goto err_enable;
return int34x_thermal_zone;
err_enable:
thermal_zone_device_unregister(int34x_thermal_zone->zone);
err_thermal_zone:
acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
kfree(int34x_thermal_zone->aux_trips);
......
......@@ -43,7 +43,7 @@
#define PCI_DEVICE_ID_PROC_ICL_THERMAL 0x8a03
/* JasperLake thermal reporting device */
#define PCI_DEVICE_ID_PROC_JSL_THERMAL 0x4503
#define PCI_DEVICE_ID_PROC_JSL_THERMAL 0x4E03
/* TigerLake thermal reporting device */
#define PCI_DEVICE_ID_PROC_TGL_THERMAL 0x9A03
......
......@@ -24,6 +24,7 @@
#define PCH_THERMAL_DID_SKL_H 0xA131 /* Skylake PCH 100 series */
#define PCH_THERMAL_DID_CNL 0x9Df9 /* CNL PCH */
#define PCH_THERMAL_DID_CNL_H 0xA379 /* CNL-H PCH */
#define PCH_THERMAL_DID_CNL_LP 0x02F9 /* CNL-LP PCH */
#define PCH_THERMAL_DID_CML_H 0X06F9 /* CML-H PCH */
/* Wildcat Point-LP PCH Thermal registers */
......@@ -352,9 +353,14 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
err = PTR_ERR(ptd->tzd);
goto error_cleanup;
}
err = thermal_zone_device_enable(ptd->tzd);
if (err)
goto err_unregister;
return 0;
err_unregister:
thermal_zone_device_unregister(ptd->tzd);
error_cleanup:
iounmap(ptd->hw_base);
error_release:
......@@ -405,6 +411,8 @@ static const struct pci_device_id intel_pch_thermal_id[] = {
.driver_data = board_cnl, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL_H),
.driver_data = board_cnl, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL_LP),
.driver_data = board_cnl, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CML_H),
.driver_data = board_cml, },
{ 0, },
......
......@@ -103,7 +103,6 @@ struct soc_sensor_entry {
bool locked;
u32 store_ptps;
u32 store_dts_enable;
enum thermal_device_mode mode;
struct thermal_zone_device *tzone;
};
......@@ -127,10 +126,8 @@ static int soc_dts_enable(struct thermal_zone_device *tzd)
if (ret)
return ret;
if (out & QRK_DTS_ENABLE_BIT) {
aux_entry->mode = THERMAL_DEVICE_ENABLED;
if (out & QRK_DTS_ENABLE_BIT)
return 0;
}
if (!aux_entry->locked) {
out |= QRK_DTS_ENABLE_BIT;
......@@ -138,10 +135,7 @@ static int soc_dts_enable(struct thermal_zone_device *tzd)
QRK_DTS_REG_OFFSET_ENABLE, out);
if (ret)
return ret;
aux_entry->mode = THERMAL_DEVICE_ENABLED;
} else {
aux_entry->mode = THERMAL_DEVICE_DISABLED;
pr_info("DTS is locked. Cannot enable DTS\n");
ret = -EPERM;
}
......@@ -160,10 +154,8 @@ static int soc_dts_disable(struct thermal_zone_device *tzd)
if (ret)
return ret;
if (!(out & QRK_DTS_ENABLE_BIT)) {
aux_entry->mode = THERMAL_DEVICE_DISABLED;
if (!(out & QRK_DTS_ENABLE_BIT))
return 0;
}
if (!aux_entry->locked) {
out &= ~QRK_DTS_ENABLE_BIT;
......@@ -172,10 +164,7 @@ static int soc_dts_disable(struct thermal_zone_device *tzd)
if (ret)
return ret;
aux_entry->mode = THERMAL_DEVICE_DISABLED;
} else {
aux_entry->mode = THERMAL_DEVICE_ENABLED;
pr_info("DTS is locked. Cannot disable DTS\n");
ret = -EPERM;
}
......@@ -309,15 +298,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd,
return 0;
}
static int sys_get_mode(struct thermal_zone_device *tzd,
enum thermal_device_mode *mode)
{
struct soc_sensor_entry *aux_entry = tzd->devdata;
*mode = aux_entry->mode;
return 0;
}
static int sys_set_mode(struct thermal_zone_device *tzd,
static int sys_change_mode(struct thermal_zone_device *tzd,
enum thermal_device_mode mode)
{
int ret;
......@@ -338,8 +319,7 @@ static struct thermal_zone_device_ops tzone_ops = {
.get_trip_type = sys_get_trip_type,
.set_trip_temp = sys_set_trip_temp,
.get_crit_temp = sys_get_crit_temp,
.get_mode = sys_get_mode,
.set_mode = sys_set_mode,
.change_mode = sys_change_mode,
};
static void free_soc_dts(struct soc_sensor_entry *aux_entry)
......@@ -414,9 +394,7 @@ static struct soc_sensor_entry *alloc_soc_dts(void)
goto err_ret;
}
mutex_lock(&dts_update_mutex);
err = soc_dts_enable(aux_entry->tzone);
mutex_unlock(&dts_update_mutex);
err = thermal_zone_device_enable(aux_entry->tzone);
if (err)
goto err_aux_status;
......
......@@ -329,6 +329,9 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
ret = PTR_ERR(dts->tzone);
goto err_ret;
}
ret = thermal_zone_device_enable(dts->tzone);
if (ret)
goto err_enable;
ret = soc_dts_enable(id);
if (ret)
......
......@@ -363,6 +363,12 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
kfree(zonedev);
return err;
}
err = thermal_zone_device_enable(zonedev->tzone);
if (err) {
thermal_zone_device_unregister(zonedev->tzone);
kfree(zonedev);
return err;
}
/* Store MSR value for package thermal interrupt, to restore at exit */
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
zonedev->msr_pkg_therm_high);
......
......@@ -65,6 +65,7 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
struct thermal_zone_device *thermal = NULL;
struct kirkwood_thermal_priv *priv;
struct resource *res;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
......@@ -82,6 +83,12 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
"Failed to register thermal zone device\n");
return PTR_ERR(thermal);
}
ret = thermal_zone_device_enable(thermal);
if (ret) {
thermal_zone_device_unregister(thermal);
dev_err(&pdev->dev, "Failed to enable thermal zone device\n");
return ret;
}
platform_set_drvdata(pdev, thermal);
......
This diff is collapsed.
......@@ -48,6 +48,63 @@
#define MSM8916_CAL_SEL_MASK 0xe0000000
#define MSM8916_CAL_SEL_SHIFT 29
/* eeprom layout data for 8939 */
#define MSM8939_BASE0_MASK 0x000000ff
#define MSM8939_BASE1_MASK 0xff000000
#define MSM8939_BASE0_SHIFT 0
#define MSM8939_BASE1_SHIFT 24
#define MSM8939_S0_P1_MASK 0x000001f8
#define MSM8939_S1_P1_MASK 0x001f8000
#define MSM8939_S2_P1_MASK_0_4 0xf8000000
#define MSM8939_S2_P1_MASK_5 0x00000001
#define MSM8939_S3_P1_MASK 0x00001f80
#define MSM8939_S4_P1_MASK 0x01f80000
#define MSM8939_S5_P1_MASK 0x00003f00
#define MSM8939_S6_P1_MASK 0x03f00000
#define MSM8939_S7_P1_MASK 0x0000003f
#define MSM8939_S8_P1_MASK 0x0003f000
#define MSM8939_S9_P1_MASK 0x07e00000
#define MSM8939_S0_P2_MASK 0x00007e00
#define MSM8939_S1_P2_MASK 0x07e00000
#define MSM8939_S2_P2_MASK 0x0000007e
#define MSM8939_S3_P2_MASK 0x0007e000
#define MSM8939_S4_P2_MASK 0x7e000000
#define MSM8939_S5_P2_MASK 0x000fc000
#define MSM8939_S6_P2_MASK 0xfc000000
#define MSM8939_S7_P2_MASK 0x00000fc0
#define MSM8939_S8_P2_MASK 0x00fc0000
#define MSM8939_S9_P2_MASK_0_4 0xf8000000
#define MSM8939_S9_P2_MASK_5 0x00002000
#define MSM8939_S0_P1_SHIFT 3
#define MSM8939_S1_P1_SHIFT 15
#define MSM8939_S2_P1_SHIFT_0_4 27
#define MSM8939_S2_P1_SHIFT_5 0
#define MSM8939_S3_P1_SHIFT 7
#define MSM8939_S4_P1_SHIFT 19
#define MSM8939_S5_P1_SHIFT 8
#define MSM8939_S6_P1_SHIFT 20
#define MSM8939_S7_P1_SHIFT 0
#define MSM8939_S8_P1_SHIFT 12
#define MSM8939_S9_P1_SHIFT 21
#define MSM8939_S0_P2_SHIFT 9
#define MSM8939_S1_P2_SHIFT 21
#define MSM8939_S2_P2_SHIFT 1
#define MSM8939_S3_P2_SHIFT 13
#define MSM8939_S4_P2_SHIFT 25
#define MSM8939_S5_P2_SHIFT 14
#define MSM8939_S6_P2_SHIFT 26
#define MSM8939_S7_P2_SHIFT 6
#define MSM8939_S8_P2_SHIFT 18
#define MSM8939_S9_P2_SHIFT_0_4 27
#define MSM8939_S9_P2_SHIFT_5 13
#define MSM8939_CAL_SEL_MASK 0x7
#define MSM8939_CAL_SEL_SHIFT 0
/* eeprom layout data for 8974 */
#define BASE1_MASK 0xff
#define S0_P1_MASK 0x3f00
......@@ -189,6 +246,76 @@ static int calibrate_8916(struct tsens_priv *priv)
return 0;
}
static int calibrate_8939(struct tsens_priv *priv)
{
int base0 = 0, base1 = 0, i;
u32 p1[10], p2[10];
int mode = 0;
u32 *qfprom_cdata;
u32 cdata[6];
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(qfprom_cdata))
return PTR_ERR(qfprom_cdata);
/* Mapping between qfprom nvmem and calibration data */
cdata[0] = qfprom_cdata[12];
cdata[1] = qfprom_cdata[13];
cdata[2] = qfprom_cdata[0];
cdata[3] = qfprom_cdata[1];
cdata[4] = qfprom_cdata[22];
cdata[5] = qfprom_cdata[21];
mode = (cdata[0] & MSM8939_CAL_SEL_MASK) >> MSM8939_CAL_SEL_SHIFT;
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
switch (mode) {
case TWO_PT_CALIB:
base1 = (cdata[3] & MSM8939_BASE1_MASK) >> MSM8939_BASE1_SHIFT;
p2[0] = (cdata[0] & MSM8939_S0_P2_MASK) >> MSM8939_S0_P2_SHIFT;
p2[1] = (cdata[0] & MSM8939_S1_P2_MASK) >> MSM8939_S1_P2_SHIFT;
p2[2] = (cdata[1] & MSM8939_S2_P2_MASK) >> MSM8939_S2_P2_SHIFT;
p2[3] = (cdata[1] & MSM8939_S3_P2_MASK) >> MSM8939_S3_P2_SHIFT;
p2[4] = (cdata[1] & MSM8939_S4_P2_MASK) >> MSM8939_S4_P2_SHIFT;
p2[5] = (cdata[2] & MSM8939_S5_P2_MASK) >> MSM8939_S5_P2_SHIFT;
p2[6] = (cdata[2] & MSM8939_S6_P2_MASK) >> MSM8939_S6_P2_SHIFT;
p2[7] = (cdata[3] & MSM8939_S7_P2_MASK) >> MSM8939_S7_P2_SHIFT;
p2[8] = (cdata[3] & MSM8939_S8_P2_MASK) >> MSM8939_S8_P2_SHIFT;
p2[9] = (cdata[4] & MSM8939_S9_P2_MASK_0_4) >> MSM8939_S9_P2_SHIFT_0_4;
p2[9] |= ((cdata[5] & MSM8939_S9_P2_MASK_5) >> MSM8939_S9_P2_SHIFT_5) << 5;
for (i = 0; i < priv->num_sensors; i++)
p2[i] = (base1 + p2[i]) << 2;
fallthrough;
case ONE_PT_CALIB2:
base0 = (cdata[2] & MSM8939_BASE0_MASK) >> MSM8939_BASE0_SHIFT;
p1[0] = (cdata[0] & MSM8939_S0_P1_MASK) >> MSM8939_S0_P1_SHIFT;
p1[1] = (cdata[0] & MSM8939_S1_P1_MASK) >> MSM8939_S1_P1_SHIFT;
p1[2] = (cdata[0] & MSM8939_S2_P1_MASK_0_4) >> MSM8939_S2_P1_SHIFT_0_4;
p1[2] |= ((cdata[1] & MSM8939_S2_P1_MASK_5) >> MSM8939_S2_P1_SHIFT_5) << 5;
p1[3] = (cdata[1] & MSM8939_S3_P1_MASK) >> MSM8939_S3_P1_SHIFT;
p1[4] = (cdata[1] & MSM8939_S4_P1_MASK) >> MSM8939_S4_P1_SHIFT;
p1[5] = (cdata[2] & MSM8939_S5_P1_MASK) >> MSM8939_S5_P1_SHIFT;
p1[6] = (cdata[2] & MSM8939_S6_P1_MASK) >> MSM8939_S6_P1_SHIFT;
p1[7] = (cdata[3] & MSM8939_S7_P1_MASK) >> MSM8939_S7_P1_SHIFT;
p1[8] = (cdata[3] & MSM8939_S8_P1_MASK) >> MSM8939_S8_P1_SHIFT;
p1[9] = (cdata[4] & MSM8939_S9_P1_MASK) >> MSM8939_S9_P1_SHIFT;
for (i = 0; i < priv->num_sensors; i++)
p1[i] = ((base0) + p1[i]) << 2;
break;
default:
for (i = 0; i < priv->num_sensors; i++) {
p1[i] = 500;
p2[i] = 780;
}
break;
}
compute_intercept_slope(priv, p1, p2, mode);
kfree(qfprom_cdata);
return 0;
}
static int calibrate_8974(struct tsens_priv *priv)
{
int base1 = 0, base2 = 0, i;
......@@ -325,7 +452,7 @@ static int calibrate_8974(struct tsens_priv *priv)
return 0;
}
/* v0.1: 8916, 8974 */
/* v0.1: 8916, 8939, 8974 */
static struct tsens_features tsens_v0_1_feat = {
.ver_major = VER_0_1,
......@@ -386,6 +513,21 @@ struct tsens_plat_data data_8916 = {
.fields = tsens_v0_1_regfields,
};
static const struct tsens_ops ops_8939 = {
.init = init_common,
.calibrate = calibrate_8939,
.get_temp = get_temp_common,
};
struct tsens_plat_data data_8939 = {
.num_sensors = 10,
.ops = &ops_8939,
.hw_ids = (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 },
.feat = &tsens_v0_1_feat,
.fields = tsens_v0_1_regfields,
};
static const struct tsens_ops ops_8974 = {
.init = init_common,
.calibrate = calibrate_8974,
......
......@@ -897,6 +897,9 @@ static const struct of_device_id tsens_table[] = {
{
.compatible = "qcom,msm8916-tsens",
.data = &data_8916,
}, {
.compatible = "qcom,msm8939-tsens",
.data = &data_8939,
}, {
.compatible = "qcom,msm8974-tsens",
.data = &data_8974,
......
......@@ -585,7 +585,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp);
extern struct tsens_plat_data data_8960;
/* TSENS v0.1 targets */
extern struct tsens_plat_data data_8916, data_8974;
extern struct tsens_plat_data data_8916, data_8939, data_8974;
/* TSENS v1 targets */
extern struct tsens_plat_data data_tsens_v1, data_8976;
......
......@@ -63,7 +63,7 @@
#define TSC_MAX_NUM 3
/* default THCODE values if FUSEs are missing */
static const int thcode[TSC_MAX_NUM][3] = {
static const int thcodes[TSC_MAX_NUM][3] = {
{ 3397, 2800, 2221 },
{ 3393, 2795, 2216 },
{ 3389, 2805, 2237 },
......@@ -172,7 +172,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 <= thcode[tsc->id][1])
if (reg <= thcodes[tsc->id][1])
val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1,
tsc->coef.a1);
else
......@@ -314,6 +314,10 @@ static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
.compatible = "renesas,r8a774b1-thermal",
.data = &rcar_gen3_ths_tj_1,
},
{
.compatible = "renesas,r8a774e1-thermal",
.data = &rcar_gen3_ths_tj_1,
},
{
.compatible = "renesas,r8a7795-thermal",
.data = &rcar_gen3_ths_tj_1,
......@@ -430,7 +434,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
priv->tscs[i] = tsc;
priv->thermal_init(tsc);
rcar_gen3_thermal_calc_coefs(tsc, ptat, thcode[i],
rcar_gen3_thermal_calc_coefs(tsc, ptat, thcodes[i],
*rcar_gen3_ths_tj_1);
zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
......
......@@ -550,12 +550,19 @@ static int rcar_thermal_probe(struct platform_device *pdev)
priv->zone = devm_thermal_zone_of_sensor_register(
dev, i, priv,
&rcar_thermal_zone_of_ops);
else
else {
priv->zone = thermal_zone_device_register(
"rcar_thermal",
1, 0, priv,
&rcar_thermal_zone_ops, NULL, 0,
idle);
ret = thermal_zone_device_enable(priv->zone);
if (ret) {
thermal_zone_device_unregister(priv->zone);
priv->zone = ERR_PTR(ret);
}
}
if (IS_ERR(priv->zone)) {
dev_err(dev, "can't register thermal zone\n");
ret = PTR_ERR(priv->zone);
......
......@@ -1068,8 +1068,10 @@ rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on)
{
struct thermal_zone_device *tzd = sensor->tzd;
tzd->ops->set_mode(tzd,
on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
if (on)
thermal_zone_device_enable(tzd);
else
thermal_zone_device_disable(tzd);
}
static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
......
......@@ -131,6 +131,11 @@ static int spear_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(spear_thermal);
goto disable_clk;
}
ret = thermal_zone_device_enable(spear_thermal);
if (ret) {
dev_err(&pdev->dev, "Cannot enable thermal zone\n");
goto unregister_tzd;
}
platform_set_drvdata(pdev, spear_thermal);
......@@ -139,6 +144,8 @@ static int spear_thermal_probe(struct platform_device *pdev)
return 0;
unregister_tzd:
thermal_zone_device_unregister(spear_thermal);
disable_clk:
clk_disable(stdev->clk);
......
......@@ -322,8 +322,10 @@ static void sprd_thm_toggle_sensor(struct sprd_thermal_sensor *sen, bool on)
{
struct thermal_zone_device *tzd = sen->tzd;
tzd->ops->set_mode(tzd,
on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
if (on)
thermal_zone_device_enable(tzd);
else
thermal_zone_device_disable(tzd);
}
static int sprd_thm_probe(struct platform_device *pdev)
......
......@@ -246,11 +246,16 @@ int st_thermal_register(struct platform_device *pdev,
ret = PTR_ERR(sensor->thermal_dev);
goto sensor_off;
}
ret = thermal_zone_device_enable(sensor->thermal_dev);
if (ret)
goto tzd_unregister;
platform_set_drvdata(pdev, sensor);
return 0;
tzd_unregister:
thermal_zone_device_unregister(sensor->thermal_dev);
sensor_off:
st_thermal_sensor_off(sensor);
......
......@@ -215,6 +215,8 @@ int thermal_zone_device_set_policy(struct thermal_zone_device *tz,
mutex_unlock(&tz->lock);
mutex_unlock(&thermal_governor_lock);
thermal_notify_tz_gov_change(tz->id, policy);
return ret;
}
......@@ -301,13 +303,22 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
cancel_delayed_work(&tz->poll_queue);
}
static inline bool should_stop_polling(struct thermal_zone_device *tz)
{
return !thermal_zone_device_is_enabled(tz);
}
static void monitor_thermal_zone(struct thermal_zone_device *tz)
{
bool stop;
stop = should_stop_polling(tz);
mutex_lock(&tz->lock);
if (tz->passive)
if (!stop && tz->passive)
thermal_zone_device_set_polling(tz, tz->passive_delay);
else if (tz->polling_delay)
else if (!stop && tz->polling_delay)
thermal_zone_device_set_polling(tz, tz->polling_delay);
else
thermal_zone_device_set_polling(tz, 0);
......@@ -406,12 +417,25 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
{
enum thermal_trip_type type;
int trip_temp, hyst = 0;
/* Ignore disabled trip points */
if (test_bit(trip, &tz->trips_disabled))
return;
tz->ops->get_trip_temp(tz, trip, &trip_temp);
tz->ops->get_trip_type(tz, trip, &type);
if (tz->ops->get_trip_hyst)
tz->ops->get_trip_hyst(tz, trip, &hyst);
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);
if (tz->last_temperature >= trip_temp &&
tz->temperature < (trip_temp - hyst))
thermal_notify_tz_trip_down(tz->id, trip);
}
if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
handle_critical_trips(tz, trip, type);
......@@ -443,6 +467,8 @@ static void update_temperature(struct thermal_zone_device *tz)
mutex_unlock(&tz->lock);
trace_thermal_temperature(tz);
thermal_genl_sampling_temp(tz->id, temp);
}
static void thermal_zone_device_init(struct thermal_zone_device *tz)
......@@ -459,11 +485,71 @@ static void thermal_zone_device_reset(struct thermal_zone_device *tz)
thermal_zone_device_init(tz);
}
static int thermal_zone_device_set_mode(struct thermal_zone_device *tz,
enum thermal_device_mode mode)
{
int ret = 0;
mutex_lock(&tz->lock);
/* do nothing if mode isn't changing */
if (mode == tz->mode) {
mutex_unlock(&tz->lock);
return ret;
}
if (tz->ops->change_mode)
ret = tz->ops->change_mode(tz, mode);
if (!ret)
tz->mode = mode;
mutex_unlock(&tz->lock);
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
if (mode == THERMAL_DEVICE_ENABLED)
thermal_notify_tz_enable(tz->id);
else
thermal_notify_tz_disable(tz->id);
return ret;
}
int thermal_zone_device_enable(struct thermal_zone_device *tz)
{
return thermal_zone_device_set_mode(tz, THERMAL_DEVICE_ENABLED);
}
EXPORT_SYMBOL_GPL(thermal_zone_device_enable);
int thermal_zone_device_disable(struct thermal_zone_device *tz)
{
return thermal_zone_device_set_mode(tz, THERMAL_DEVICE_DISABLED);
}
EXPORT_SYMBOL_GPL(thermal_zone_device_disable);
int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
{
enum thermal_device_mode mode;
mutex_lock(&tz->lock);
mode = tz->mode;
mutex_unlock(&tz->lock);
return mode == THERMAL_DEVICE_ENABLED;
}
void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
{
int count;
if (should_stop_polling(tz))
return;
if (atomic_read(&in_suspend))
return;
......@@ -617,6 +703,73 @@ void thermal_zone_device_rebind_exception(struct thermal_zone_device *tz,
mutex_unlock(&thermal_list_lock);
}
int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
void *data)
{
struct thermal_governor *gov;
int ret = 0;
mutex_lock(&thermal_governor_lock);
list_for_each_entry(gov, &thermal_governor_list, governor_list) {
ret = cb(gov, data);
if (ret)
break;
}
mutex_unlock(&thermal_governor_lock);
return ret;
}
int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
void *), void *data)
{
struct thermal_cooling_device *cdev;
int ret = 0;
mutex_lock(&thermal_list_lock);
list_for_each_entry(cdev, &thermal_cdev_list, node) {
ret = cb(cdev, data);
if (ret)
break;
}
mutex_unlock(&thermal_list_lock);
return ret;
}
int for_each_thermal_zone(int (*cb)(struct thermal_zone_device *, void *),
void *data)
{
struct thermal_zone_device *tz;
int ret = 0;
mutex_lock(&thermal_list_lock);
list_for_each_entry(tz, &thermal_tz_list, node) {
ret = cb(tz, data);
if (ret)
break;
}
mutex_unlock(&thermal_list_lock);
return ret;
}
struct thermal_zone_device *thermal_zone_get_by_id(int id)
{
struct thermal_zone_device *tz, *match = NULL;
mutex_lock(&thermal_list_lock);
list_for_each_entry(tz, &thermal_tz_list, node) {
if (tz->id == id) {
match = tz;
break;
}
}
mutex_unlock(&thermal_list_lock);
return match;
}
void thermal_zone_device_unbind_exception(struct thermal_zone_device *tz,
const char *cdev_type, size_t size)
{
......@@ -1340,6 +1493,8 @@ thermal_zone_device_register(const char *type, int trips, int mask,
if (atomic_cmpxchg(&tz->need_update, 1, 0))
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
thermal_notify_tz_create(tz->id, tz->type);
return tz;
unregister:
......@@ -1411,6 +1566,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
ida_destroy(&tz->ida);
mutex_destroy(&tz->lock);
device_unregister(&tz->device);
thermal_notify_tz_delete(tz->id);
}
EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
......@@ -1456,7 +1613,6 @@ static int thermal_pm_notify(struct notifier_block *nb,
unsigned long mode, void *_unused)
{
struct thermal_zone_device *tz;
enum thermal_device_mode tz_mode;
switch (mode) {
case PM_HIBERNATION_PREPARE:
......@@ -1469,11 +1625,7 @@ static int thermal_pm_notify(struct notifier_block *nb,
case PM_POST_SUSPEND:
atomic_set(&in_suspend, 0);
list_for_each_entry(tz, &thermal_tz_list, node) {
tz_mode = THERMAL_DEVICE_ENABLED;
if (tz->ops->get_mode)
tz->ops->get_mode(tz, &tz_mode);
if (tz_mode == THERMAL_DEVICE_DISABLED)
if (!thermal_zone_device_is_enabled(tz))
continue;
thermal_zone_device_init(tz);
......@@ -1495,6 +1647,10 @@ static int __init thermal_init(void)
{
int result;
result = thermal_netlink_init();
if (result)
goto error;
mutex_init(&poweroff_lock);
result = thermal_register_governors();
if (result)
......@@ -1527,4 +1683,4 @@ static int __init thermal_init(void)
mutex_destroy(&poweroff_lock);
return result;
}
core_initcall(thermal_init);
postcore_initcall(thermal_init);
......@@ -12,6 +12,8 @@
#include <linux/device.h>
#include <linux/thermal.h>
#include "thermal_netlink.h"
/* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise"
......@@ -41,6 +43,17 @@ extern struct thermal_governor *__governor_thermal_table_end[];
__governor < __governor_thermal_table_end; \
__governor++)
int for_each_thermal_zone(int (*cb)(struct thermal_zone_device *, void *),
void *);
int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
void *), void *);
int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
void *thermal_governor);
struct thermal_zone_device *thermal_zone_get_by_id(int id);
struct thermal_attr {
struct device_attribute attr;
char name[THERMAL_NAME_LENGTH];
......@@ -166,4 +179,6 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz)
}
#endif
int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
#endif /* __THERMAL_CORE_H__ */
......@@ -175,6 +175,16 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
mutex_unlock(&tz->lock);
}
static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev,
int target)
{
if (cdev->ops->set_cur_state(cdev, target))
return;
thermal_notify_cdev_state_update(cdev->id, target);
thermal_cooling_device_stats_update(cdev, target);
}
void thermal_cdev_update(struct thermal_cooling_device *cdev)
{
struct thermal_instance *instance;
......@@ -197,8 +207,7 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
target = instance->target;
}
if (!cdev->ops->set_cur_state(cdev, target))
thermal_cooling_device_stats_update(cdev, target);
thermal_cdev_set_cur_state(cdev, target);
cdev->updated = true;
mutex_unlock(&cdev->lock);
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) Linaro Ltd 2020
* Author: Daniel Lezcano <daniel.lezcano@linaro.org>
*/
/* Netlink notification function */
#ifdef CONFIG_THERMAL_NETLINK
int __init thermal_netlink_init(void);
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_delete(int tz_id, int id);
int thermal_notify_tz_trip_add(int tz_id, int id, int type,
int temp, int hyst);
int thermal_notify_tz_trip_change(int tz_id, int id, int type,
int temp, int hyst);
int thermal_notify_cdev_state_update(int cdev_id, int state);
int thermal_notify_cdev_add(int cdev_id, const char *name, int max_state);
int thermal_notify_cdev_delete(int cdev_id);
int thermal_notify_tz_gov_change(int tz_id, const char *name);
int thermal_genl_sampling_temp(int id, int temp);
#else
static inline int thermal_netlink_init(void)
{
return 0;
}
static inline int thermal_notify_tz_create(int tz_id, const char *name)
{
return 0;
}
static inline int thermal_notify_tz_delete(int tz_id)
{
return 0;
}
static inline int thermal_notify_tz_enable(int tz_id)
{
return 0;
}
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)
{
return 0;
}
static inline int thermal_notify_tz_trip_up(int tz_id, int id)
{
return 0;
}
static inline int thermal_notify_tz_trip_delete(int tz_id, int id)
{
return 0;
}
static inline int thermal_notify_tz_trip_add(int tz_id, int id, int type,
int temp, int hyst)
{
return 0;
}
static inline int thermal_notify_tz_trip_change(int tz_id, int id, int type,
int temp, int hyst)
{
return 0;
}
static inline int thermal_notify_cdev_state_update(int cdev_id, int state)
{
return 0;
}
static inline int thermal_notify_cdev_add(int cdev_id, const char *name,
int max_state)
{
return 0;
}
static inline int thermal_notify_cdev_delete(int cdev_id)
{
return 0;
}
static inline int thermal_notify_tz_gov_change(int tz_id, const char *name)
{
return 0;
}
static inline int thermal_genl_sampling_temp(int id, int temp)
{
return 0;
}
#endif /* CONFIG_THERMAL_NETLINK */
......@@ -51,7 +51,6 @@ struct __thermal_bind_params {
/**
* struct __thermal_zone - internal representation of a thermal zone
* @mode: current thermal zone device mode (enabled/disabled)
* @passive_delay: polling interval while passive cooling is activated
* @polling_delay: zone polling interval
* @slope: slope of the temperature adjustment curve
......@@ -65,7 +64,6 @@ struct __thermal_bind_params {
*/
struct __thermal_zone {
enum thermal_device_mode mode;
int passive_delay;
int polling_delay;
int slope;
......@@ -269,39 +267,6 @@ static int of_thermal_unbind(struct thermal_zone_device *thermal,
return 0;
}
static int of_thermal_get_mode(struct thermal_zone_device *tz,
enum thermal_device_mode *mode)
{
struct __thermal_zone *data = tz->devdata;
*mode = data->mode;
return 0;
}
static int of_thermal_set_mode(struct thermal_zone_device *tz,
enum thermal_device_mode mode)
{
struct __thermal_zone *data = tz->devdata;
mutex_lock(&tz->lock);
if (mode == THERMAL_DEVICE_ENABLED) {
tz->polling_delay = data->polling_delay;
tz->passive_delay = data->passive_delay;
} else {
tz->polling_delay = 0;
tz->passive_delay = 0;
}
mutex_unlock(&tz->lock);
data->mode = mode;
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
return 0;
}
static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
enum thermal_trip_type *type)
{
......@@ -393,9 +358,6 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
}
static struct thermal_zone_device_ops of_thermal_ops = {
.get_mode = of_thermal_get_mode,
.set_mode = of_thermal_set_mode,
.get_trip_type = of_thermal_get_trip_type,
.get_trip_temp = of_thermal_get_trip_temp,
.set_trip_temp = of_thermal_set_trip_temp,
......@@ -554,7 +516,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
tzd = thermal_zone_of_add_sensor(child, sensor_np,
data, ops);
if (!IS_ERR(tzd))
tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
thermal_zone_device_enable(tzd);
of_node_put(child);
goto exit;
......@@ -979,7 +941,6 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)
finish:
of_node_put(child);
tz->mode = THERMAL_DEVICE_DISABLED;
return tz;
......
......@@ -49,18 +49,9 @@ static ssize_t
mode_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
enum thermal_device_mode mode;
int result;
if (!tz->ops->get_mode)
return -EPERM;
result = tz->ops->get_mode(tz, &mode);
if (result)
return result;
int enabled = thermal_zone_device_is_enabled(tz);
return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
: "disabled");
return sprintf(buf, "%s\n", enabled ? "enabled" : "disabled");
}
static ssize_t
......@@ -70,13 +61,10 @@ mode_store(struct device *dev, struct device_attribute *attr,
struct thermal_zone_device *tz = to_thermal_zone(dev);
int result;
if (!tz->ops->set_mode)
return -EPERM;
if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
result = thermal_zone_device_enable(tz);
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
result = thermal_zone_device_disable(tz);
else
result = -EINVAL;
......@@ -124,7 +112,8 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
int trip, ret;
int temperature;
int temperature, hyst = 0;
enum thermal_trip_type type;
if (!tz->ops->set_trip_temp)
return -EPERM;
......@@ -139,6 +128,18 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
if (tz->ops->get_trip_hyst) {
ret = tz->ops->get_trip_hyst(tz, trip, &hyst);
if (ret)
return ret;
}
ret = tz->ops->get_trip_type(tz, trip, &type);
if (ret)
return ret;
thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst);
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
return count;
......@@ -428,30 +429,13 @@ static struct attribute_group thermal_zone_attribute_group = {
.attrs = thermal_zone_dev_attrs,
};
/* We expose mode only if .get_mode is present */
static struct attribute *thermal_zone_mode_attrs[] = {
&dev_attr_mode.attr,
NULL,
};
static umode_t thermal_zone_mode_is_visible(struct kobject *kobj,
struct attribute *attr,
int attrno)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct thermal_zone_device *tz;
tz = container_of(dev, struct thermal_zone_device, device);
if (tz->ops->get_mode)
return attr->mode;
return 0;
}
static struct attribute_group thermal_zone_mode_attribute_group = {
.attrs = thermal_zone_mode_attrs,
.is_visible = thermal_zone_mode_is_visible,
};
/* We expose passive only if passive trips are present */
......
......@@ -169,7 +169,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
data = ti_bandgap_get_sensor_data(bgp, id);
if (!IS_ERR_OR_NULL(data))
if (IS_ERR_OR_NULL(data))
data = ti_thermal_build_data(bgp, id);
if (!data)
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/include/linux/clock_cooling.h
*
* Copyright (C) 2014 Eduardo Valentin <edubezval@gmail.com>
*
* Copyright (C) 2013 Texas Instruments Inc.
* Contact: Eduardo Valentin <eduardo.valentin@ti.com>
*
* Highly based on cpufreq_cooling.c.
* Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
*/
#ifndef __CPU_COOLING_H__
#define __CPU_COOLING_H__
#include <linux/of.h>
#include <linux/thermal.h>
#include <linux/cpumask.h>
#ifdef CONFIG_CLOCK_THERMAL
/**
* clock_cooling_register - function to create clock cooling device.
* @dev: struct device pointer to the device used as clock cooling device.
* @clock_name: string containing the clock used as cooling mechanism.
*/
struct thermal_cooling_device *
clock_cooling_register(struct device *dev, const char *clock_name);
/**
* clock_cooling_unregister - function to remove clock cooling device.
* @cdev: thermal cooling device pointer.
*/
void clock_cooling_unregister(struct thermal_cooling_device *cdev);
unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev,
unsigned long freq);
#else /* !CONFIG_CLOCK_THERMAL */
static inline struct thermal_cooling_device *
clock_cooling_register(struct device *dev, const char *clock_name)
{
return NULL;
}
static inline
void clock_cooling_unregister(struct thermal_cooling_device *cdev)
{
}
static inline
unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev,
unsigned long freq)
{
return THERMAL_CSTATE_INVALID;
}
#endif /* CONFIG_CLOCK_THERMAL */
#endif /* __CPU_COOLING_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* devfreq_cooling: Thermal cooling device implementation for devices using
* devfreq
*
* Copyright (C) 2014-2015 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DEVFREQ_COOLING_H__
......
......@@ -37,18 +37,6 @@ struct thermal_cooling_device;
struct thermal_instance;
struct thermal_attr;
enum thermal_device_mode {
THERMAL_DEVICE_DISABLED = 0,
THERMAL_DEVICE_ENABLED,
};
enum thermal_trip_type {
THERMAL_TRIP_ACTIVE = 0,
THERMAL_TRIP_PASSIVE,
THERMAL_TRIP_HOT,
THERMAL_TRIP_CRITICAL,
};
enum thermal_trend {
THERMAL_TREND_STABLE, /* temperature is stable */
THERMAL_TREND_RAISING, /* temperature is raising */
......@@ -76,9 +64,7 @@ struct thermal_zone_device_ops {
struct thermal_cooling_device *);
int (*get_temp) (struct thermal_zone_device *, int *);
int (*set_trips) (struct thermal_zone_device *, int, int);
int (*get_mode) (struct thermal_zone_device *,
enum thermal_device_mode *);
int (*set_mode) (struct thermal_zone_device *,
int (*change_mode) (struct thermal_zone_device *,
enum thermal_device_mode);
int (*get_trip_type) (struct thermal_zone_device *, int,
enum thermal_trip_type *);
......@@ -128,6 +114,7 @@ struct thermal_cooling_device {
* @trip_temp_attrs: attributes for trip points for sysfs: trip temperature
* @trip_type_attrs: attributes for trip points for sysfs: trip type
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
* @mode: current mode of this thermal zone
* @devdata: private pointer for device private data
* @trips: number of trip points the thermal zone supports
* @trips_disabled; bitmap for disabled trips
......@@ -170,6 +157,7 @@ struct thermal_zone_device {
struct thermal_attr *trip_temp_attrs;
struct thermal_attr *trip_type_attrs;
struct thermal_attr *trip_hyst_attrs;
enum thermal_device_mode mode;
void *devdata;
int trips;
unsigned long trips_disabled; /* bitmap for disabled trips */
......@@ -303,11 +291,6 @@ struct thermal_zone_params {
int offset;
};
struct thermal_genl_event {
u32 orig;
enum events event;
};
/**
* struct thermal_zone_of_device_ops - scallbacks for handling DT based zones
*
......@@ -416,6 +399,8 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz);
void thermal_cdev_update(struct thermal_cooling_device *);
void thermal_notify_framework(struct thermal_zone_device *, int);
int thermal_zone_device_enable(struct thermal_zone_device *tz);
int thermal_zone_device_disable(struct thermal_zone_device *tz);
#else
static inline struct thermal_zone_device *thermal_zone_device_register(
const char *type, int trips, int mask, void *devdata,
......@@ -463,6 +448,12 @@ static inline void thermal_cdev_update(struct thermal_cooling_device *cdev)
static inline void thermal_notify_framework(struct thermal_zone_device *tz,
int trip)
{ }
static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
{ return -ENODEV; }
static inline int thermal_zone_device_disable(struct thermal_zone_device *tz)
{ return -ENODEV; }
#endif /* CONFIG_THERMAL */
#endif /* __THERMAL_H__ */
......@@ -4,31 +4,86 @@
#define THERMAL_NAME_LENGTH 20
enum thermal_device_mode {
THERMAL_DEVICE_DISABLED = 0,
THERMAL_DEVICE_ENABLED,
};
enum thermal_trip_type {
THERMAL_TRIP_ACTIVE = 0,
THERMAL_TRIP_PASSIVE,
THERMAL_TRIP_HOT,
THERMAL_TRIP_CRITICAL,
};
/* Adding event notification support elements */
#define THERMAL_GENL_FAMILY_NAME "thermal_event"
#define THERMAL_GENL_FAMILY_NAME "thermal"
#define THERMAL_GENL_VERSION 0x01
#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp"
/* Events supported by Thermal Netlink */
enum events {
THERMAL_AUX0,
THERMAL_AUX1,
THERMAL_CRITICAL,
THERMAL_DEV_FAULT,
};
#define THERMAL_GENL_SAMPLING_GROUP_NAME "sampling"
#define THERMAL_GENL_EVENT_GROUP_NAME "event"
/* attributes of thermal_genl_family */
enum {
/* Attributes of thermal_genl_family */
enum thermal_genl_attr {
THERMAL_GENL_ATTR_UNSPEC,
THERMAL_GENL_ATTR_EVENT,
THERMAL_GENL_ATTR_TZ,
THERMAL_GENL_ATTR_TZ_ID,
THERMAL_GENL_ATTR_TZ_TEMP,
THERMAL_GENL_ATTR_TZ_TRIP,
THERMAL_GENL_ATTR_TZ_TRIP_ID,
THERMAL_GENL_ATTR_TZ_TRIP_TYPE,
THERMAL_GENL_ATTR_TZ_TRIP_TEMP,
THERMAL_GENL_ATTR_TZ_TRIP_HYST,
THERMAL_GENL_ATTR_TZ_MODE,
THERMAL_GENL_ATTR_TZ_NAME,
THERMAL_GENL_ATTR_TZ_CDEV_WEIGHT,
THERMAL_GENL_ATTR_TZ_GOV,
THERMAL_GENL_ATTR_TZ_GOV_NAME,
THERMAL_GENL_ATTR_CDEV,
THERMAL_GENL_ATTR_CDEV_ID,
THERMAL_GENL_ATTR_CDEV_CUR_STATE,
THERMAL_GENL_ATTR_CDEV_MAX_STATE,
THERMAL_GENL_ATTR_CDEV_NAME,
THERMAL_GENL_ATTR_GOV_NAME,
__THERMAL_GENL_ATTR_MAX,
};
#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
/* commands supported by the thermal_genl_family */
enum {
enum thermal_genl_sampling {
THERMAL_GENL_SAMPLING_TEMP,
__THERMAL_GENL_SAMPLING_MAX,
};
#define THERMAL_GENL_SAMPLING_MAX (__THERMAL_GENL_SAMPLING_MAX - 1)
/* Events of thermal_genl_family */
enum thermal_genl_event {
THERMAL_GENL_EVENT_UNSPEC,
THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */
THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */
THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabed */
THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */
THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */
THERMAL_GENL_EVENT_TZ_TRIP_DOWN, /* Trip point crossed the way down */
THERMAL_GENL_EVENT_TZ_TRIP_CHANGE, /* Trip point changed */
THERMAL_GENL_EVENT_TZ_TRIP_ADD, /* Trip point added */
THERMAL_GENL_EVENT_TZ_TRIP_DELETE, /* Trip point deleted */
THERMAL_GENL_EVENT_CDEV_ADD, /* Cdev bound to the thermal zone */
THERMAL_GENL_EVENT_CDEV_DELETE, /* Cdev unbound */
THERMAL_GENL_EVENT_CDEV_STATE_UPDATE, /* Cdev state updated */
THERMAL_GENL_EVENT_TZ_GOV_CHANGE, /* Governor policy changed */
__THERMAL_GENL_EVENT_MAX,
};
#define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1)
/* Commands supported by the thermal_genl_family */
enum thermal_genl_cmd {
THERMAL_GENL_CMD_UNSPEC,
THERMAL_GENL_CMD_EVENT,
THERMAL_GENL_CMD_TZ_GET_ID, /* List of thermal zones id */
THERMAL_GENL_CMD_TZ_GET_TRIP, /* List of thermal trips */
THERMAL_GENL_CMD_TZ_GET_TEMP, /* Get the thermal zone temperature */
THERMAL_GENL_CMD_TZ_GET_GOV, /* Get the thermal zone governor */
THERMAL_GENL_CMD_TZ_GET_MODE, /* Get the thermal zone mode */
THERMAL_GENL_CMD_CDEV_GET, /* List of cdev id */
__THERMAL_GENL_CMD_MAX,
};
#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
......
......@@ -1192,7 +1192,7 @@ static int __init genl_init(void)
panic("GENL: Cannot register controller: %d\n", err);
}
subsys_initcall(genl_init);
core_initcall(genl_init);
static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
gfp_t flags)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment