Merge branches 'acpi-power', 'acpi-fan', 'acpi-thermal', 'acpi-button' and 'acpi-video'

Merge five ACPI driver updates for 6.15-rc1:

 - Use the str_on_off() helper function instead of hard-coded strings in
   the ACPI power resources handling code (Thorsten Blum).

 - Add fan speed reporting for ACPI fans that have _FST, but otherwise
   do not support the entire ACPI 4 fan interface (Joshua Grisham).

 - Fix a stale comment regarding trip points in acpi_thermal_add() that
   diverged from the commented code after removing _CRT evaluation from
   acpi_thermal_get_trip_points() (xueqin Luo).

 - Make ACPI button driver also subscribe to system events (Mario
   Limonciello).

 - Use the str_yes_no() helper function instead of hard-coded strings in
   the ACPI backlight (video) driver (Thorsten Blum).

* acpi-power:
  ACPI: power: Use str_on_off() helper function

* acpi-fan:
  ACPI: fan: Add fan speed reporting for fans with only _FST

* acpi-thermal:
  ACPI: thermal: Fix stale comment regarding trip points

* acpi-button:
  ACPI: button: Install notifier for system events as well

* acpi-video:
  ACPI: video: Use str_yes_no() helper in acpi_video_bus_add()
This commit is contained in:
Rafael J. Wysocki 2025-03-24 11:50:52 +01:00
8 changed files with 65 additions and 30 deletions

View File

@ -27,6 +27,7 @@
#include <linux/acpi.h>
#include <acpi/video.h>
#include <linux/uaccess.h>
#include <linux/string_choices.h>
#define ACPI_VIDEO_BUS_NAME "Video Bus"
#define ACPI_VIDEO_DEVICE_NAME "Video Device"
@ -2039,9 +2040,9 @@ static int acpi_video_bus_add(struct acpi_device *device)
pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n",
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
video->flags.multihead ? "yes" : "no",
video->flags.rom ? "yes" : "no",
video->flags.post ? "yes" : "no");
str_yes_no(video->flags.multihead),
str_yes_no(video->flags.rom),
str_yes_no(video->flags.post));
mutex_lock(&video_list_lock);
list_add_tail(&video->entry, &video_bus_head);
mutex_unlock(&video_list_lock);

View File

@ -24,6 +24,7 @@
#define ACPI_BUTTON_CLASS "button"
#define ACPI_BUTTON_FILE_STATE "state"
#define ACPI_BUTTON_TYPE_UNKNOWN 0x00
#define ACPI_BUTTON_NOTIFY_WAKE 0x02
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
@ -443,7 +444,12 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
struct input_dev *input;
int keycode;
if (event != ACPI_BUTTON_NOTIFY_STATUS) {
switch (event) {
case ACPI_BUTTON_NOTIFY_STATUS:
break;
case ACPI_BUTTON_NOTIFY_WAKE:
break;
default:
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
event);
return;
@ -629,7 +635,7 @@ static int acpi_button_add(struct acpi_device *device)
break;
default:
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY, handler,
ACPI_ALL_NOTIFY, handler,
device);
break;
}

View File

@ -49,6 +49,7 @@ struct acpi_fan_fst {
struct acpi_fan {
bool acpi4;
bool has_fst;
struct acpi_fan_fif fif;
struct acpi_fan_fps *fps;
int fps_count;

View File

@ -75,15 +75,6 @@ int acpi_fan_create_attributes(struct acpi_device *device)
struct acpi_fan *fan = acpi_driver_data(device);
int i, status;
sysfs_attr_init(&fan->fine_grain_control.attr);
fan->fine_grain_control.show = show_fine_grain_control;
fan->fine_grain_control.store = NULL;
fan->fine_grain_control.attr.name = "fine_grain_control";
fan->fine_grain_control.attr.mode = 0444;
status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
if (status)
return status;
/* _FST is present if we are here */
sysfs_attr_init(&fan->fst_speed.attr);
fan->fst_speed.show = show_fan_speed;
@ -92,7 +83,19 @@ int acpi_fan_create_attributes(struct acpi_device *device)
fan->fst_speed.attr.mode = 0444;
status = sysfs_create_file(&device->dev.kobj, &fan->fst_speed.attr);
if (status)
goto rem_fine_grain_attr;
return status;
if (!fan->acpi4)
return 0;
sysfs_attr_init(&fan->fine_grain_control.attr);
fan->fine_grain_control.show = show_fine_grain_control;
fan->fine_grain_control.store = NULL;
fan->fine_grain_control.attr.name = "fine_grain_control";
fan->fine_grain_control.attr.mode = 0444;
status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
if (status)
goto rem_fst_attr;
for (i = 0; i < fan->fps_count; ++i) {
struct acpi_fan_fps *fps = &fan->fps[i];
@ -109,18 +112,18 @@ int acpi_fan_create_attributes(struct acpi_device *device)
for (j = 0; j < i; ++j)
sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
goto rem_fst_attr;
goto rem_fine_grain_attr;
}
}
return 0;
rem_fst_attr:
sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
rem_fine_grain_attr:
sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
rem_fst_attr:
sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
return status;
}
@ -129,9 +132,13 @@ void acpi_fan_delete_attributes(struct acpi_device *device)
struct acpi_fan *fan = acpi_driver_data(device);
int i;
sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
if (!fan->acpi4)
return;
for (i = 0; i < fan->fps_count; ++i)
sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
}

