Merge branches 'acpica' and 'acpi-thermal'

Merge ACPICA updates and ACPI thermal control updates for 7.4:

 - Add IOVT IOMMU support to ACPICA (Bibo Mao)

 - Fix PCC OperationRegion command offsets in ACPICA (Sudeep Holla)

 - Fix memory leak in acpi_ds_create_field() related to the handling of
   internal_pcc_buffer allocations (Breno Leitao)

 - Fix memory leak due to leftover devm_kcalloc() argument in the ACPI
   fan driver (Rafael Wysocki)

 - Fix backlight unregistration ordering in the ACPI video bus device
   driver (Rafael Wysocki)

 - Update the thermal core to allow the registration of thermal class
   cooling devices under specific parents and convert the ACPI fan,
   ACPI processor, and ACPI video bus device drivers to do so (Rafael
   Wysocki)

 - Adjust the ACPI thermal zone driver to use thermal class cooling
   device parent information for binding cooling devices to trip points
   in thermal zones (Rafael Wysocki)

 - Use cooling device data that is a better match for a given driver
   instread of a struct acpi_device pointer that had to be used for
   this purpose previously in the ACPI fan and processor drivers (Rafael
   Wysocki)

 - Fix acpi_thermal_guess_offset() in the ACPI thermal zone driver for
   thermal zone devices with a 273.0°K offset (Hans de Goede)

 - Define a free for ACPI objects allocated by ACPICA helpers and use
   it to simplify AML error handling in the ACPI fan driver (Rafael
   Wysocki)

* acpica:
  ACPICA: actbl2.h: Add bit constants of the Flags field in the IOVT IOMMU structure
  ACPICA: Fix PCC OperationRegion command offsets
  ACPICA: Fix memory leak in acpi_ds_create_field()

* acpi-thermal:
  ACPI: fan: Use __free() to simplify AML error handling
  ACPI: thermal: Fix acpi_thermal_guess_offset() for device with a 273.0°K offset
  ACPI: fan: Use more suitable cooling device data
  ACPI: fan: Store ACPI device pointer in struct acpi_fan
  ACPI: processor: thermal: Use more suitable cooling device data
  ACPI: thermal: Use cooling device parent for thermal zone binding
  ACPI: fan: Use thermal_cooling_device_create()
  ACPI: video: Use thermal_cooling_device_create()
  ACPI: processor: thermal: Use thermal_cooling_device_create()
  thermal: core: Introduce thermal_cooling_device_create()
  ACPI: video: Fix backlight unregistration ordering
  ACPI: fan: Fix memory leak due to leftover devm_kcalloc() argument
This commit is contained in:
Rafael J. Wysocki 2026-10-19 13:30:25 +02:00
commit 5a44bb4863
16 changed files with 150 additions and 230 deletions

View File

