aboutsummaryrefslogtreecommitdiff
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 7dd3f9fb9f3..f22741069ad 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -976,6 +976,18 @@ static int battery_notify(struct notifier_block *nb,
return 0;
}
+static LIST_HEAD(acpi_battery_domain);
+
+static void acpi_battery_update_async(struct acpi_device *device, async_cookie_t cookie)
+{
+ struct acpi_battery *battery = acpi_driver_data(device);
+
+ acpi_battery_update(battery);
+ printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
+ ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
+ device->status.battery_present ? "present" : "absent");
+}
+
static int acpi_battery_add(struct acpi_device *device)
{
int result = 0;
@@ -995,13 +1007,16 @@ static int acpi_battery_add(struct acpi_device *device)
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
"_BIX", &handle)))
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
- result = acpi_battery_update(battery);
- if (result)
- goto fail;
+
+ /* Mark the battery for update at first access. */
+ battery->update_time = 0;
#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_battery_add_fs(device);
#endif
- if (result) {
+ if (!result) {
+ async_schedule_domain(acpi_battery_update_async, device, &acpi_battery_domain);
+
+ } else {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_remove_fs(device);
#endif
@@ -1031,6 +1046,10 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
+
+ /* Ensure all async updates are complete before freeing the battery. */
+ async_synchronize_full_domain(&acpi_battery_domain);
+
battery = acpi_driver_data(device);
unregister_pm_notifier(&battery->pm_nb);
#ifdef CONFIG_ACPI_PROCFS_POWER
@@ -1068,27 +1087,21 @@ static struct acpi_driver acpi_battery_driver = {
},
};
-static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
+static int __init acpi_battery_init(void)
{
if (acpi_disabled)
return;
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
- return;
+ return -1;
#endif
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
- return;
+ return -1;
}
- return;
-}
-
-static int __init acpi_battery_init(void)
-{
- async_schedule(acpi_battery_init_async, NULL);
return 0;
}