drivers/acpi/thermal_lib.c

Source file repositories/reference/linux-study-clean/drivers/acpi/thermal_lib.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/thermal_lib.c
Extension
.c
Size
5129 bytes
Lines
167
Domain
Driver Families
Bucket
drivers/acpi
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// 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	2180ULL
#define TEMP_MAX_DECIK	4480ULL

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

Annotation

Implementation Notes