projects/linux·commit 3382bfbc

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

3382bfbc · Linus Torvalds <[email protected]> · 2026-08-26 14:06:08 -07:00

Pull more ACPI support updates from Rafael Wysocki:
 "These update documentation to reflect recent changes in the upstream
  ACPICA project, fix issues in the core ACPI device enumeration code
  (one of which has been introduced recently), improve the primary
  "physical" device lookup for ACPI device objects in that code, and
  update ACPI device drivers:

   - Update MAINTAINERS, CREDITS and ACPI subsystem documentation to
     reflect recent changes in the upstream ACPICA project (Rafael
     Wysocki)

   - Prevent the core ACPI enumeration code from combining device
     resources that overlap completely in order to avoid resource
     conflicts during platform device registration because there are
     drivers that expect such resources to be present (Rafael Wysocki)

   - Defer device power initialization during ACPI-based device
     enumeration to the point when the given device is known to be
     present and functional and all of its dependencies have been met
     (Peixin Xie)

   - Fix bus ID cleanup on device_add() failures during ACPI device
     object registration (Hongyan Xu)

   - Introduce a new helper function for looking up the primary
     "physical" device for a given ACPI device object and update the
     core ACPI device enumeration code to use that function (Rafael
     Wysocki)

   - Protect all battery properties with a separated mutex in the ACPI
     battery driver to prevent race conditions from occurring and avoid
     evaluating the _BST ACPI control method multiple times in parallel
     for the same battery device (Rong Zhang)

   - Add DMI quirk for the Razer Blade Pro 17 early 2020 lid switch to
     the ACPI button driver (Robin Everaars)

   - Convert fixed clock rates in the ACPI driver for AMD SoCs (APD) to
     use HZ_PER_MHZ and add a clock frequency for the HJMC01 I2C
     controller to it (Hongnan Li and Xiangyang Yu)

   - Fix a stack buffer overflow in query_capability() in the ACPI
     platform firmware runtime update driver (Anirudh Prasad)"

* tag 'acpi-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: button: Add DMI quirk for Razer Blade Pro 17 early 2020 lid switch
  ACPI: scan: Do not combine resources that overlap completely
  ACPI: Update upstream ACPICA repository URL in documentation
  ACPI: Update MAINTAINERS entry for ACPICA
  ACPI: Add Bob Moore to CREDITS
  ACPI: pfr_update: fix stack buffer overflow in query_capability()
  ACPI: scan: Defer device power initialization
  ACPI: APD: Add clock frequency for HJMC01 I2C controller
  ACPI: APD: Convert fixed clock rates to use HZ_PER_MHZ
  ACPI: scan: Use acpi_bus_get_primary_device()
  ACPI: platform: Use acpi_bus_get_primary_device()
  ACPI: bus: Introduce acpi_bus_get_primary_device()
  ACPI: scan: fix bus ID cleanup on device_add() failures
  ACPI: battery: Protect all properties with a separated mutex
Commit
3382bfbca58c7d5ee3f31a7b37fbeb208e98e656
Parents
502d4577 · ea10c0b3

Merge commit. Changes below are compared with the first parent: 502d4577.

Changes

12 files changed · +246 −134

Only the first 600 diff lines are shown. Download the complete patch.

CREDITS

View file
diff --git a/CREDITS b/CREDITS
index 32abf67..f8a3391 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2919,6 +2919,10 @@ N: Thomas Molina
D: bug fixes, documentation, minor hackery
+N: Bob Moore
+D: ACPI Component Architecture (ACPICA)
+
N: Paul Moore
W: https://www.paul-moore.com

Documentation/driver-api/acpi/linuxized-acpica.rst

