1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2023 Linaro Limited
4 * Copyright 2023 Intel Corporation
6 * Library routines for retrieving trip point temperature values from the
7 * platform firmware via ACPI.
9 #include <linux/acpi.h>
10 #include <linux/units.h>
11 #include <linux/thermal.h>
15 * Minimum temperature for full military grade is 218°K (-55°C) and
16 * max temperature is 448°K (175°C). We can consider those values as
17 * the boundaries for the [trips] temperature returned by the
18 * firmware. Any values out of these boundaries may be considered
19 * bogus and we can assume the firmware has no data to provide.
21 #define TEMP_MIN_DECIK 2180ULL
22 #define TEMP_MAX_DECIK 4480ULL
24 static int acpi_trip_temp(struct acpi_device
*adev
, char *obj_name
,
27 unsigned long long temp
;
30 status
= acpi_evaluate_integer(adev
->handle
, obj_name
, NULL
, &temp
);
31 if (ACPI_FAILURE(status
)) {
32 acpi_handle_debug(adev
->handle
, "%s evaluation failed\n", obj_name
);
36 if (temp
>= TEMP_MIN_DECIK
&& temp
<= TEMP_MAX_DECIK
) {
39 acpi_handle_debug(adev
->handle
, "%s result %llu out of range\n",
41 *ret_temp
= THERMAL_TEMP_INVALID
;
47 int acpi_active_trip_temp(struct acpi_device
*adev
, int id
, int *ret_temp
)
49 char obj_name
[] = {'_', 'A', 'C', '0' + id
, '\0'};
54 return acpi_trip_temp(adev
, obj_name
, ret_temp
);
56 EXPORT_SYMBOL_NS_GPL(acpi_active_trip_temp
, "ACPI_THERMAL");
58 int acpi_passive_trip_temp(struct acpi_device
*adev
, int *ret_temp
)
60 return acpi_trip_temp(adev
, "_PSV", ret_temp
);
62 EXPORT_SYMBOL_NS_GPL(acpi_passive_trip_temp
, "ACPI_THERMAL");
64 int acpi_hot_trip_temp(struct acpi_device
*adev
, int *ret_temp
)
66 return acpi_trip_temp(adev
, "_HOT", ret_temp
);
68 EXPORT_SYMBOL_NS_GPL(acpi_hot_trip_temp
, "ACPI_THERMAL");
70 int acpi_critical_trip_temp(struct acpi_device
*adev
, int *ret_temp
)
72 return acpi_trip_temp(adev
, "_CRT", ret_temp
);
74 EXPORT_SYMBOL_NS_GPL(acpi_critical_trip_temp
, "ACPI_THERMAL");
76 static int thermal_temp(int error
, int temp_decik
, int *ret_temp
)
81 if (temp_decik
== THERMAL_TEMP_INVALID
)
82 *ret_temp
= THERMAL_TEMP_INVALID
;
84 *ret_temp
= deci_kelvin_to_millicelsius(temp_decik
);
90 * thermal_acpi_active_trip_temp - Retrieve active trip point temperature
91 * @adev: Target thermal zone ACPI device object.
92 * @id: Active cooling level (0 - 9).
93 * @ret_temp: Address to store the retrieved temperature value on success.
95 * Evaluate the _ACx object for the thermal zone represented by @adev to obtain
96 * the temperature of the active cooling trip point corresponding to the active
97 * cooling level given by @id.
99 * Return 0 on success or a negative error value on failure.
101 int thermal_acpi_active_trip_temp(struct acpi_device
*adev
, int id
, int *ret_temp
)
104 int ret
= acpi_active_trip_temp(adev
, id
, &temp_decik
);
106 return thermal_temp(ret
, temp_decik
, ret_temp
);
108 EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp
);
111 * thermal_acpi_passive_trip_temp - Retrieve passive trip point temperature
112 * @adev: Target thermal zone ACPI device object.
113 * @ret_temp: Address to store the retrieved temperature value on success.
115 * Evaluate the _PSV object for the thermal zone represented by @adev to obtain
116 * the temperature of the passive cooling trip point.
118 * Return 0 on success or -ENODATA on failure.
120 int thermal_acpi_passive_trip_temp(struct acpi_device
*adev
, int *ret_temp
)
123 int ret
= acpi_passive_trip_temp(adev
, &temp_decik
);
125 return thermal_temp(ret
, temp_decik
, ret_temp
);
127 EXPORT_SYMBOL_GPL(thermal_acpi_passive_trip_temp
);
130 * thermal_acpi_hot_trip_temp - Retrieve hot trip point temperature
131 * @adev: Target thermal zone ACPI device object.
132 * @ret_temp: Address to store the retrieved temperature value on success.
134 * Evaluate the _HOT object for the thermal zone represented by @adev to obtain
135 * the temperature of the trip point at which the system is expected to be put
136 * into the S4 sleep state.
138 * Return 0 on success or -ENODATA on failure.
140 int thermal_acpi_hot_trip_temp(struct acpi_device
*adev
, int *ret_temp
)
143 int ret
= acpi_hot_trip_temp(adev
, &temp_decik
);
145 return thermal_temp(ret
, temp_decik
, ret_temp
);
147 EXPORT_SYMBOL_GPL(thermal_acpi_hot_trip_temp
);
150 * thermal_acpi_critical_trip_temp - Retrieve critical trip point temperature
151 * @adev: Target thermal zone ACPI device object.
152 * @ret_temp: Address to store the retrieved temperature value on success.
154 * Evaluate the _CRT object for the thermal zone represented by @adev to obtain
155 * the temperature of the critical cooling trip point.
157 * Return 0 on success or -ENODATA on failure.
159 int thermal_acpi_critical_trip_temp(struct acpi_device
*adev
, int *ret_temp
)
162 int ret
= acpi_critical_trip_temp(adev
, &temp_decik
);
164 return thermal_temp(ret
, temp_decik
, ret_temp
);
166 EXPORT_SYMBOL_GPL(thermal_acpi_critical_trip_temp
);