1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2023 Linaro Limited 4 * Copyright 2023 Intel Corporation 5 * 6 * Library routines for populating a generic thermal trip point structure 7 * with data obtained by evaluating a specific object in the ACPI Namespace. 8 */ 9 #include <linux/acpi.h> 10 #include <linux/units.h> 11 12 #include "thermal_core.h" 13 14 /* 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. 20 */ 21 #define TEMP_MIN_DECIK 2180 22 #define TEMP_MAX_DECIK 4480 23 24 static int thermal_acpi_trip_temp(struct acpi_device *adev, char *obj_name, 25 int *ret_temp) 26 { 27 unsigned long long temp; 28 acpi_status status; 29 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); 33 return -ENODATA; 34 } 35 36 if (temp >= TEMP_MIN_DECIK && temp <= TEMP_MAX_DECIK) { 37 *ret_temp = deci_kelvin_to_millicelsius(temp); 38 } else { 39 acpi_handle_debug(adev->handle, "%s result %llu out of range\n", 40 obj_name, temp); 41 *ret_temp = THERMAL_TEMP_INVALID; 42 } 43 44 return 0; 45 } 46 47 /** 48 * thermal_acpi_active_trip_temp - Retrieve active trip point temperature 49 * @adev: Target thermal zone ACPI device object. 50 * @id: Active cooling level (0 - 9). 51 * @ret_temp: Address to store the retrieved temperature value on success. 52 * 53 * Evaluate the _ACx object for the thermal zone represented by @adev to obtain 54 * the temperature of the active cooling trip point corresponding to the active 55 * cooling level given by @id. 56 * 57 * Return 0 on success or a negative error value on failure. 58 */ 59 int thermal_acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp) 60 { 61 char obj_name[] = {'_', 'A', 'C', '0' + id, '\0'}; 62 63 if (id < 0 || id > 9) 64 return -EINVAL; 65 66 return thermal_acpi_trip_temp(adev, obj_name, ret_temp); 67 } 68 EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp); 69 70 /** 71 * thermal_acpi_passive_trip_temp - Retrieve passive trip point temperature 72 * @adev: Target thermal zone ACPI device object. 73 * @ret_temp: Address to store the retrieved temperature value on success. 74 * 75 * Evaluate the _PSV object for the thermal zone represented by @adev to obtain 76 * the temperature of the passive cooling trip point. 77 * 78 * Return 0 on success or -ENODATA on failure. 79 */ 80 int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp) 81 { 82 return thermal_acpi_trip_temp(adev, "_PSV", ret_temp); 83 } 84 EXPORT_SYMBOL_GPL(thermal_acpi_passive_trip_temp); 85 86 /** 87 * thermal_acpi_hot_trip_temp - Retrieve hot trip point temperature 88 * @adev: Target thermal zone ACPI device object. 89 * @ret_temp: Address to store the retrieved temperature value on success. 90 * 91 * Evaluate the _HOT object for the thermal zone represented by @adev to obtain 92 * the temperature of the trip point at which the system is expected to be put 93 * into the S4 sleep state. 94 * 95 * Return 0 on success or -ENODATA on failure. 96 */ 97 int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp) 98 { 99 return thermal_acpi_trip_temp(adev, "_HOT", ret_temp); 100 } 101 EXPORT_SYMBOL_GPL(thermal_acpi_hot_trip_temp); 102 103 /** 104 * thermal_acpi_critical_trip_temp - Retrieve critical trip point temperature 105 * @adev: Target thermal zone ACPI device object. 106 * @ret_temp: Address to store the retrieved temperature value on success. 107 * 108 * Evaluate the _CRT object for the thermal zone represented by @adev to obtain 109 * the temperature of the critical cooling trip point. 110 * 111 * Return 0 on success or -ENODATA on failure. 112 */ 113 int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp) 114 { 115 return thermal_acpi_trip_temp(adev, "_CRT", ret_temp); 116 } 117 EXPORT_SYMBOL_GPL(thermal_acpi_critical_trip_temp); 118