View File

@ -203,12 +203,16 @@ static const struct thermal_cooling_device_ops fan_cooling_ops = {
* --------------------------------------------------------------------------
*/
static bool acpi_fan_has_fst(struct acpi_device *device)
{
return acpi_has_method(device->handle, "_FST");
}
static bool acpi_fan_is_acpi4(struct acpi_device *device)
{
return acpi_has_method(device->handle, "_FIF") &&
acpi_has_method(device->handle, "_FPS") &&
acpi_has_method(device->handle, "_FSL") &&
acpi_has_method(device->handle, "_FST");
acpi_has_method(device->handle, "_FSL");
}
static int acpi_fan_get_fif(struct acpi_device *device)
@ -327,7 +331,12 @@ static int acpi_fan_probe(struct platform_device *pdev)
device->driver_data = fan;
platform_set_drvdata(pdev, fan);
if (acpi_fan_is_acpi4(device)) {
if (acpi_fan_has_fst(device)) {
fan->has_fst = true;
fan->acpi4 = acpi_fan_is_acpi4(device);
}
if (fan->acpi4) {
result = acpi_fan_get_fif(device);
if (result)
return result;
@ -335,7 +344,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
result = acpi_fan_get_fps(device);
if (result)
return result;
}
if (fan->has_fst) {
result = devm_acpi_fan_create_hwmon(device);
if (result)
return result;
@ -343,9 +354,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
result = acpi_fan_create_attributes(device);
if (result)
return result;
}
fan->acpi4 = true;
} else {
if (!fan->acpi4) {
result = acpi_device_update_power(device, NULL);
if (result) {
dev_err(&device->dev, "Failed to set initial power state\n");
@ -391,7 +402,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
err_unregister:
thermal_cooling_device_unregister(cdev);
err_end:
if (fan->acpi4)
if (fan->has_fst)
acpi_fan_delete_attributes(device);
return result;
@ -401,7 +412,7 @@ static void acpi_fan_remove(struct platform_device *pdev)
{
struct acpi_fan *fan = platform_get_drvdata(pdev);
if (fan->acpi4) {
if (fan->has_fst) {
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
acpi_fan_delete_attributes(device);

View File

@ -43,6 +43,10 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_
case hwmon_fan_input:
return 0444;
case hwmon_fan_target:
/* Only acpi4 fans support fan control. */
if (!fan->acpi4)
return 0;
/*
* When in fine grain control mode, not every fan control value
* has an associated fan performance state.
@ -57,6 +61,10 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_
case hwmon_power:
switch (attr) {
case hwmon_power_input:
/* Only acpi4 fans support fan control. */
if (!fan->acpi4)
return 0;
/*
* When in fine grain control mode, not every fan control value
* has an associated fan performance state.

View File

@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/string_choices.h>
#include <linux/pm_runtime.h>
#include <linux/sysfs.h>
#include <linux/acpi.h>
@ -197,7 +198,7 @@ static int __get_state(acpi_handle handle, u8 *state)
cur_state = sta & ACPI_POWER_RESOURCE_STATE_ON;
acpi_handle_debug(handle, "Power resource is %s\n",
cur_state ? "on" : "off");
str_on_off(cur_state));
*state = cur_state;
return 0;
@ -240,7 +241,7 @@ static int acpi_power_get_list_state(struct list_head *list, u8 *state)
break;
}
pr_debug("Power resource list is %s\n", cur_state ? "on" : "off");
pr_debug("Power resource list is %s\n", str_on_off(cur_state));
*state = cur_state;
return 0;

View File

@ -803,7 +803,7 @@ static int acpi_thermal_add(struct acpi_device *device)
acpi_thermal_aml_dependency_fix(tz);
/* Get trip points [_CRT, _PSV, etc.] (required). */
/* Get trip points [_ACi, _PSV, etc.] (required). */
acpi_thermal_get_trip_points(tz);
crit_temp = acpi_thermal_get_critical_trip(tz);