View file
diff --git a/Documentation/driver-api/acpi/linuxized-acpica.rst b/Documentation/driver-api/acpi/linuxized-acpica.rst
index cc23435..317a68e 100644
--- a/Documentation/driver-api/acpi/linuxized-acpica.rst
+++ b/Documentation/driver-api/acpi/linuxized-acpica.rst
@@ -117,7 +117,7 @@ ACPICA Release
==============
The ACPICA project maintains its code base at the following repository URL:
-https://github.com/acpica/acpica.git. As a rule, a release is made every
+https://github.com/open-acpica/acpica.git. As a rule, a release is made every
month.
As the coding style adopted by the ACPICA project is not acceptable by
@@ -173,7 +173,7 @@ illustrated in the following figure::
utility located in source/tools/acpisrc folder and a number of
scripts located in generate/linux folder.
B. acpica / master - "master" branch of the git repository at
- <https://github.com/acpica/acpica.git>.
+ <https://github.com/open-acpica/acpica.git>.
C. linux-pm / linux-next - "linux-next" branch of the git repository at
<https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git>.
D. linux / master - "master" branch of the git repository at
@@ -244,7 +244,7 @@ before they become available from the ACPICA release process.
Then the gen-patch.sh command can help to cherry-pick an ACPICA commit
from the ACPICA local repository::
- $ git clone https://github.com/acpica/acpica
+ $ git clone https://github.com/open-acpica/acpica
$ cd acpica
$ generate/linux/gen-patch.sh -u [commit ID]
@@ -259,7 +259,7 @@ before they become available from the ACPICA release process.
You can generate the ACPICA release series yourself and rebase your code on
top of the generated ACPICA release patches::
- $ git clone https://github.com/acpica/acpica
+ $ git clone https://github.com/open-acpica/acpica
$ cd acpica
$ generate/linux/make-patches.sh -u [commit ID]
@@ -273,7 +273,7 @@ before they become available from the ACPICA release process.
If you have local copies of both Linux and upstream ACPICA, you can generate
a diff file indicating the state of the current divergences::
- # git clone https://github.com/acpica/acpica
+ # git clone https://github.com/open-acpica/acpica
# git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# cd acpica
# generate/linux/divergence.sh -s ../linux

MAINTAINERS

View file
diff --git a/MAINTAINERS b/MAINTAINERS
index 7e44f41..55b3c2d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -313,15 +313,15 @@ F: drivers/firmware/efi/cper*
ACPI COMPONENT ARCHITECTURE (ACPICA)
M: "Rafael J. Wysocki" <[email protected]>
-M: Saket Dumbre <[email protected]>
+M: Maciej Wieczor-Retman <[email protected]>
+M: Pawel Chmielewski <[email protected]>
S: Supported
W: https://acpica.org/
-W: https://github.com/acpica/acpica/
+W: https://github.com/open-acpica/acpica/
Q: https://patchwork.kernel.org/project/linux-acpi/list/
B: https://bugzilla.kernel.org
-B: https://bugs.acpica.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
F: drivers/acpi/acpica/
F: include/acpi/

drivers/acpi/acpi_apd.c

View file
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 008bd05..e7366fc 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -14,6 +14,7 @@
#include <linux/io.h>
#include <linux/platform_data/clk-fch.h>
#include <linux/platform_device.h>
+#include <linux/units.h>
#include "internal.h"
@@ -110,17 +111,17 @@ static int fch_misc_setup(struct apd_private_data *pdata)
static const struct apd_device_desc cz_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 133000000,
+ .fixed_clk_rate = 133 * HZ_PER_MHZ,
};
static const struct apd_device_desc wt_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 150000000,
+ .fixed_clk_rate = 150 * HZ_PER_MHZ,
};
static const struct apd_device_desc wt_i3c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 125000000,
+ .fixed_clk_rate = 125 * HZ_PER_MHZ,
};
static struct property_entry uart_properties[] = {
@@ -132,7 +133,7 @@ static struct property_entry uart_properties[] = {
static const struct apd_device_desc cz_uart_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 48000000,
+ .fixed_clk_rate = 48 * HZ_PER_MHZ,
.properties = uart_properties,
};
@@ -144,52 +145,57 @@ static const struct apd_device_desc fch_misc_desc = {
#ifdef CONFIG_ARM64
static const struct apd_device_desc xgene_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 100000000,
+ .fixed_clk_rate = 100 * HZ_PER_MHZ,
};
static const struct apd_device_desc vulcan_spi_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 133000000,
+ .fixed_clk_rate = 133 * HZ_PER_MHZ,
};
static const struct apd_device_desc hip07_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 200000000,
+ .fixed_clk_rate = 200 * HZ_PER_MHZ,
};
static const struct apd_device_desc hip08_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 250000000,
+ .fixed_clk_rate = 250 * HZ_PER_MHZ,
};
static const struct apd_device_desc hip08_lite_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 125000000,
+ .fixed_clk_rate = 125 * HZ_PER_MHZ,
};
static const struct apd_device_desc thunderx2_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 125000000,
+ .fixed_clk_rate = 125 * HZ_PER_MHZ,
};
static const struct apd_device_desc nxp_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 350000000,
+ .fixed_clk_rate = 350 * HZ_PER_MHZ,
};
static const struct apd_device_desc hip08_spi_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 250000000,
+ .fixed_clk_rate = 250 * HZ_PER_MHZ,
};
static const struct apd_device_desc leca_spi_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 400000000,
+ .fixed_clk_rate = 400 * HZ_PER_MHZ,
};
static const struct apd_device_desc leca_i2c_desc = {
.setup = acpi_apd_setup,
- .fixed_clk_rate = 250000000,
+ .fixed_clk_rate = 250 * HZ_PER_MHZ,
+};
+
+static const struct apd_device_desc hjmc_i2c_desc = {
+ .setup = acpi_apd_setup,
+ .fixed_clk_rate = 200 * HZ_PER_MHZ,
};
#endif /* CONFIG_ARM64 */
@@ -262,6 +268,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "HISI02A2", APD_ADDR(hip08_i2c_desc) },
{ "HISI02A3", APD_ADDR(hip08_lite_i2c_desc) },
{ "HISI0173", APD_ADDR(hip08_spi_desc) },
+ { "HJMC3001", APD_ADDR(hjmc_i2c_desc) },
{ "LECA0002", APD_ADDR(leca_spi_desc) },
{ "LECA0003", APD_ADDR(leca_i2c_desc) },
{ "NXP0001", APD_ADDR(nxp_i2c_desc) },