@ -1700,9 +1700,9 @@ static int acpi_video_resume(struct notifier_block *nb,
static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
{
struct device *phys_dev, *parent = NULL;
struct backlight_properties props;
struct pci_dev *pdev;
struct device *parent = NULL;
int result;
static int count;
char *name;
@ -1729,11 +1729,10 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
device,
&acpi_backlight_ops,
&props);
put_device(parent);
kfree(name);
if (IS_ERR(device->backlight)) {
device->backlight = NULL;
return;
goto put_parent;
}
/*
@ -1743,8 +1742,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
device->backlight->props.brightness =
acpi_video_get_brightness(device->backlight);
device->cooling_dev = thermal_cooling_device_register("LCD", device,
&video_cooling_ops);
phys_dev = acpi_bus_get_primary_device(device->dev);
if (!phys_dev)
phys_dev = get_device(parent);
device->cooling_dev = thermal_cooling_device_create(phys_dev, "LCD", device,
&video_cooling_ops);
if (IS_ERR(device->cooling_dev)) {
/*
* Set cooling_dev to NULL so we don't crash trying to free it.
@ -1753,21 +1756,17 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
* -- dtor
*/
device->cooling_dev = NULL;
return;
goto put_phys_dev;
}
dev_info(&device->dev->dev, "registered as cooling_device%d\n",
device->cooling_dev->id);
result = sysfs_create_link(&device->dev->dev.kobj,
&device->cooling_dev->device.kobj,
"thermal_cooling");
if (result)
pr_info("sysfs link creation failed\n");
dev_info(&device->cooling_dev->device, "Using ACPI device %s\n",
acpi_dev_name(device->dev));
result = sysfs_create_link(&device->cooling_dev->device.kobj,
&device->dev->dev.kobj, "device");
if (result)
pr_info("Reverse sysfs link creation failed\n");
put_phys_dev:
put_device(phys_dev);
put_parent:
put_device(parent);
}
static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video)
@ -1825,6 +1824,10 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device)
{
if (device->cooling_dev) {
thermal_cooling_device_unregister(device->cooling_dev);
device->cooling_dev = NULL;
}
if (device->backlight) {
backlight_device_unregister(device->backlight);
device->backlight = NULL;
@ -1834,12 +1837,6 @@ static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device
kfree(device->brightness);
device->brightness = NULL;
}
if (device->cooling_dev) {
sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling");
sysfs_remove_link(&device->cooling_dev->device.kobj, "device");
thermal_cooling_device_unregister(device->cooling_dev);
device->cooling_dev = NULL;
}
}
static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video)

View File

@ -522,7 +522,8 @@ acpi_ds_create_field(union acpi_parse_object *op,
}
if (info.region_node->object->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_COMM) {
ACPI_ADR_SPACE_PLATFORM_COMM &&
!region_node->object->field.internal_pcc_buffer) {
region_node->object->field.internal_pcc_buffer =
ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
length);

View File

