More ACPI support updates for 6.18-rc1

- Add missing synchronization between interface updates in the ACPI
    battery driver (Rafael Wysocki)
 
  - Remove open coded check for cpu_feature_enabled() from
    acpi_processor_power_init_bm_check() (Mario Limonciello)
 
  - Remove redundant rcu_read_lock/unlock() under spinlock from
    ghes_notify_hed() in the ACPI APEI support code (pengdonglin)
 
  - Make the .get_next_child_node() callback in the ACPI fwnode backend
    skip ACPI devices that are not present for consistency with the
    analogous callback in the OF fwnode backend (Sakari Ailus)
 -----BEGIN PGP SIGNATURE-----
 
 iQFGBAABCAAwFiEEcM8Aw/RY0dgsiRUR7l+9nS/U47UFAmjk9loSHHJqd0Byand5
 c29ja2kubmV0AAoJEO5fvZ0v1OO1zEwH/1b6+0ZA4EAG+TtPylVA5FptHUq9AUHW
 rkk/bCjCaTfDsI2jffs3Ui1k4Gmwtr370EfwoXKx8dc8/4AQJZioqVIhbozXMDTx
 0Hviylc8eTe6peeUJKl6RD/HrE38cOemlfX2M5t/2rENfBFp9ZI9KMrVpvermvX7
 Nba+r0+mK75At90EsI25JzqxUuyW12A5wYORfXcznugEL69ovupqK3U01E/TEWWb
 pqZgHbdMgtnP4F0hh2gDMDbWwxgEcm0lGkLoZ/w1UxKcw+wgeT0NaEP+c2+XiGrw
 iXsXF8ZcfrZcq22rNR0SQ7kS0F2b9q6lqjkIfSKbHqqqaY8pXEBmEys=
 =BQsI
 -----END PGP SIGNATURE-----

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

Pull more ACPI updates from Rafael Wysocki:
 "These fix a driver bug, clean up two pieces of code and improve the
  fwnode API consistency:

   - Add missing synchronization between interface updates in the ACPI
     battery driver (Rafael Wysocki)

   - Remove open coded check for cpu_feature_enabled() from
     acpi_processor_power_init_bm_check() (Mario Limonciello)

   - Remove redundant rcu_read_lock/unlock() under spinlock from
     ghes_notify_hed() in the ACPI APEI support code (pengdonglin)

   - Make the .get_next_child_node() callback in the ACPI fwnode backend
     skip ACPI devices that are not present for consistency with the
     analogous callback in the OF fwnode backend (Sakari Ailus)"

* tag 'acpi-6.18-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: property: Return present device nodes only on fwnode interface
  ACPI: APEI: Remove redundant rcu_read_lock/unlock() under spinlock
  ACPI: battery: Add synchronization between interface updates
  x86/acpi/cstate: Remove open coded check for cpu_feature_enabled()
This commit is contained in:
Linus Torvalds 2025-10-07 09:45:07 -07:00
commit 89b59f0979
4 changed files with 53 additions and 18 deletions

View File

