Commit f845351a authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'acpi-thermal'

Merge ACPI thermal zone driver updates for 6.8-rc1:

 - Use generic ACPI helpers for evaluating trip point temperature
   objects in the ACPI thermal zone driver (Rafael J. Wysockii, Arnd
   Bergmann).

 - Add Thermal fast Sampling Period (_TFP) support to the ACPI thermal
   zone driver (Jeff Brasen).

* acpi-thermal:
  ACPI: thermal_lib: include "internal.h" for function prototypes
  ACPI: thermal: Add Thermal fast Sampling Period (_TFP) support
  ACPI: thermal: Use library functions to obtain trip point temperature values
  ACPI: thermal_lib: Add functions returning temperature in deci-Kelvin
  thermal: ACPI: Move the ACPI thermal library to drivers/acpi/
parents f00571b5 b14b2d56
......@@ -61,6 +61,10 @@ config ACPI_CCA_REQUIRED
config ACPI_TABLE_LIB
bool
config ACPI_THERMAL_LIB
depends on THERMAL
bool
config ACPI_DEBUGGER
bool "AML debugger interface"
select ACPI_DEBUG
......@@ -327,6 +331,7 @@ config ACPI_THERMAL
tristate "Thermal Zone"
depends on ACPI_PROCESSOR
select THERMAL
select ACPI_THERMAL_LIB
default y
help
This driver supports ACPI thermal zones. Most mobile and
......
......@@ -89,6 +89,7 @@ obj-$(CONFIG_ACPI_TAD) += acpi_tad.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI) += container.o
obj-$(CONFIG_ACPI_THERMAL_LIB) += thermal_lib.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-$(CONFIG_ACPI_PLATFORM_PROFILE) += platform_profile.o
obj-$(CONFIG_ACPI_NFIT) += nfit/
......
......@@ -85,6 +85,11 @@ bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context);
void acpi_scan_table_notify(void);
int acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp);
int acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp);
int acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp);
int acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp);
#ifdef CONFIG_ARM64
int acpi_arch_thermal_cpufreq_pctg(void);
#else
......
......@@ -31,6 +31,8 @@
#include <linux/uaccess.h>
#include <linux/units.h>
#include "internal.h"
#define ACPI_THERMAL_CLASS "thermal_zone"
#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone"
#define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
......@@ -90,7 +92,7 @@ struct acpi_thermal_passive {
struct acpi_thermal_trip trip;
unsigned long tc1;
unsigned long tc2;
unsigned long tsp;
unsigned long delay;
};
struct acpi_thermal_active {
......@@ -188,24 +190,19 @@ static int active_trip_index(struct acpi_thermal *tz,
static long get_passive_temp(struct acpi_thermal *tz)
{
unsigned long long tmp;
acpi_status status;
int temp;
status = acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, &tmp);
if (ACPI_FAILURE(status))
if (acpi_passive_trip_temp(tz->device, &temp))
return THERMAL_TEMP_INVALID;
return tmp;
return temp;
}
static long get_active_temp(struct acpi_thermal *tz, int index)
{
char method[] = { '_', 'A', 'C', '0' + index, '\0' };
unsigned long long tmp;
acpi_status status;
int temp;
status = acpi_evaluate_integer(tz->device->handle, method, NULL, &tmp);
if (ACPI_FAILURE(status))
if (acpi_active_trip_temp(tz->device, index, &temp))
return THERMAL_TEMP_INVALID;
/*
......@@ -215,10 +212,10 @@ static long get_active_temp(struct acpi_thermal *tz, int index)
if (act > 0) {
unsigned long long override = celsius_to_deci_kelvin(act);
if (tmp > override)
tmp = override;
if (temp > override)
return override;
}
return tmp;
return temp;
}
static void acpi_thermal_update_trip(struct acpi_thermal *tz,
......@@ -337,13 +334,12 @@ static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event)
dev_name(&adev->dev), event, 0);
}
static long acpi_thermal_get_critical_trip(struct acpi_thermal *tz)
static int acpi_thermal_get_critical_trip(struct acpi_thermal *tz)
{
unsigned long long tmp;
acpi_status status;
int temp;
if (crt > 0) {
tmp = celsius_to_deci_kelvin(crt);
temp = celsius_to_deci_kelvin(crt);
goto set;
}
if (crt == -1) {
......@@ -351,38 +347,34 @@ static long acpi_thermal_get_critical_trip(struct acpi_thermal *tz)
return THERMAL_TEMP_INVALID;
}
status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp);
if (ACPI_FAILURE(status)) {
acpi_handle_debug(tz->device->handle, "No critical threshold\n");
if (acpi_critical_trip_temp(tz->device, &temp))
return THERMAL_TEMP_INVALID;
}
if (tmp <= 2732) {
if (temp <= 2732) {
/*
* Below zero (Celsius) values clearly aren't right for sure,
* so discard them as invalid.
*/
pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp);
pr_info(FW_BUG "Invalid critical threshold (%d)\n", temp);
return THERMAL_TEMP_INVALID;
}
set:
acpi_handle_debug(tz->device->handle, "Critical threshold [%llu]\n", tmp);
return tmp;
acpi_handle_debug(tz->device->handle, "Critical threshold [%d]\n", temp);
return temp;
}
static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz)
static int acpi_thermal_get_hot_trip(struct acpi_thermal *tz)
{
unsigned long long tmp;
acpi_status status;
int temp;
status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp);
if (ACPI_FAILURE(status)) {
if (acpi_hot_trip_temp(tz->device, &temp) || temp == THERMAL_TEMP_INVALID) {
acpi_handle_debug(tz->device->handle, "No hot threshold\n");
return THERMAL_TEMP_INVALID;
}
acpi_handle_debug(tz->device->handle, "Hot threshold [%llu]\n", tmp);
return tmp;
acpi_handle_debug(tz->device->handle, "Hot threshold [%d]\n", temp);
return temp;
}
static bool passive_trip_params_init(struct acpi_thermal *tz)
......@@ -402,11 +394,17 @@ static bool passive_trip_params_init(struct acpi_thermal *tz)
tz->trips.passive.tc2 = tmp;
status = acpi_evaluate_integer(tz->device->handle, "_TFP", NULL, &tmp);
if (ACPI_SUCCESS(status)) {
tz->trips.passive.delay = tmp;
return true;
}
status = acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, &tmp);
if (ACPI_FAILURE(status))
return false;
tz->trips.passive.tsp = tmp;
tz->trips.passive.delay = tmp * 100;
return true;
}
......@@ -902,7 +900,7 @@ static int acpi_thermal_add(struct acpi_device *device)
acpi_trip = &tz->trips.passive.trip;
if (acpi_thermal_trip_valid(acpi_trip)) {
passive_delay = tz->trips.passive.tsp * 100;
passive_delay = tz->trips.passive.delay;
trip->type = THERMAL_TRIP_PASSIVE;
trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk);
......@@ -1140,6 +1138,7 @@ static void __exit acpi_thermal_exit(void)
module_init(acpi_thermal_init);
module_exit(acpi_thermal_exit);
MODULE_IMPORT_NS(ACPI_THERMAL);
MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
MODULE_LICENSE("GPL");
......@@ -3,12 +3,13 @@
* Copyright 2023 Linaro Limited
* Copyright 2023 Intel Corporation
*
* Library routines for populating a generic thermal trip point structure
* with data obtained by evaluating a specific object in the ACPI Namespace.
* 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
......@@ -17,11 +18,11 @@
* 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
#define TEMP_MAX_DECIK 4480
#define TEMP_MIN_DECIK 2180ULL
#define TEMP_MAX_DECIK 4480ULL
static int thermal_acpi_trip_temp(struct acpi_device *adev, char *obj_name,
int *ret_temp)
static int acpi_trip_temp(struct acpi_device *adev, char *obj_name,
int *ret_temp)
{
unsigned long long temp;
acpi_status status;
......@@ -33,7 +34,7 @@ static int thermal_acpi_trip_temp(struct acpi_device *adev, char *obj_name,
}
if (temp >= TEMP_MIN_DECIK && temp <= TEMP_MAX_DECIK) {
*ret_temp = deci_kelvin_to_millicelsius(temp);
*ret_temp = temp;
} else {
acpi_handle_debug(adev->handle, "%s result %llu out of range\n",
obj_name, temp);
......@@ -43,6 +44,48 @@ static int thermal_acpi_trip_temp(struct acpi_device *adev, char *obj_name,
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.
......@@ -57,12 +100,10 @@ static int thermal_acpi_trip_temp(struct acpi_device *adev, char *obj_name,
*/
int thermal_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;
int temp_decik;
int ret = acpi_active_trip_temp(adev, id, &temp_decik);
return thermal_acpi_trip_temp(adev, obj_name, ret_temp);
return thermal_temp(ret, temp_decik, ret_temp);
}
EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp);
......@@ -78,7 +119,10 @@ EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp);
*/
int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp)
{
return thermal_acpi_trip_temp(adev, "_PSV", ret_temp);
int temp_decik;
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);
......@@ -95,7 +139,10 @@ EXPORT_SYMBOL_GPL(thermal_acpi_passive_trip_temp);
*/
int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp)
{
return thermal_acpi_trip_temp(adev, "_HOT", ret_temp);
int temp_decik;
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);
......@@ -111,6 +158,9 @@ EXPORT_SYMBOL_GPL(thermal_acpi_hot_trip_temp);
*/
int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp)
{
return thermal_acpi_trip_temp(adev, "_CRT", ret_temp);
int temp_decik;
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);
......@@ -76,10 +76,6 @@ config THERMAL_OF
Say 'Y' here if you need to build thermal infrastructure
based on device tree.
config THERMAL_ACPI
depends on ACPI
bool
config THERMAL_WRITABLE_TRIPS
bool "Enable writable trip points"
help
......
......@@ -13,7 +13,6 @@ 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
thermal_sys-$(CONFIG_THERMAL_ACPI) += thermal_acpi.o
# governors
CFLAGS_gov_power_allocator.o := -I$(src)
......
......@@ -85,7 +85,7 @@ config INTEL_BXT_PMIC_THERMAL
config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
select THERMAL_ACPI if ACPI
select ACPI_THERMAL_LIB if ACPI
help
Enable this to support thermal reporting on certain intel PCHs.
Thermal reporting device will provide temperature reading,
......
......@@ -9,7 +9,7 @@ config INT340X_THERMAL
select THERMAL_GOV_USER_SPACE
select ACPI_THERMAL_REL
select ACPI_FAN
select THERMAL_ACPI
select ACPI_THERMAL_LIB
select INTEL_SOC_DTS_IOSF_CORE
select INTEL_TCC
select PROC_THERMAL_MMIO_RAPL if POWERCAP
......
......@@ -424,6 +424,13 @@ extern int acpi_blacklisted(void);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);
#ifdef CONFIG_ACPI_THERMAL_LIB
int thermal_acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp);
int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp);
int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp);
int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp);
#endif
#ifdef CONFIG_ACPI_NUMA
int acpi_map_pxm_to_node(int pxm);
int acpi_get_node(acpi_handle handle);
......
......@@ -294,13 +294,6 @@ int thermal_zone_get_num_trips(struct thermal_zone_device *tz);
int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp);
#ifdef CONFIG_THERMAL_ACPI
int thermal_acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp);
int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp);
int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp);
int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp);
#endif
#ifdef CONFIG_THERMAL
struct thermal_zone_device *thermal_zone_device_register_with_trips(
const char *type,
......
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