@ -45,12 +45,13 @@ static const u8 acpi_protocol_lengths[] = {
/*
* The following macros determine a given offset is a COMD field.
* According to the specification, generic subspaces (types 0-2) contains a
* 2-byte COMD field at offset 4 and master subspaces (type 3) contains a 4-byte
* COMD field starting at offset 12.
* According to the specification, the PCC OperationRegion begins after
* the PCC signature. The raw shared memory COMD offsets of 4 for generic
* subspaces (types 0-2) and 12 for master subspaces (type 3) therefore
* appear at OperationRegion offsets 0 and 8.
*/
#define GENERIC_SUBSPACE_COMMAND(a) (4 == a || a == 5)
#define MASTER_SUBSPACE_COMMAND(a) (12 <= a && a <= 15)
#define GENERIC_SUBSPACE_COMMAND(a) (0 == a || a == 1)
#define MASTER_SUBSPACE_COMMAND(a) (8 <= a && a <= 11)
/*******************************************************************************
*

View File

@ -52,7 +52,7 @@ struct acpi_fan_fst {
};
struct acpi_fan {
acpi_handle handle;
struct acpi_device *adev;
bool acpi4;
bool has_fst;
struct acpi_fan_fif fif;

View File

@ -54,8 +54,7 @@ MODULE_DEVICE_TABLE(acpi, fan_device_ids);
static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
*state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_fan *fan = cdev->devdata;
if (fan->acpi4) {
if (fan->fif.fine_grain_ctrl)
@ -72,42 +71,34 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
int ret = 0;
status = acpi_evaluate_object(handle, "_FST", NULL, &buffer);
if (ACPI_FAILURE(status))
return -EIO;
return -ENXIO;
obj = buffer.pointer;
union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
if (!obj)
return -ENODATA;
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) {
ret = -EPROTO;
goto err;
}
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3)
return -EPROTO;
if (obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
obj->package.elements[1].type != ACPI_TYPE_INTEGER ||
obj->package.elements[2].type != ACPI_TYPE_INTEGER) {
ret = -EPROTO;
goto err;
}
obj->package.elements[2].type != ACPI_TYPE_INTEGER)
return -EPROTO;
fst->revision = obj->package.elements[0].integer.value;
fst->control = obj->package.elements[1].integer.value;
fst->speed = obj->package.elements[2].integer.value;
err:
kfree(obj);
return ret;
return 0;
}
static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
static int fan_get_state_acpi4(struct acpi_fan *fan, unsigned long *state)
{
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_device *device = fan->adev;
struct acpi_fan_fst fst;
int status, i;
@ -159,13 +150,12 @@ static int fan_get_state(struct acpi_device *device, unsigned long *state)
static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
*state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_fan *fan = cdev->devdata;
if (fan->acpi4)
return fan_get_state_acpi4(device, state);
return fan_get_state_acpi4(fan, state);
else
return fan_get_state(device, state);
return fan_get_state(fan->adev, state);
}
static int fan_set_state(struct acpi_device *device, unsigned long state)
@ -177,9 +167,9 @@ static int fan_set_state(struct acpi_device *device, unsigned long state)
state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
}
static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
static int fan_set_state_acpi4(struct acpi_fan *fan, unsigned long state)
{
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_device *device = fan->adev;
acpi_status status;
u64 value = state;
int max_state;
@ -213,13 +203,12 @@ static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
static int
fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_fan *fan = cdev->devdata;
if (fan->acpi4)
return fan_set_state_acpi4(device, state);
return fan_set_state_acpi4(fan, state);
else
return fan_set_state(device, state);
return fan_set_state(fan->adev, state);
}
static const struct thermal_cooling_device_ops fan_cooling_ops = {
@ -240,25 +229,22 @@ static int acpi_fan_get_fif(struct acpi_device *device)
struct acpi_buffer format = { sizeof("NNNN"), "NNNN" };
u64 fields[4];
struct acpi_buffer fif = { sizeof(fields), fields };
union acpi_object *obj;
acpi_status status;
status = acpi_evaluate_object(device->handle, "_FIF", NULL, &buffer);
if (ACPI_FAILURE(status))
return status;
return -ENXIO;
obj = buffer.pointer;
union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
if (!obj || obj->type != ACPI_TYPE_PACKAGE) {
dev_err(&device->dev, "Invalid _FIF data\n");
status = -EINVAL;
goto err;
return -ENODATA;
}
status = acpi_extract_package(obj, &format, &fif);
if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "Invalid _FIF element\n");
status = -EINVAL;
goto err;
return -ENODATA;
}
fan->fif.revision = fields[0];
@ -272,9 +258,8 @@ static int acpi_fan_get_fif(struct acpi_device *device)
/* If step size > 9, change to 9 (by spec valid values 1-9) */
else if (fan->fif.step_size > 9)
fan->fif.step_size = 9;
err:
kfree(obj);
return status;
return 0;
}
static int acpi_fan_speed_cmp(const void *a, const void *b)
@ -284,34 +269,28 @@ static int acpi_fan_speed_cmp(const void *a, const void *b)
return fps1->speed - fps2->speed;
}
static int acpi_fan_get_fps(struct acpi_device *device)
static int acpi_fan_get_fps(struct device *dev, struct acpi_device *device)
{
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
int i;
status = acpi_evaluate_object(device->handle, "_FPS", NULL, &buffer);
if (ACPI_FAILURE(status))
return status;
return -ENXIO;
obj = buffer.pointer;
union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) {
dev_err(&device->dev, "Invalid _FPS data\n");
status = -EINVAL;
goto err;
return -ENODATA;
}
fan->fps_count = obj->package.count - 1; /* minus revision field */
fan->fps = devm_kcalloc(&device->dev,
fan->fps_count, sizeof(struct acpi_fan_fps),
GFP_KERNEL);
if (!fan->fps) {
dev_err(&device->dev, "Not enough memory\n");
status = -ENOMEM;
goto err;
}
fan->fps = devm_kcalloc(dev, fan->fps_count, sizeof(*fan->fps), GFP_KERNEL);
if (!fan->fps)
return -ENOMEM;
for (i = 0; i < fan->fps_count; i++) {
struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
struct acpi_buffer fps = { offsetof(struct acpi_fan_fps, name),
@ -320,7 +299,7 @@ static int acpi_fan_get_fps(struct acpi_device *device)
&format, &fps);
if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "Invalid _FPS element\n");
goto err;
return -ENODATA;
}
}
@ -328,9 +307,7 @@ static int acpi_fan_get_fps(struct acpi_device *device)
sort(fan->fps, fan->fps_count, sizeof(*fan->fps),
acpi_fan_speed_cmp, NULL);
err:
kfree(obj);
return status;
return 0;
}
static int acpi_fan_dsm_init(struct device *dev)
@ -343,30 +320,28 @@ static int acpi_fan_dsm_init(struct device *dev)
},
};
struct acpi_fan *fan = dev_get_drvdata(dev);
union acpi_object *obj;
int ret = 0;
acpi_handle fan_handle = fan->adev->handle;
if (!acpi_check_dsm(fan->handle, &acpi_fan_microsoft_guid, 0,
if (!acpi_check_dsm(fan_handle, &acpi_fan_microsoft_guid, 0,
BIT(ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY) |
BIT(ACPI_FAN_DSM_SET_TRIP_POINTS)))
return 0;
dev_info(dev, "Using Microsoft fan extensions\n");
obj = acpi_evaluate_dsm_typed(fan->handle, &acpi_fan_microsoft_guid, 0,
ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY, &dummy,
ACPI_TYPE_INTEGER);
union acpi_object *obj __free(acpi_object_free) =
acpi_evaluate_dsm_typed(fan_handle, &acpi_fan_microsoft_guid, 0,
ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY,
&dummy, ACPI_TYPE_INTEGER);
if (!obj)
return -EIO;
return -ENXIO;
if (obj->integer.value > U32_MAX)
ret = -EOVERFLOW;
else
fan->fan_trip_granularity = obj->integer.value;
return -EOVERFLOW;
kfree(obj);
fan->fan_trip_granularity = obj->integer.value;
return ret;
return 0;
}
static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower)
@ -395,9 +370,9 @@ static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower
};
union acpi_object *obj;
obj = acpi_evaluate_dsm(fan->handle, &acpi_fan_microsoft_guid, 0,
ACPI_FAN_DSM_SET_TRIP_POINTS, &in);
kfree(obj);
obj = acpi_evaluate_dsm(fan->adev->handle, &acpi_fan_microsoft_guid,
0, ACPI_FAN_DSM_SET_TRIP_POINTS, &in);
ACPI_FREE(obj);
return 0;
}
@ -506,7 +481,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
return -ENOMEM;
}
fan->handle = device->handle;
fan->adev = device;
device->driver_data = fan;
platform_set_drvdata(pdev, fan);
@ -522,7 +497,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
if (result)
return result;
result = acpi_fan_get_fps(device);
result = acpi_fan_get_fps(&pdev->dev, device);
if (result)
return result;
}
@ -567,8 +542,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
else
name = acpi_device_bid(device);
cdev = thermal_cooling_device_register(name, device,
&fan_cooling_ops);
cdev = thermal_cooling_device_create(&pdev->dev, name, fan, &fan_cooling_ops);
if (IS_ERR(cdev)) {
result = PTR_ERR(cdev);
goto err_end;
@ -577,28 +551,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id);
fan->cdev = cdev;
result = sysfs_create_link(&pdev->dev.kobj,
&cdev->device.kobj,
"thermal_cooling");
if (result) {
dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
goto err_unregister;
}
result = sysfs_create_link(&cdev->device.kobj,
&pdev->dev.kobj,
"device");
if (result) {
dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
goto err_remove_link;
}
return 0;
err_remove_link:
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
err_unregister:
thermal_cooling_device_unregister(cdev);
err_end:
if (fan->has_fst)
acpi_fan_delete_attributes(device);
@ -615,8 +570,6 @@ static void acpi_fan_remove(struct platform_device *pdev)
acpi_fan_delete_attributes(device);
}
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
sysfs_remove_link(&fan->cdev->device.kobj, "device");
thermal_cooling_device_unregister(fan->cdev);
}

