// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2023 Linaro Limited
* Copyright 2023 Intel Corporation
*
* Library routines for retrieving trip point temperature values from the
* platform firmware via ACPI .
*/
#include <linux/acpi.h>
#include <linux/units.h>
#include <linux/thermal.h>
#include "internal.h"
/*
* Minimum temperature for full military grade is 218 ° K ( - 55 ° C ) and
* max temperature is 448 ° K ( 175 ° C ) . We can consider those values as
* the boundaries for the [ trips ] temperature returned by the
* firmware . Any values out of these boundaries may be considered
* bogus and we can assume the firmware has no data to provide .
*/
#define TEMP_MIN_DECIK 2180 ULL
#define TEMP_MAX_DECIK 4480 ULL
static int acpi_trip_temp(struct acpi_device *adev, char *obj_name,
int *ret_temp)
{
unsigned long long temp;
acpi_status status;
status = acpi_evaluate_integer(adev->handle, obj_name, NULL, &temp);
if (ACPI_FAILURE(status)) {
acpi_handle_debug(adev->handle, "%s evaluation failed\n" , obj_name);
return -ENODATA;
}
if (temp >= TEMP_MIN_DECIK && temp <= TEMP_MAX_DECIK) {
*ret_temp = temp;
} else {
acpi_handle_debug(adev->handle, "%s result %llu out of range\n" ,
obj_name, temp);
*ret_temp = THERMAL_TEMP_INVALID;
}
return 0 ;
}
int acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp)
{
char obj_name[] = {'_' , 'A' , 'C' , '0' + id, '\0' };
if (id < 0 || id > 9 )
return -EINVAL;
return acpi_trip_temp(adev, obj_name, ret_temp);
}
EXPORT_SYMBOL_NS_GPL(acpi_active_trip_temp, "ACPI_THERMAL" );
int acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp)
{
return acpi_trip_temp(adev, "_PSV" , ret_temp);
}
EXPORT_SYMBOL_NS_GPL(acpi_passive_trip_temp, "ACPI_THERMAL" );
int acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp)
{
return acpi_trip_temp(adev, "_HOT" , ret_temp);
}
EXPORT_SYMBOL_NS_GPL(acpi_hot_trip_temp, "ACPI_THERMAL" );
int acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp)
{
return acpi_trip_temp(adev, "_CRT" , ret_temp);
}
EXPORT_SYMBOL_NS_GPL(acpi_critical_trip_temp, "ACPI_THERMAL" );
static int thermal_temp(int error, int temp_decik, int *ret_temp)
{
if (error)
return error;
if (temp_decik == THERMAL_TEMP_INVALID)
*ret_temp = THERMAL_TEMP_INVALID;
else
*ret_temp = deci_kelvin_to_millicelsius(temp_decik);
return 0 ;
}
/**
* thermal_acpi_active_trip_temp - Retrieve active trip point temperature
* @ adev : Target thermal zone ACPI device object .
* @ id : Active cooling level ( 0 - 9 ) .
* @ ret_temp : Address to store the retrieved temperature value on success .
*
* Evaluate the _ ACx object for the thermal zone represented by @ adev to obtain
* the temperature of the active cooling trip point corresponding to the active
* cooling level given by @ id .
*
* Return 0 on success or a negative error value on failure .
*/
int thermal_acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp)
{
int temp_decik = 0 ;
int ret = acpi_active_trip_temp(adev, id, &temp_decik);
return thermal_temp(ret, temp_decik, ret_temp);
}
EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp);
/**
* thermal_acpi_passive_trip_temp - Retrieve passive trip point temperature
* @ adev : Target thermal zone ACPI device object .
* @ ret_temp : Address to store the retrieved temperature value on success .
*
* Evaluate the _ PSV object for the thermal zone represented by @ adev to obtain
* the temperature of the passive cooling trip point .
*
* Return 0 on success or - ENODATA on failure .
*/
int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp)
{
int temp_decik = 0 ;
int ret = acpi_passive_trip_temp(adev, &temp_decik);
return thermal_temp(ret, temp_decik, ret_temp);
}
EXPORT_SYMBOL_GPL(thermal_acpi_passive_trip_temp);
/**
* thermal_acpi_hot_trip_temp - Retrieve hot trip point temperature
* @ adev : Target thermal zone ACPI device object .
* @ ret_temp : Address to store the retrieved temperature value on success .
*
* Evaluate the _ HOT object for the thermal zone represented by @ adev to obtain
* the temperature of the trip point at which the system is expected to be put
* into the S4 sleep state .
*
* Return 0 on success or - ENODATA on failure .
*/
int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp)
{
int temp_decik = 0 ;
int ret = acpi_hot_trip_temp(adev, &temp_decik);
return thermal_temp(ret, temp_decik, ret_temp);
}
EXPORT_SYMBOL_GPL(thermal_acpi_hot_trip_temp);
/**
* thermal_acpi_critical_trip_temp - Retrieve critical trip point temperature
* @ adev : Target thermal zone ACPI device object .
* @ ret_temp : Address to store the retrieved temperature value on success .
*
* Evaluate the _ CRT object for the thermal zone represented by @ adev to obtain
* the temperature of the critical cooling trip point .
*
* Return 0 on success or - ENODATA on failure .
*/
int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp)
{
int temp_decik = 0 ;
int ret = acpi_critical_trip_temp(adev, &temp_decik);
return thermal_temp(ret, temp_decik, ret_temp);
}
EXPORT_SYMBOL_GPL(thermal_acpi_critical_trip_temp);
Messung V0.5 in Prozent C=96 H=100 G=97
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland