Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'acpi-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI updates from Rafael Wysocki:
"From the functional perspective, the most significant changes here are
the ACPI fan driver update allowing it to handle fans with
fine-grained state checking supported, but without fine-grained
control, and the ACPI button driver update making it subscribe to
system event notifications (in addition to device notifications) which
on some systems is requisite for waking up the system from sleep.

The rest is fixes and cleanups including removal of some dead code.

Specifics:

- 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)

- Add a missing header file include to the x86 arch CPPC code (Mario
Limonciello)

- Rework the sysfs attributes implementation in the ACPI
platform-profile driver and improve the unregistration code in it
(Nathan Chancellor, Kurt Borja)

- Prevent the ACPI HED driver from being built as a module and change
its initcall level to subsys_initcall to avoid initialization
ordering issues related to it (Xiaofei Tan)

- Update a maintainer email address in the ACPI PMIC entry in
MAINTAINERS (Mika Westerberg)

- Address a GCC 15's -Wunterminated-string-initialization warning in
the core PNP subsystem code and remove some dead code from it (Kees
Cook, David Alan Gilbert)"

* tag 'acpi-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PNP: Expand length of fixup id string
PNP: Remove prehistoric deadcode
ACPI: button: Install notifier for system events as well
ACPI: fan: Add fan speed reporting for fans with only _FST
ACPI: HED: Always initialize before evged
x86/ACPI: CPPC: Add missing include
ACPI: video: Use str_yes_no() helper in acpi_video_bus_add()
ACPI: platform_profile: Improve platform_profile_unregister()
ACPI: platform-profile: Fix CFI violation when accessing sysfs files
ACPI: power: Use str_on_off() helper function
ACPI: thermal: Fix stale comment regarding trip points
MAINTAINERS: Use my kernel.org address for ACPI PMIC work