View File

@ -94,7 +94,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
struct acpi_fan_fst fst;
int ret;
ret = acpi_fan_get_fst(fan->handle, &fst);
ret = acpi_fan_get_fst(fan->adev->handle, &fst);
if (ret < 0)
return ret;

View File

@ -164,7 +164,7 @@ static int __acpi_processor_start(struct acpi_device *device)
acpi_pss_perf_init(pr);
result = acpi_processor_thermal_init(pr, device);
result = acpi_processor_thermal_init(pr);
if (result)
goto err_power_exit;
@ -179,7 +179,7 @@ static int __acpi_processor_start(struct acpi_device *device)
return 0;
err_thermal_exit:
acpi_processor_thermal_exit(pr, device);
acpi_processor_thermal_exit(pr);
err_power_exit:
acpi_processor_power_exit(pr);
return result;
@ -203,7 +203,7 @@ static int acpi_processor_stop(struct device *dev)
acpi_cppc_processor_exit(pr);
acpi_processor_thermal_exit(pr, device);
acpi_processor_thermal_exit(pr);
return 0;
}

View File

@ -235,15 +235,7 @@ static int
processor_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr;
if (!device)
return -EINVAL;
pr = acpi_driver_data(device);
if (!pr)
return -EINVAL;
struct acpi_processor *pr = cdev->devdata;
*state = acpi_processor_max_state(pr);
return 0;
@ -253,15 +245,7 @@ static int
processor_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *cur_state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr;
if (!device)
return -EINVAL;
pr = acpi_driver_data(device);
if (!pr)
return -EINVAL;
struct acpi_processor *pr = cdev->devdata;
*cur_state = cpufreq_get_cur_state(pr->id);
if (pr->flags.throttling)
@ -273,18 +257,10 @@ static int
processor_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr;
struct acpi_processor *pr = cdev->devdata;
int result = 0;
int max_pstate;
if (!device)
return -EINVAL;
pr = acpi_driver_data(device);
if (!pr)
return -EINVAL;
max_pstate = cpufreq_get_max_state(pr->id);
if (state > acpi_processor_max_state(pr))
@ -308,55 +284,21 @@ const struct thermal_cooling_device_ops processor_cooling_ops = {
.set_cur_state = processor_set_cur_state,
};
int acpi_processor_thermal_init(struct acpi_processor *pr,
struct acpi_device *device)
int acpi_processor_thermal_init(struct acpi_processor *pr)
{
int result = 0;
pr->cdev = thermal_cooling_device_create(pr->dev, "Processor", pr,
&processor_cooling_ops);
if (IS_ERR(pr->cdev))
return PTR_ERR(pr->cdev);
pr->cdev = thermal_cooling_device_register("Processor", device,
&processor_cooling_ops);
if (IS_ERR(pr->cdev)) {
result = PTR_ERR(pr->cdev);
return result;
}
dev_dbg(&device->dev, "registered as cooling_device%d\n",
pr->cdev->id);
result = sysfs_create_link(&device->dev.kobj,
&pr->cdev->device.kobj,
"thermal_cooling");
if (result) {
dev_err(&device->dev,
"Failed to create sysfs link 'thermal_cooling'\n");
goto err_thermal_unregister;
}
result = sysfs_create_link(&pr->cdev->device.kobj,
&device->dev.kobj,
"device");
if (result) {
dev_err(&pr->cdev->device,
"Failed to create sysfs link 'device'\n");
goto err_remove_sysfs_thermal;
}
dev_dbg(pr->dev, "registered as cooling_device%d\n", pr->cdev->id);
return 0;
err_remove_sysfs_thermal:
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
err_thermal_unregister:
thermal_cooling_device_unregister(pr->cdev);
return result;
}
void acpi_processor_thermal_exit(struct acpi_processor *pr,
struct acpi_device *device)
void acpi_processor_thermal_exit(struct acpi_processor *pr)
{
if (pr->cdev) {
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
sysfs_remove_link(&pr->cdev->device.kobj, "device");
if (!IS_ERR_OR_NULL(pr->cdev)) {
thermal_cooling_device_unregister(pr->cdev);
pr->cdev = NULL;
}

View File

@ -564,17 +564,20 @@ static bool acpi_thermal_should_bind_cdev(struct thermal_zone_device *thermal,
struct cooling_spec *c)
{
struct acpi_thermal_trip *acpi_trip = trip->priv;
struct acpi_device *cdev_adev = cdev->devdata;
struct device *parent = cdev->device.parent;
acpi_handle parent_handle;
int i;
/* Skip critical and hot trips. */
if (!acpi_trip)
/* Skip critical and hot trips and parentless cooling devices. */
if (!acpi_trip || !parent)
return false;
parent_handle = ACPI_HANDLE(parent);
if (!parent_handle)
return false;
for (i = 0; i < acpi_trip->devices.count; i++) {
acpi_handle handle = acpi_trip->devices.handles[i];
if (acpi_fetch_acpi_dev(handle) == cdev_adev)
if (acpi_trip->devices.handles[i] == parent_handle)
return true;
}
@ -738,7 +741,9 @@ static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
*/
static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp)
{
if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1)
if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 0)
tz->kelvin_offset = 273000;
else if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1)
tz->kelvin_offset = 273100;
else
tz->kelvin_offset = 273200;