@ -89,7 +89,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
*/ */
flags->bm_control = 0; flags->bm_control = 0;
} }
if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17) { if (cpu_feature_enabled(X86_FEATURE_ZEN)) {
/* /*
* For all AMD Zen or newer CPUs that support C3, caches * For all AMD Zen or newer CPUs that support C3, caches
* should not be flushed by software while entering C3 * should not be flushed by software while entering C3

View File

@ -1207,12 +1207,10 @@ static int ghes_notify_hed(struct notifier_block *this, unsigned long event,
int ret = NOTIFY_DONE; int ret = NOTIFY_DONE;
spin_lock_irqsave(&ghes_notify_lock_irq, flags); spin_lock_irqsave(&ghes_notify_lock_irq, flags);
rcu_read_lock();
list_for_each_entry_rcu(ghes, &ghes_hed, list) { list_for_each_entry_rcu(ghes, &ghes_hed, list) {
if (!ghes_proc(ghes)) if (!ghes_proc(ghes))
ret = NOTIFY_OK; ret = NOTIFY_OK;
} }
rcu_read_unlock();
spin_unlock_irqrestore(&ghes_notify_lock_irq, flags); spin_unlock_irqrestore(&ghes_notify_lock_irq, flags);
return ret; return ret;

View File

@ -92,7 +92,7 @@ enum {
struct acpi_battery { struct acpi_battery {
struct mutex lock; struct mutex lock;
struct mutex sysfs_lock; struct mutex update_lock;
struct power_supply *bat; struct power_supply *bat;
struct power_supply_desc bat_desc; struct power_supply_desc bat_desc;
struct acpi_device *device; struct acpi_device *device;
@ -904,15 +904,12 @@ static int sysfs_add_battery(struct acpi_battery *battery)
static void sysfs_remove_battery(struct acpi_battery *battery) static void sysfs_remove_battery(struct acpi_battery *battery)
{ {
mutex_lock(&battery->sysfs_lock); if (!battery->bat)
if (!battery->bat) {
mutex_unlock(&battery->sysfs_lock);
return; return;
}
battery_hook_remove_battery(battery); battery_hook_remove_battery(battery);
power_supply_unregister(battery->bat); power_supply_unregister(battery->bat);
battery->bat = NULL; battery->bat = NULL;
mutex_unlock(&battery->sysfs_lock);
} }
static void find_battery(const struct dmi_header *dm, void *private) static void find_battery(const struct dmi_header *dm, void *private)
@ -1072,6 +1069,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
if (!battery) if (!battery)
return; return;
guard(mutex)(&battery->update_lock);
old = battery->bat; old = battery->bat;
/* /*
* On Acer Aspire V5-573G notifications are sometimes triggered too * On Acer Aspire V5-573G notifications are sometimes triggered too
@ -1094,21 +1094,22 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
} }
static int battery_notify(struct notifier_block *nb, static int battery_notify(struct notifier_block *nb,
unsigned long mode, void *_unused) unsigned long mode, void *_unused)
{ {
struct acpi_battery *battery = container_of(nb, struct acpi_battery, struct acpi_battery *battery = container_of(nb, struct acpi_battery,
pm_nb); pm_nb);
int result;
switch (mode) { if (mode == PM_POST_SUSPEND || mode == PM_POST_HIBERNATION) {
case PM_POST_HIBERNATION: guard(mutex)(&battery->update_lock);
case PM_POST_SUSPEND:
if (!acpi_battery_present(battery)) if (!acpi_battery_present(battery))
return 0; return 0;
if (battery->bat) { if (battery->bat) {
acpi_battery_refresh(battery); acpi_battery_refresh(battery);
} else { } else {
int result;
result = acpi_battery_get_info(battery); result = acpi_battery_get_info(battery);
if (result) if (result)
return result; return result;
@ -1120,7 +1121,6 @@ static int battery_notify(struct notifier_block *nb,
acpi_battery_init_alarm(battery); acpi_battery_init_alarm(battery);
acpi_battery_get_state(battery); acpi_battery_get_state(battery);
break;
} }
return 0; return 0;
@ -1198,6 +1198,8 @@ static int acpi_battery_update_retry(struct acpi_battery *battery)
{ {
int retry, ret; int retry, ret;
guard(mutex)(&battery->update_lock);
for (retry = 5; retry; retry--) { for (retry = 5; retry; retry--) {
ret = acpi_battery_update(battery, false); ret = acpi_battery_update(battery, false);
if (!ret) if (!ret)
@ -1208,6 +1210,13 @@ static int acpi_battery_update_retry(struct acpi_battery *battery)
return ret; return ret;
} }
static void sysfs_battery_cleanup(struct acpi_battery *battery)
{
guard(mutex)(&battery->update_lock);
sysfs_remove_battery(battery);
}
static int acpi_battery_add(struct acpi_device *device) static int acpi_battery_add(struct acpi_device *device)
{ {
int result = 0; int result = 0;
@ -1230,7 +1239,7 @@ static int acpi_battery_add(struct acpi_device *device)
if (result) if (result)
return result; return result;
result = devm_mutex_init(&device->dev, &battery->sysfs_lock); result = devm_mutex_init(&device->dev, &battery->update_lock);
if (result) if (result)
return result; return result;
@ -1262,7 +1271,7 @@ fail_pm:
device_init_wakeup(&device->dev, 0); device_init_wakeup(&device->dev, 0);
unregister_pm_notifier(&battery->pm_nb); unregister_pm_notifier(&battery->pm_nb);
fail: fail:
sysfs_remove_battery(battery); sysfs_battery_cleanup(battery);
return result; return result;
} }
@ -1281,6 +1290,9 @@ static void acpi_battery_remove(struct acpi_device *device)
device_init_wakeup(&device->dev, 0); device_init_wakeup(&device->dev, 0);
unregister_pm_notifier(&battery->pm_nb); unregister_pm_notifier(&battery->pm_nb);
guard(mutex)(&battery->update_lock);
sysfs_remove_battery(battery); sysfs_remove_battery(battery);
} }
@ -1297,6 +1309,9 @@ static int acpi_battery_resume(struct device *dev)
return -EINVAL; return -EINVAL;
battery->update_time = 0; battery->update_time = 0;
guard(mutex)(&battery->update_lock);
acpi_battery_update(battery, true); acpi_battery_update(battery, true);
return 0; return 0;
} }

View File

@ -1388,6 +1388,28 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
return NULL; return NULL;
} }
/*
* acpi_get_next_present_subnode - Return the next present child node handle
* @fwnode: Firmware node to find the next child node for.
* @child: Handle to one of the device's child nodes or a null handle.
*
* Like acpi_get_next_subnode(), but the device nodes returned by
* acpi_get_next_present_subnode() are guaranteed to be present.
*
* Returns: The fwnode handle of the next present sub-node.
*/
static struct fwnode_handle *
acpi_get_next_present_subnode(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
do {
child = acpi_get_next_subnode(fwnode, child);
} while (is_acpi_device_node(child) &&
!acpi_device_is_present(to_acpi_device_node(child)));
return child;
}
/** /**
* acpi_node_get_parent - Return parent fwnode of this fwnode * acpi_node_get_parent - Return parent fwnode of this fwnode
* @fwnode: Firmware node whose parent to get * @fwnode: Firmware node whose parent to get
@ -1722,7 +1744,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode,
.property_read_string_array = \ .property_read_string_array = \
acpi_fwnode_property_read_string_array, \ acpi_fwnode_property_read_string_array, \
.get_parent = acpi_node_get_parent, \ .get_parent = acpi_node_get_parent, \
.get_next_child_node = acpi_get_next_subnode, \ .get_next_child_node = acpi_get_next_present_subnode, \
.get_named_child_node = acpi_fwnode_get_named_child_node, \ .get_named_child_node = acpi_fwnode_get_named_child_node, \
.get_name = acpi_fwnode_get_name, \ .get_name = acpi_fwnode_get_name, \
.get_name_prefix = acpi_fwnode_get_name_prefix, \ .get_name_prefix = acpi_fwnode_get_name_prefix, \