pds_core: Use struct pdsc for the pdsc_adminq_isr private data
[linux-2.6-block.git] / drivers / acpi / thermal_lib.c
CommitLineData
7a0e3974
RW
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2023 Linaro Limited
4 * Copyright 2023 Intel Corporation
5 *
6908097a
RW
6 * Library routines for retrieving trip point temperature values from the
7 * platform firmware via ACPI.
7a0e3974
RW
8 */
9#include <linux/acpi.h>
10#include <linux/units.h>
c27d08f7 11#include <linux/thermal.h>
b14b2d56 12#include "internal.h"
7a0e3974
RW
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 */
6908097a
RW
21#define TEMP_MIN_DECIK 2180ULL
22#define TEMP_MAX_DECIK 4480ULL
7a0e3974 23
6908097a
RW
24static int acpi_trip_temp(struct acpi_device *adev, char *obj_name,
25 int *ret_temp)
7a0e3974
RW
26{
27 unsigned long long temp;
28 acpi_status status;
7a0e3974
RW
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
97efecfd 36 if (temp >= TEMP_MIN_DECIK && temp <= TEMP_MAX_DECIK) {
6908097a 37 *ret_temp = temp;
97efecfd 38 } else {
7a0e3974
RW
39 acpi_handle_debug(adev->handle, "%s result %llu out of range\n",
40 obj_name, temp);
dd3b3d16 41 *ret_temp = THERMAL_TEMP_INVALID;
7a0e3974
RW
42 }
43
7a0e3974
RW
44 return 0;
45}
46
6908097a
RW
47int acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp)
48{
49 char obj_name[] = {'_', 'A', 'C', '0' + id, '\0'};
50
51 if (id < 0 || id > 9)
52 return -EINVAL;
53
54 return acpi_trip_temp(adev, obj_name, ret_temp);
55}
9c864722 56EXPORT_SYMBOL_NS_GPL(acpi_active_trip_temp, ACPI_THERMAL);
6908097a
RW
57
58int acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp)
59{
60 return acpi_trip_temp(adev, "_PSV", ret_temp);
61}
9c864722 62EXPORT_SYMBOL_NS_GPL(acpi_passive_trip_temp, ACPI_THERMAL);
6908097a
RW
63
64int acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp)
65{
66 return acpi_trip_temp(adev, "_HOT", ret_temp);
67}
9c864722 68EXPORT_SYMBOL_NS_GPL(acpi_hot_trip_temp, ACPI_THERMAL);
6908097a
RW
69
70int acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp)
71{
72 return acpi_trip_temp(adev, "_CRT", ret_temp);
73}
9c864722 74EXPORT_SYMBOL_NS_GPL(acpi_critical_trip_temp, ACPI_THERMAL);
6908097a
RW
75
76static int thermal_temp(int error, int temp_decik, int *ret_temp)
77{
78 if (error)
79 return error;
80
81 if (temp_decik == THERMAL_TEMP_INVALID)
82 *ret_temp = THERMAL_TEMP_INVALID;
83 else
84 *ret_temp = deci_kelvin_to_millicelsius(temp_decik);
85
86 return 0;
87}
88
7a0e3974 89/**
dd3b3d16
RW
90 * thermal_acpi_active_trip_temp - Retrieve active trip point temperature
91 * @adev: Target thermal zone ACPI device object.
7a0e3974 92 * @id: Active cooling level (0 - 9).
dd3b3d16 93 * @ret_temp: Address to store the retrieved temperature value on success.
7a0e3974
RW
94 *
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
dd3b3d16 97 * cooling level given by @id.
7a0e3974
RW
98 *
99 * Return 0 on success or a negative error value on failure.
100 */
dd3b3d16 101int thermal_acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp)
7a0e3974 102{
6908097a
RW
103 int temp_decik;
104 int ret = acpi_active_trip_temp(adev, id, &temp_decik);
dd3b3d16 105
6908097a 106 return thermal_temp(ret, temp_decik, ret_temp);
7a0e3974 107}
dd3b3d16 108EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp);
7a0e3974
RW
109
110/**
dd3b3d16
RW
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.
7a0e3974
RW
114 *
115 * Evaluate the _PSV object for the thermal zone represented by @adev to obtain
dd3b3d16 116 * the temperature of the passive cooling trip point.
7a0e3974
RW
117 *
118 * Return 0 on success or -ENODATA on failure.
119 */
dd3b3d16 120int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp)
7a0e3974 121{
6908097a
RW
122 int temp_decik;
123 int ret = acpi_passive_trip_temp(adev, &temp_decik);
124
125 return thermal_temp(ret, temp_decik, ret_temp);
7a0e3974 126}
dd3b3d16 127EXPORT_SYMBOL_GPL(thermal_acpi_passive_trip_temp);
7a0e3974
RW
128
129/**
dd3b3d16
RW
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.
7a0e3974
RW
133 *
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
dd3b3d16 136 * into the S4 sleep state.
7a0e3974
RW
137 *
138 * Return 0 on success or -ENODATA on failure.
139 */
dd3b3d16 140int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp)
7a0e3974 141{
6908097a
RW
142 int temp_decik;
143 int ret = acpi_hot_trip_temp(adev, &temp_decik);
144
145 return thermal_temp(ret, temp_decik, ret_temp);
7a0e3974 146}
dd3b3d16 147EXPORT_SYMBOL_GPL(thermal_acpi_hot_trip_temp);
7a0e3974
RW
148
149/**
dd3b3d16
RW
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.
7a0e3974
RW
153 *
154 * Evaluate the _CRT object for the thermal zone represented by @adev to obtain
dd3b3d16 155 * the temperature of the critical cooling trip point.
7a0e3974
RW
156 *
157 * Return 0 on success or -ENODATA on failure.
158 */
dd3b3d16 159int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp)
7a0e3974 160{
6908097a
RW
161 int temp_decik;
162 int ret = acpi_critical_trip_temp(adev, &temp_decik);
163
164 return thermal_temp(ret, temp_decik, ret_temp);
7a0e3974 165}
dd3b3d16 166EXPORT_SYMBOL_GPL(thermal_acpi_critical_trip_temp);