View File

@ -1005,7 +1005,8 @@ thermal_cooling_device_alloc(const char *type, const struct thermal_cooling_devi
return ERR_PTR(ret);
}
int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdata)
int thermal_cooling_device_add(struct thermal_cooling_device *cdev,
struct device *parent, void *devdata)
{
unsigned long current_state;
int ret;
@ -1013,6 +1014,7 @@ int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdat
mutex_init(&cdev->lock);
INIT_LIST_HEAD(&cdev->thermal_instances);
cdev->updated = false;
cdev->device.parent = parent;
cdev->device.class = &thermal_class;
cdev->device.release = thermal_cdev_release;
device_initialize(&cdev->device);
@ -1062,21 +1064,23 @@ int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdat
}
/**
* thermal_cooling_device_register() - register a new thermal cooling device
* thermal_cooling_device_create() - register a new thermal cooling device
* @parent: parent device (optional).
* @type: the thermal cooling device type.
* @devdata: device private data.
* @ops: standard thermal cooling devices callbacks.
*
* This interface function adds a new thermal cooling device (fan/processor/...)
* to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
* to all the thermal zone devices registered at the same time.
* Allocate and register a new thermal cooling device under the given parent (if
* not NULL) and with the given type, device data, and operations. During the
* registration, it will be matched against all of the registered thermal zones
* and it will be bound to the matching ones.
*
* Return: a pointer to the created struct thermal_cooling_device or an
* ERR_PTR. Caller must check return value with IS_ERR*() helpers.
* Return: A pointer to the created struct thermal_cooling_device or an ERR_PTR.
* Callers must use IS_ERR*() helpers to check the return value.
*/
struct thermal_cooling_device *
thermal_cooling_device_register(const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
struct thermal_cooling_device *thermal_cooling_device_create(
struct device *parent, const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
{
struct thermal_cooling_device *cdev;
int ret;
@ -1085,13 +1089,13 @@ thermal_cooling_device_register(const char *type, void *devdata,
if (IS_ERR(cdev))
return cdev;
ret = thermal_cooling_device_add(cdev, devdata);
ret = thermal_cooling_device_add(cdev, parent, devdata);
if (ret)
return ERR_PTR(ret);
return cdev;
}
EXPORT_SYMBOL_GPL(thermal_cooling_device_register);
EXPORT_SYMBOL_GPL(thermal_cooling_device_create);
static void thermal_cooling_device_release(void *data)
{

View File

@ -270,7 +270,8 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
struct thermal_cooling_device *
thermal_cooling_device_alloc(const char *type, const struct thermal_cooling_device_ops *ops);
int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdata);
int thermal_cooling_device_add(struct thermal_cooling_device *cdev,
struct device *parent, void *devdata);
/* Helpers */
#define for_each_trip_desc(__tz, __td) \

View File

@ -561,7 +561,7 @@ thermal_of_cooling_device_register(struct device_node *np, u32 cdev_id,
cdev->np = np;
cdev->cdev_id = cdev_id;
ret = thermal_cooling_device_add(cdev, devdata);
ret = thermal_cooling_device_add(cdev, NULL, devdata);
if (ret)
return ERR_PTR(ret);

View File

@ -919,6 +919,13 @@ struct acpi_iovt_iommu {
u32 device_entry_offset;
};
/* Masks for Flags field above */
#define ACPI_IOVT_IOMMU_PCI_DEVICE (1<<0)
#define ACPI_IOVT_IOMMU_PXM_VALID (1<<1)
#define ACPI_IOVT_IOMMU_MAGAGE_BY_SEGMENT (1<<2)
#define ACPI_IOVT_IOMMU_HW_CAP_SUPPORT (1<<3)
#define ACPI_IOVT_IOMMU_MSI_INT_BYPASS (1<<4)
struct acpi_iovt_device_entry {
u8 type;
u8 length;

View File

@ -427,10 +427,8 @@ int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi);
#endif /* CONFIG_ACPI_PROCESSOR_IDLE */
/* in processor_thermal.c */
int acpi_processor_thermal_init(struct acpi_processor *pr,
struct acpi_device *device);
void acpi_processor_thermal_exit(struct acpi_processor *pr,
struct acpi_device *device);
int acpi_processor_thermal_init(struct acpi_processor *pr);
void acpi_processor_thermal_exit(struct acpi_processor *pr);
extern const struct thermal_cooling_device_ops processor_cooling_ops;
#ifdef CONFIG_CPU_FREQ
void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy);

View File

@ -29,6 +29,8 @@ struct irq_domain_ops;
#ifdef CONFIG_ACPI
DEFINE_FREE(acpi_object_free, union acpi_object *, if (_T) ACPI_FREE(_T));
#include <linux/list.h>
#include <linux/dynamic_debug.h>
#include <linux/module.h>

View File

@ -293,8 +293,9 @@ struct device *thermal_zone_device(struct thermal_zone_device *tzd);
void thermal_zone_device_update(struct thermal_zone_device *,
enum thermal_notify_event);
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
void *, const struct thermal_cooling_device_ops *);
struct thermal_cooling_device *thermal_cooling_device_create(
struct device *parent, const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops);
struct thermal_cooling_device *
devm_thermal_cooling_device_register(struct device *dev, const char *type, void *devdata,
@ -340,9 +341,9 @@ static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
{ }
static inline struct thermal_cooling_device *
thermal_cooling_device_register(const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
static inline struct thermal_cooling_device *thermal_cooling_device_create(
struct device *parent, const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
{ return ERR_PTR(-ENODEV); }
static inline struct thermal_cooling_device *
@ -391,4 +392,12 @@ static inline void thermal_pm_prepare(void) {}
static inline void thermal_pm_complete(void) {}
#endif /* CONFIG_THERMAL */
static inline struct thermal_cooling_device *thermal_cooling_device_register(
const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
{
return thermal_cooling_device_create(NULL, type, devdata, ops);
}
#endif /* __THERMAL_H__ */