Merge branch 'battery' into release
[pandora-kernel.git] / drivers / acpi / battery.c
index 4ba339d..7711d94 100644 (file)
@@ -99,6 +99,7 @@ enum {
 
 struct acpi_battery {
        struct mutex lock;
+       struct mutex sysfs_lock;
        struct power_supply bat;
        struct acpi_device *device;
        struct notifier_block pm_nb;
@@ -130,7 +131,7 @@ struct acpi_battery {
        unsigned long flags;
 };
 
-#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
 
 inline int acpi_battery_present(struct acpi_battery *battery)
 {
@@ -573,11 +574,16 @@ static int sysfs_add_battery(struct acpi_battery *battery)
 
 static void sysfs_remove_battery(struct acpi_battery *battery)
 {
-       if (!battery->bat.dev)
+       mutex_lock(&battery->sysfs_lock);
+       if (!battery->bat.dev) {
+               mutex_unlock(&battery->sysfs_lock);
                return;
+       }
+
        device_remove_file(battery->bat.dev, &alarm_attr);
        power_supply_unregister(&battery->bat);
        battery->bat.dev = NULL;
+       mutex_unlock(&battery->sysfs_lock);
 }
 
 /*
@@ -625,8 +631,11 @@ static int acpi_battery_update(struct acpi_battery *battery)
                        return result;
                acpi_battery_init_alarm(battery);
        }
-       if (!battery->bat.dev)
-               sysfs_add_battery(battery);
+       if (!battery->bat.dev) {
+               result = sysfs_add_battery(battery);
+               if (result)
+                       return result;
+       }
        result = acpi_battery_get_state(battery);
        acpi_battery_quirks(battery);
        return result;
@@ -862,7 +871,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
                }, \
        }
 
-static struct battery_file {
+static const struct battery_file {
        struct file_operations ops;
        mode_t mode;
        const char *name;
@@ -974,28 +983,38 @@ static int acpi_battery_add(struct acpi_device *device)
        strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
        device->driver_data = battery;
        mutex_init(&battery->lock);
+       mutex_init(&battery->sysfs_lock);
        if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
                        "_BIX", &handle)))
                set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
-       acpi_battery_update(battery);
+       result = acpi_battery_update(battery);
+       if (result)
+               goto fail;
 #ifdef CONFIG_ACPI_PROCFS_POWER
        result = acpi_battery_add_fs(device);
 #endif
-       if (!result) {
-               printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
-                       ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
-                       device->status.battery_present ? "present" : "absent");
-       } else {
+       if (result) {
 #ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_battery_remove_fs(device);
 #endif
-               kfree(battery);
+               goto fail;
        }
 
+       printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
+               ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
+               device->status.battery_present ? "present" : "absent");
+
        battery->pm_nb.notifier_call = battery_notify;
        register_pm_notifier(&battery->pm_nb);
 
        return result;
+
+fail:
+       sysfs_remove_battery(battery);
+       mutex_destroy(&battery->lock);
+       mutex_destroy(&battery->sysfs_lock);
+       kfree(battery);
+       return result;
 }
 
 static int acpi_battery_remove(struct acpi_device *device, int type)
@@ -1011,6 +1030,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 #endif
        sysfs_remove_battery(battery);
        mutex_destroy(&battery->lock);
+       mutex_destroy(&battery->sysfs_lock);
        kfree(battery);
        return 0;
 }