+99 -113
-3
Documentation/admin-guide/pnp.rst
··· 129 129 pnp_register_protocol 130 130 use this to register a new PnP protocol 131 131 132 - pnp_unregister_protocol 133 - use this function to remove a PnP protocol from the Plug and Play Layer 134 - 135 132 pnp_register_driver 136 133 adds a PnP driver to the Plug and Play Layer 137 134
+1 -1
MAINTAINERS
··· 356 356 M: "Rafael J. Wysocki" <rafael@kernel.org> 357 357 M: Len Brown <lenb@kernel.org> 358 358 R: Andy Shevchenko <andy@kernel.org> 359 - R: Mika Westerberg <mika.westerberg@linux.intel.com> 359 + R: Mika Westerberg <westeri@kernel.org> 360 360 L: linux-acpi@vger.kernel.org 361 361 S: Supported 362 362 Q: https://patchwork.kernel.org/project/linux-acpi/list/
+2
arch/x86/kernel/acpi/cppc.c
··· 4 4 * Copyright (c) 2016, Intel Corporation. 5 5 */ 6 6 7 + #include <linux/bitfield.h> 8 + 7 9 #include <acpi/cppc_acpi.h> 8 10 #include <asm/msr.h> 9 11 #include <asm/processor.h>
+1 -1
drivers/acpi/Kconfig
··· 452 452 the modules will be called sbs and sbshc. 453 453 454 454 config ACPI_HED 455 - tristate "Hardware Error Device" 455 + bool "Hardware Error Device" 456 456 help 457 457 This driver supports the Hardware Error Device (PNP0C33), 458 458 which is used to report some hardware errors notified via
+4 -3
drivers/acpi/acpi_video.c
··· 27 27 #include <linux/acpi.h> 28 28 #include <acpi/video.h> 29 29 #include <linux/uaccess.h> 30 + #include <linux/string_choices.h> 30 31 31 32 #define ACPI_VIDEO_BUS_NAME "Video Bus" 32 33 #define ACPI_VIDEO_DEVICE_NAME "Video Device" ··· 2040 2039 2041 2040 pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n", 2042 2041 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 2043 - video->flags.multihead ? "yes" : "no", 2044 - video->flags.rom ? "yes" : "no", 2045 - video->flags.post ? "yes" : "no"); 2042 + str_yes_no(video->flags.multihead), 2043 + str_yes_no(video->flags.rom), 2044 + str_yes_no(video->flags.post)); 2046 2045 mutex_lock(&video_list_lock); 2047 2046 list_add_tail(&video->entry, &video_bus_head); 2048 2047 mutex_unlock(&video_list_lock);
+8 -2
drivers/acpi/button.c
··· 24 24 #define ACPI_BUTTON_CLASS "button" 25 25 #define ACPI_BUTTON_FILE_STATE "state" 26 26 #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 27 + #define ACPI_BUTTON_NOTIFY_WAKE 0x02 27 28 #define ACPI_BUTTON_NOTIFY_STATUS 0x80 28 29 29 30 #define ACPI_BUTTON_SUBCLASS_POWER "power" ··· 444 443 struct input_dev *input; 445 444 int keycode; 446 445 447 - if (event != ACPI_BUTTON_NOTIFY_STATUS) { 446 + switch (event) { 447 + case ACPI_BUTTON_NOTIFY_STATUS: 448 + break; 449 + case ACPI_BUTTON_NOTIFY_WAKE: 450 + break; 451 + default: 448 452 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", 449 453 event); 450 454 return; ··· 635 629 break; 636 630 default: 637 631 status = acpi_install_notify_handler(device->handle, 638 - ACPI_DEVICE_NOTIFY, handler, 632 + ACPI_ALL_NOTIFY, handler, 639 633 device); 640 634 break; 641 635 }
+1
drivers/acpi/fan.h
··· 49 49 50 50 struct acpi_fan { 51 51 bool acpi4; 52 + bool has_fst; 52 53 struct acpi_fan_fif fif; 53 54 struct acpi_fan_fps *fps; 54 55 int fps_count;
+22 -15
drivers/acpi/fan_attr.c
··· 75 75 struct acpi_fan *fan = acpi_driver_data(device); 76 76 int i, status; 77 77 78 - sysfs_attr_init(&fan->fine_grain_control.attr); 79 - fan->fine_grain_control.show = show_fine_grain_control; 80 - fan->fine_grain_control.store = NULL; 81 - fan->fine_grain_control.attr.name = "fine_grain_control"; 82 - fan->fine_grain_control.attr.mode = 0444; 83 - status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr); 84 - if (status) 85 - return status; 86 - 87 78 /* _FST is present if we are here */ 88 79 sysfs_attr_init(&fan->fst_speed.attr); 89 80 fan->fst_speed.show = show_fan_speed; ··· 83 92 fan->fst_speed.attr.mode = 0444; 84 93 status = sysfs_create_file(&device->dev.kobj, &fan->fst_speed.attr); 85 94 if (status) 86 - goto rem_fine_grain_attr; 95 + return status; 96 + 97 + if (!fan->acpi4) 98 + return 0; 99 + 100 + sysfs_attr_init(&fan->fine_grain_control.attr); 101 + fan->fine_grain_control.show = show_fine_grain_control; 102 + fan->fine_grain_control.store = NULL; 103 + fan->fine_grain_control.attr.name = "fine_grain_control"; 104 + fan->fine_grain_control.attr.mode = 0444; 105 + status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr); 106 + if (status) 107 + goto rem_fst_attr; 87 108 88 109 for (i = 0; i < fan->fps_count; ++i) { 89 110 struct acpi_fan_fps *fps = &fan->fps[i]; ··· 112 109 113 110 for (j = 0; j < i; ++j) 114 111 sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr); 115 - goto rem_fst_attr; 112 + goto rem_fine_grain_attr; 116 113 } 117 114 } 118 115 119 116 return 0; 120 117 121 - rem_fst_attr: 122 - sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr); 123 - 124 118 rem_fine_grain_attr: 125 119 sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr); 120 + 121 + rem_fst_attr: 122 + sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr); 126 123 127 124 return status; 128 125 } ··· 132 129 struct acpi_fan *fan = acpi_driver_data(device); 133 130 int i; 134 131 132 + sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr); 133 + 134 + if (!fan->acpi4) 135 + return; 136 + 135 137 for (i = 0; i < fan->fps_count; ++i) 136 138 sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr); 137 139 138 - sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr); 139 140 sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr); 140 141 }
+18 -7
drivers/acpi/fan_core.c
··· 203 203 * -------------------------------------------------------------------------- 204 204 */ 205 205 206 + static bool acpi_fan_has_fst(struct acpi_device *device) 207 + { 208 + return acpi_has_method(device->handle, "_FST"); 209 + } 210 + 206 211 static bool acpi_fan_is_acpi4(struct acpi_device *device) 207 212 { 208 213 return acpi_has_method(device->handle, "_FIF") && 209 214 acpi_has_method(device->handle, "_FPS") && 210 - acpi_has_method(device->handle, "_FSL") && 211 - acpi_has_method(device->handle, "_FST"); 215 + acpi_has_method(device->handle, "_FSL"); 212 216 } 213 217 214 218 static int acpi_fan_get_fif(struct acpi_device *device) ··· 331 327 device->driver_data = fan; 332 328 platform_set_drvdata(pdev, fan); 333 329 334 - if (acpi_fan_is_acpi4(device)) { 330 + if (acpi_fan_has_fst(device)) { 331 + fan->has_fst = true; 332 + fan->acpi4 = acpi_fan_is_acpi4(device); 333 + } 334 + 335 + if (fan->acpi4) { 335 336 result = acpi_fan_get_fif(device); 336 337 if (result) 337 338 return result; ··· 344 335 result = acpi_fan_get_fps(device); 345 336 if (result) 346 337 return result; 338 + } 347 339 340 + if (fan->has_fst) { 348 341 result = devm_acpi_fan_create_hwmon(device); 349 342 if (result) 350 343 return result; ··· 354 343 result = acpi_fan_create_attributes(device); 355 344 if (result) 356 345 return result; 346 + } 357 347 358 - fan->acpi4 = true; 359 - } else { 348 + if (!fan->acpi4) { 360 349 result = acpi_device_update_power(device, NULL); 361 350 if (result) { 362 351 dev_err(&device->dev, "Failed to set initial power state\n"); ··· 402 391 err_unregister: 403 392 thermal_cooling_device_unregister(cdev); 404 393 err_end: 405 - if (fan->acpi4) 394 + if (fan->has_fst) 406 395 acpi_fan_delete_attributes(device); 407 396 408 397 return result; ··· 412 401 { 413 402 struct acpi_fan *fan = platform_get_drvdata(pdev); 414 403 415 - if (fan->acpi4) { 404 + if (fan->has_fst) { 416 405 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); 417 406 418 407 acpi_fan_delete_attributes(device);
+8
drivers/acpi/fan_hwmon.c
··· 43 43 case hwmon_fan_input: 44 44 return 0444; 45 45 case hwmon_fan_target: 46 + /* Only acpi4 fans support fan control. */ 47 + if (!fan->acpi4) 48 + return 0; 49 + 46 50 /* 47 51 * When in fine grain control mode, not every fan control value 48 52 * has an associated fan performance state. ··· 61 57 case hwmon_power: 62 58 switch (attr) { 63 59 case hwmon_power_input: 60 + /* Only acpi4 fans support fan control. */ 61 + if (!fan->acpi4) 62 + return 0; 63 + 64 64 /* 65 65 * When in fine grain control mode, not every fan control value 66 66 * has an associated fan performance state.
+6 -1
drivers/acpi/hed.c
··· 80 80 .remove = acpi_hed_remove, 81 81 }, 82 82 }; 83 - module_acpi_driver(acpi_hed_driver); 83 + 84 + static int __init acpi_hed_driver_init(void) 85 + { 86 + return acpi_bus_register_driver(&acpi_hed_driver); 87 + } 88 + subsys_initcall(acpi_hed_driver_init); 84 89 85 90 MODULE_AUTHOR("Huang Ying"); 86 91 MODULE_DESCRIPTION("ACPI Hardware Error Device Driver");
+22 -23
drivers/acpi/platform_profile.c
··· 289 289 290 290 /** 291 291 * platform_profile_choices_show - Show the available profile choices for legacy sysfs interface 292 - * @dev: The device 292 + * @kobj: The kobject 293 293 * @attr: The attribute 294 294 * @buf: The buffer to write to 295 295 * 296 296 * Return: The number of bytes written 297 297 */ 298 - static ssize_t platform_profile_choices_show(struct device *dev, 299 - struct device_attribute *attr, 298 + static ssize_t platform_profile_choices_show(struct kobject *kobj, 299 + struct kobj_attribute *attr, 300 300 char *buf) 301 301 { 302 302 struct aggregate_choices_data data = { ··· 371 371 372 372 /** 373 373 * platform_profile_show - Show the current profile for legacy sysfs interface 374 - * @dev: The device 374 + * @kobj: The kobject 375 375 * @attr: The attribute 376 376 * @buf: The buffer to write to 377 377 * 378 378 * Return: The number of bytes written 379 379 */ 380 - static ssize_t platform_profile_show(struct device *dev, 381 - struct device_attribute *attr, 380 + static ssize_t platform_profile_show(struct kobject *kobj, 381 + struct kobj_attribute *attr, 382 382 char *buf) 383 383 { 384 384 enum platform_profile_option profile = PLATFORM_PROFILE_LAST; ··· 400 400 401 401 /** 402 402 * platform_profile_store - Set the profile for legacy sysfs interface 403 - * @dev: The device 403 + * @kobj: The kobject 404 404 * @attr: The attribute 405 405 * @buf: The buffer to read from 406 406 * @count: The number of bytes to read 407 407 * 408 408 * Return: The number of bytes read 409 409 */ 410 - static ssize_t platform_profile_store(struct device *dev, 411 - struct device_attribute *attr, 410 + static ssize_t platform_profile_store(struct kobject *kobj, 411 + struct kobj_attribute *attr, 412 412 const char *buf, size_t count) 413 413 { 414 414 struct aggregate_choices_data data = { ··· 442 442 return count; 443 443 } 444 444 445 - static DEVICE_ATTR_RO(platform_profile_choices); 446 - static DEVICE_ATTR_RW(platform_profile); 445 + static struct kobj_attribute attr_platform_profile_choices = __ATTR_RO(platform_profile_choices); 446 + static struct kobj_attribute attr_platform_profile = __ATTR_RW(platform_profile); 447 447 448 448 static struct attribute *platform_profile_attrs[] = { 449 - &dev_attr_platform_profile_choices.attr, 450 - &dev_attr_platform_profile.attr, 449 + &attr_platform_profile_choices.attr, 450 + &attr_platform_profile.attr, 451 451 NULL 452 452 }; 453 453 ··· 627 627 /** 628 628 * platform_profile_remove - Unregisters a platform profile class device 629 629 * @dev: Class device 630 - * 631 - * Return: 0 632 630 */ 633 - int platform_profile_remove(struct device *dev) 631 + void platform_profile_remove(struct device *dev) 634 632 { 635 - struct platform_profile_handler *pprof = to_pprof_handler(dev); 636 - int id; 633 + struct platform_profile_handler *pprof; 634 + 635 + if (IS_ERR_OR_NULL(dev)) 636 + return; 637 + 638 + pprof = to_pprof_handler(dev); 639 + 637 640 guard(mutex)(&profile_lock); 638 641 639 - id = pprof->minor; 642 + ida_free(&platform_profile_ida, pprof->minor); 640 643 device_unregister(&pprof->dev); 641 - ida_free(&platform_profile_ida, id); 642 644 643 645 sysfs_notify(acpi_kobj, NULL, "platform_profile"); 644 - 645 646 sysfs_update_group(acpi_kobj, &platform_profile_group); 646 - 647 - return 0; 648 647 } 649 648 EXPORT_SYMBOL_GPL(platform_profile_remove); 650 649
+3 -2
drivers/acpi/power.c
··· 29 29 #include <linux/init.h> 30 30 #include <linux/types.h> 31 31 #include <linux/slab.h> 32 + #include <linux/string_choices.h> 32 33 #include <linux/pm_runtime.h> 33 34 #include <linux/sysfs.h> 34 35 #include <linux/acpi.h> ··· 198 197 cur_state = sta & ACPI_POWER_RESOURCE_STATE_ON; 199 198 200 199 acpi_handle_debug(handle, "Power resource is %s\n", 201 - cur_state ? "on" : "off"); 200 + str_on_off(cur_state)); 202 201 203 202 *state = cur_state; 204 203 return 0; ··· 241 240 break; 242 241 } 243 242 244 - pr_debug("Power resource list is %s\n", cur_state ? "on" : "off"); 243 + pr_debug("Power resource list is %s\n", str_on_off(cur_state)); 245 244 246 245 *state = cur_state; 247 246 return 0;
+1 -1
drivers/acpi/thermal.c
··· 803 803 804 804 acpi_thermal_aml_dependency_fix(tz); 805 805 806 - /* Get trip points [_CRT, _PSV, etc.] (required). */ 806 + /* Get trip points [_ACi, _PSV, etc.] (required). */ 807 807 acpi_thermal_get_trip_points(tz); 808 808 809 809 crit_temp = acpi_thermal_get_critical_trip(tz);
-4
drivers/pnp/base.h
··· 9 9 extern const struct bus_type pnp_bus_type; 10 10 11 11 int pnp_register_protocol(struct pnp_protocol *protocol); 12 - void pnp_unregister_protocol(struct pnp_protocol *protocol); 13 12 14 13 #define PNP_EISA_ID_MASK 0x7fffffff 15 14 void pnp_eisa_id_to_string(u32 id, char *str); ··· 20 21 struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id); 21 22 22 23 int pnp_add_card(struct pnp_card *card); 23 - void pnp_remove_card(struct pnp_card *card); 24 24 int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); 25 - void pnp_remove_card_device(struct pnp_dev *dev); 26 25 27 26 struct pnp_port { 28 27 resource_size_t min; /* min base number */ ··· 135 138 void pnp_fixup_device(struct pnp_dev *dev); 136 139 void pnp_free_options(struct pnp_dev *dev); 137 140 int __pnp_add_device(struct pnp_dev *dev); 138 - void __pnp_remove_device(struct pnp_dev *dev); 139 141 140 142 int pnp_check_port(struct pnp_dev *dev, struct resource *res); 141 143 int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
-32
drivers/pnp/card.c
··· 270 270 } 271 271 272 272 /** 273 - * pnp_remove_card - removes a PnP card from the PnP Layer 274 - * @card: pointer to the card to remove 275 - */ 276 - void pnp_remove_card(struct pnp_card *card) 277 - { 278 - struct list_head *pos, *temp; 279 - 280 - device_unregister(&card->dev); 281 - mutex_lock(&pnp_lock); 282 - list_del(&card->global_list); 283 - list_del(&card->protocol_list); 284 - mutex_unlock(&pnp_lock); 285 - list_for_each_safe(pos, temp, &card->devices) { 286 - struct pnp_dev *dev = card_to_pnp_dev(pos); 287 - pnp_remove_card_device(dev); 288 - } 289 - } 290 - 291 - /** 292 273 * pnp_add_card_device - adds a device to the specified card 293 274 * @card: pointer to the card to add to 294 275 * @dev: pointer to the device to add ··· 285 304 list_add_tail(&dev->card_list, &card->devices); 286 305 mutex_unlock(&pnp_lock); 287 306 return 0; 288 - } 289 - 290 - /** 291 - * pnp_remove_card_device- removes a device from the specified card 292 - * @dev: pointer to the device to remove 293 - */ 294 - void pnp_remove_card_device(struct pnp_dev *dev) 295 - { 296 - mutex_lock(&pnp_lock); 297 - dev->card = NULL; 298 - list_del(&dev->card_list); 299 - mutex_unlock(&pnp_lock); 300 - __pnp_remove_device(dev); 301 307 } 302 308 303 309 /**
-16
drivers/pnp/core.c
··· 78 78 return ret; 79 79 } 80 80 81 - /** 82 - * pnp_unregister_protocol - removes a pnp protocol from the pnp layer 83 - * @protocol: pointer to the corresponding pnp_protocol structure 84 - */ 85 - void pnp_unregister_protocol(struct pnp_protocol *protocol) 86 - { 87 - pnp_remove_protocol(protocol); 88 - device_unregister(&protocol->dev); 89 - } 90 - 91 81 static void pnp_free_ids(struct pnp_dev *dev) 92 82 { 93 83 struct pnp_id *id; ··· 208 218 dev_dbg(&dev->dev, "%s device, IDs%s (%s)\n", dev->protocol->name, buf, 209 219 dev->active ? "active" : "disabled"); 210 220 return 0; 211 - } 212 - 213 - void __pnp_remove_device(struct pnp_dev *dev) 214 - { 215 - pnp_delist_device(dev); 216 - device_unregister(&dev->dev); 217 221 } 218 222 219 223 static int __init pnp_init(void)
+1 -1
include/linux/platform_profile.h
··· 50 50 struct device *platform_profile_register(struct device *dev, const char *name, 51 51 void *drvdata, 52 52 const struct platform_profile_ops *ops); 53 - int platform_profile_remove(struct device *dev); 53 + void platform_profile_remove(struct device *dev); 54 54 struct device *devm_platform_profile_register(struct device *dev, const char *name, 55 55 void *drvdata, 56 56 const struct platform_profile_ops *ops);
+1 -1
include/linux/pnp.h
··· 290 290 } 291 291 292 292 struct pnp_fixup { 293 - char id[7]; 293 + char id[8]; 294 294 void (*quirk_function) (struct pnp_dev *dev); /* fixup function */ 295 295 }; 296 296