drivers/acpi/acpi_platform.c

View file
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 373c94d..80ea712 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -85,7 +85,13 @@ static unsigned int acpi_platform_adjust_resources(struct acpi_device *adev,
for (i = 0; i < count; ) {
struct resource *res = &resources[i];
- if (resource_type(new_res) != resource_type(res) ||
+ /*
+ * Look for overlaps of resources of the same type that would
+ * cause resource insertion to fail down the road.
+ */
+ if (__resource_contains_unbound(res, new_res) ||
+ __resource_contains_unbound(new_res, res) ||
+ resource_type(new_res) != resource_type(res) ||
!resource_union(new_res, res, new_res)) {
i++;
continue;
@@ -102,18 +108,15 @@ static unsigned int acpi_platform_adjust_resources(struct acpi_device *adev,
return count;
}
-static void acpi_platform_fill_resource(struct acpi_device *adev,
- const struct resource *src, struct resource *dest)
+static void acpi_platform_fill_resource(struct device *parent,
+ const struct resource *src,
+ struct resource *dest)
{
- struct device *parent;
-
*dest = *src;
-
/*
* If the device has parent we need to take its resources into
* account as well because this device might consume part of those.
*/
- parent = acpi_get_first_physical_node(acpi_dev_parent(adev));
if (parent && dev_is_pci(parent))
dest->parent = pci_find_resource(to_pci_dev(parent), dest);
}
@@ -141,7 +144,8 @@ static unsigned int acpi_platform_resource_count(struct acpi_resource *ares, voi
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
const struct property_entry *properties)
{
- struct acpi_device *parent = acpi_dev_parent(adev);
+ struct acpi_device *p = acpi_dev_parent(adev);
+ struct device *parent __free(put_device) = acpi_bus_get_primary_device(p);
struct platform_device *pdev = NULL;
struct platform_device_info pdevinfo;
const struct acpi_device_id *match;
@@ -187,7 +191,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
rentry->res,
resources,
count);
- acpi_platform_fill_resource(adev, rentry->res,
+ acpi_platform_fill_resource(parent, rentry->res,
&resources[count++]);
}
acpi_dev_free_resource_list(&resource_list);
@@ -200,7 +204,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
* attached to it, that physical device should be the parent of the
* platform device we are about to create.
*/
- pdevinfo.parent = parent ? acpi_get_first_physical_node(parent) : NULL;
+ pdevinfo.parent = parent;
pdevinfo.name = dev_name(&adev->dev);
pdevinfo.id = PLATFORM_DEVID_NONE;
pdevinfo.res = resources;

drivers/acpi/battery.c

View file
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 0084f30..670853e 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/kfifo.h>
#include <linux/list.h>
+#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
@@ -105,6 +106,9 @@ struct acpi_battery {
struct delayed_work acpi_notif_dwork;
struct notifier_block pm_nb;
struct list_head list;
+ unsigned long flags;
+
+ struct mutex property_lock; /* Protects properties below. */
unsigned long update_time;
int revision;
int rate_now;
@@ -131,7 +135,6 @@ struct acpi_battery {
char oem_info[MAX_STRING_LENGTH];
int state;
int power_unit;
- unsigned long flags;
};
#define to_acpi_battery(x) power_supply_get_drvdata(x)
@@ -189,20 +192,6 @@ static bool acpi_battery_is_degraded(struct acpi_battery *battery)
battery->full_charge_capacity < battery->design_capacity;
}
-static int acpi_battery_handle_discharging(struct acpi_battery *battery)
-{
- /*
- * Some devices wrongly report discharging if the battery's charge level
- * was above the device's start charging threshold atm the AC adapter
- * was plugged in and the device thus did not start a new charge cycle.
- */
- if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
- battery->rate_now == 0)
- return POWER_SUPPLY_STATUS_NOT_CHARGING;
-
- return POWER_SUPPLY_STATUS_DISCHARGING;
-}
-
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -210,15 +199,41 @@ static int acpi_battery_get_property(struct power_supply *psy,
int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0;
struct acpi_battery *battery = to_acpi_battery(psy);
- if (acpi_battery_present(battery)) {
- /* run battery update only if it is present */
- acpi_battery_get_state(battery);
- } else if (psp != POWER_SUPPLY_PROP_PRESENT)
- return -ENODEV;
+ /* run battery update only if it is present */
+ if (!acpi_battery_present(battery)) {
+ switch (psp) {
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = 0;
+ return 0;
+ default:
+ return -ENODEV;
+ }
+ }
+
+ mutex_lock(&battery->property_lock);
+
+ acpi_battery_get_state(battery);
+
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
+ /*
+ * Some devices wrongly report discharging if the battery's charge level
+ * was above the device's start charging threshold atm the AC adapter
+ * was plugged in and the device thus did not start a new charge cycle.
+ */
if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
- val->intval = acpi_battery_handle_discharging(battery);
+ if (battery->rate_now != 0) {
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ } else if (battery_ac_is_broken) {
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ mutex_unlock(&battery->property_lock);
+
+ val->intval = power_supply_is_system_supplied()
+ ? POWER_SUPPLY_STATUS_NOT_CHARGING
+ : POWER_SUPPLY_STATUS_DISCHARGING;
+ return 0;
+ }
else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
/* Check the rate and capacity to validate the status. */
if (!acpi_battery_is_full(battery) ||
@@ -321,6 +336,8 @@ static int acpi_battery_get_property(struct power_supply *psy,
default:
ret = -EINVAL;
}
+
+ mutex_unlock(&battery->property_lock);
return ret;
}
@@ -556,6 +573,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
int use_bix;
int result = -ENODEV;
+ lockdep_assert_held(&battery->property_lock);
+
if (!acpi_battery_present(battery))
return 0;
@@ -595,6 +614,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ lockdep_assert_held(&battery->property_lock);
+
if (!acpi_battery_present(battery))
return 0;
@@ -648,6 +669,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
{
acpi_status status = 0;
+ lockdep_assert_held(&battery->property_lock);
+
if (!acpi_battery_present(battery) ||
!test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
return -ENODEV;
@@ -665,6 +688,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
static int acpi_battery_init_alarm(struct acpi_battery *battery)
{
+ lockdep_assert_held(&battery->property_lock);
+
/* See if alarms are supported, and if so, set default */
if (!acpi_has_method(battery->device->handle, "_BTP")) {
clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
@@ -682,6 +707,8 @@ static ssize_t acpi_battery_alarm_show(struct device *dev,
{
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+ guard(mutex)(&battery->property_lock);
+
return sysfs_emit(buf, "%d\n", battery->alarm * 1000);
}
@@ -697,6 +724,8 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
if (err)
return err;
+ guard(mutex)(&battery->property_lock);
+
battery->alarm = x / 1000;
if (acpi_battery_present(battery))
acpi_battery_set_alarm(battery);
@@ -881,12 +910,17 @@ static int sysfs_add_battery(struct acpi_battery *battery)
.no_wakeup_source = true,
};
bool full_cap_broken = false;
+ int power_unit;
- if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
- !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
- full_cap_broken = true;
+ scoped_guard(mutex, &battery->property_lock) {
+ power_unit = battery->power_unit;
- if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
+ if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
+ !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
+ full_cap_broken = true;
+ }
+
+ if (power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
if (full_cap_broken) {
battery->bat_desc.properties =
charge_battery_full_cap_broken_props;
@@ -940,6 +974,9 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
static void find_battery(const struct dmi_header *dm, void *private)
{
struct acpi_battery *battery = (struct acpi_battery *)private;
+
+ lockdep_assert_held(&battery->property_lock);
+
/* Note: the hardcoded offsets below have been extracted from
* the source code of dmidecode.
*/
@@ -971,6 +1008,8 @@ static void find_battery(const struct dmi_header *dm, void *private)
*/
static void acpi_battery_quirks(struct acpi_battery *battery)
{
+ lockdep_assert_held(&battery->property_lock);
+
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
return;
@@ -1023,30 +1062,38 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
static int acpi_battery_update(struct acpi_battery *battery, bool resume)
{
int result = acpi_battery_get_status(battery);
+ bool wakeup;
if (result)
return result;
if (!acpi_battery_present(battery)) {
sysfs_remove_battery(battery);
- battery->update_time = 0;
+ scoped_guard(mutex, &battery->property_lock)
+ battery->update_time = 0;
return 0;
}
if (resume)
return 0;
- if (!battery->update_time) {
- result = acpi_battery_get_info(battery);
+ scoped_guard(mutex, &battery->property_lock) {
+ if (!battery->update_time) {
+ result = acpi_battery_get_info(battery);
+ if (result)
+ return result;
+ acpi_battery_init_alarm(battery);
+ }
+
+ result = acpi_battery_get_state(battery);
if (result)
return result;
- acpi_battery_init_alarm(battery);
- }
+ acpi_battery_quirks(battery);
- result = acpi_battery_get_state(battery);
- if (result)
- return result;
- acpi_battery_quirks(battery);
+ wakeup = ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
+ (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
+ (battery->capacity_now <= battery->alarm)));
+ }
if (!battery->bat) {
result = sysfs_add_battery(battery);
@@ -1058,9 +1105,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume)
* Wakeup the system if battery is critical low
* or lower than the alarm level
*/
- if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
- (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
- (battery->capacity_now <= battery->alarm)))
+ if (wakeup)
acpi_pm_wakeup_event(battery->phys_dev);
return result;
@@ -1073,12 +1118,14 @@ static void acpi_battery_refresh(struct acpi_battery *battery)
if (!battery->bat)
return;
- power_unit = battery->power_unit;
+ scoped_guard(mutex, &battery->property_lock) {
+ power_unit = battery->power_unit;
- acpi_battery_get_info(battery);
+ acpi_battery_get_info(battery);
- if (power_unit == battery->power_unit)
- return;
+ if (power_unit == battery->power_unit)
+ return;
+ }
/* The battery has changed its reporting units. */
sysfs_remove_battery(battery);
@@ -1170,17 +1217,21 @@ static int battery_notify(struct notifier_block *nb,
} else {
int result;
- result = acpi_battery_get_info(battery);
- if (result)
- return result;
+ scoped_guard(mutex, &battery->property_lock) {
+ result = acpi_battery_get_info(battery);
+ if (result)
+ return result;
+ }
result = sysfs_add_battery(battery);
if (result)
return result;
}
- acpi_battery_init_alarm(battery);
- acpi_battery_get_state(battery);
+ scoped_guard(mutex, &battery->property_lock) {
+ acpi_battery_init_alarm(battery);
+ acpi_battery_get_state(battery);
+ }
}
return 0;
@@ -1345,6 +1396,10 @@ static int acpi_battery_probe(struct platform_device *pdev)
if (result)
return result;
+ result = devm_mutex_init(&pdev->dev, &battery->property_lock);
+ if (result)
+ return result;
+
if (acpi_has_method(battery->device->handle, "_BIX"))
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);

drivers/acpi/bus.c

View file
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index beb5115..808c674 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -774,30 +774,52 @@ static int __init acpi_setup_sb_notify_handler(void)
Device Matching
-------------------------------------------------------------------------- */

This diff is incomplete. Download the complete patch.

drivers/acpi/button.c

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/pfr_update.c

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/power.c

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/scan.c

View file

This diff is incomplete. Download the complete patch.

include/acpi/acpi_bus.h

View file

This diff is incomplete. Download the complete patch.