Kyle McMartin 6406b98
From kyle@infradead.org Wed Sep 22 18:35:38 2010
Kyle McMartin 6406b98
From: Matthew Garrett <mjg@redhat.com>
Kyle McMartin 6406b98
To: linux-acpi@vger.kernel.org
Kyle McMartin 6406b98
Cc: linux-kernel@vger.kernel.org, Matthew Garrett <mjg@redhat.com>
Kyle McMartin 6406b98
Subject: [PATCH] acpi: Update battery information on notification 0x81
Kyle McMartin 6406b98
Date: 	Mon, 16 Aug 2010 16:32:19 -0400
Kyle McMartin 6406b98
Kyle McMartin 6406b98
A notification event 0x81 from an ACPI battery device requires us to
Kyle McMartin 6406b98
re-read the battery information structure. Do so, and if the battery's
Kyle McMartin 6406b98
reporting units have changed (as is the case on some Thinkpads) destroy
Kyle McMartin 6406b98
and recreate the battery in order to populate the fields correctly.
Kyle McMartin 6406b98
Kyle McMartin 6406b98
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Kyle McMartin 6406b98
---
Kyle McMartin 7b2f649
 drivers/acpi/battery.c |   20 +++++++++++++++-----
Kyle McMartin 7b2f649
 1 files changed, 15 insertions(+), 5 deletions(-)
Kyle McMartin 6406b98
Kyle McMartin 6406b98
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
Kyle McMartin 7b2f649
index 95649d3..2a774a8 100644
Kyle McMartin 6406b98
--- a/drivers/acpi/battery.c
Kyle McMartin 6406b98
+++ b/drivers/acpi/battery.c
Kyle McMartin 7b2f649
@@ -605,9 +605,10 @@ static void acpi_battery_quirks2(struct acpi_battery *battery)
Kyle McMartin 6406b98
 	}
Kyle McMartin 6406b98
 }
Kyle McMartin 6406b98
 
Kyle McMartin 6406b98
-static int acpi_battery_update(struct acpi_battery *battery)
Kyle McMartin 6406b98
+static int acpi_battery_update(struct acpi_battery *battery, bool get_info)
Kyle McMartin 6406b98
 {
Kyle McMartin 6406b98
 	int result, old_present = acpi_battery_present(battery);
Kyle McMartin 6406b98
+	int old_power_unit = battery->power_unit;
Kyle McMartin 6406b98
 	result = acpi_battery_get_status(battery);
Kyle McMartin 6406b98
 	if (result)
Kyle McMartin 6406b98
 		return result;
Kyle McMartin 7b2f649
@@ -628,6 +629,14 @@ static int acpi_battery_update(struct acpi_battery *battery)
Kyle McMartin 6406b98
 		sysfs_add_battery(battery);
Kyle McMartin 7b2f649
 	result = acpi_battery_get_state(battery);
Kyle McMartin 7b2f649
 	acpi_battery_quirks2(battery);
Kyle McMartin 6406b98
+	if (get_info) {
Kyle McMartin 6406b98
+		acpi_battery_get_info(battery);
Kyle McMartin 6406b98
+		if (old_power_unit != battery->power_unit) {
Kyle McMartin 6406b98
+			/* The battery has changed its reporting units */
Kyle McMartin 6406b98
+			sysfs_remove_battery(battery);
Kyle McMartin 6406b98
+			sysfs_add_battery(battery);
Kyle McMartin 6406b98
+		}
Kyle McMartin 6406b98
+	}
Kyle McMartin 7b2f649
 	return result;
Kyle McMartin 6406b98
 }
Kyle McMartin 6406b98
 
Kyle McMartin 7b2f649
@@ -803,7 +812,7 @@ static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
Kyle McMartin 6406b98
 static int acpi_battery_read(int fid, struct seq_file *seq)
Kyle McMartin 6406b98
 {
Kyle McMartin 6406b98
 	struct acpi_battery *battery = seq->private;
Kyle McMartin 6406b98
-	int result = acpi_battery_update(battery);
Kyle McMartin 6406b98
+	int result = acpi_battery_update(battery, false);
Kyle McMartin 6406b98
 	return acpi_print_funcs[fid](seq, result);
Kyle McMartin 6406b98
 }
Kyle McMartin 6406b98
 
Kyle McMartin 7b2f649
@@ -914,7 +923,8 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
Kyle McMartin 7b2f649
 	if (!battery)
Kyle McMartin 7b2f649
 		return;
Kyle McMartin 6406b98
 	old = battery->bat.dev;
Kyle McMartin 6406b98
-	acpi_battery_update(battery);
Kyle McMartin 6406b98
+	acpi_battery_update(battery, (event == ACPI_BATTERY_NOTIFY_INFO ? true
Kyle McMartin 6406b98
+				      : false));
Kyle McMartin 6406b98
 	acpi_bus_generate_proc_event(device, event,
Kyle McMartin 6406b98
 				     acpi_battery_present(battery));
Kyle McMartin 6406b98
 	acpi_bus_generate_netlink_event(device->pnp.device_class,
Kyle McMartin 7b2f649
@@ -943,7 +953,7 @@ static int acpi_battery_add(struct acpi_device *device)
Kyle McMartin 6406b98
 	if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
Kyle McMartin 6406b98
 			"_BIX", &handle)))
Kyle McMartin 6406b98
 		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
Kyle McMartin 6406b98
-	acpi_battery_update(battery);
Kyle McMartin 6406b98
+	acpi_battery_update(battery, false);
Kyle McMartin 6406b98
 #ifdef CONFIG_ACPI_PROCFS_POWER
Kyle McMartin 6406b98
 	result = acpi_battery_add_fs(device);
Kyle McMartin 6406b98
 #endif
Kyle McMartin 7b2f649
@@ -984,7 +994,7 @@ static int acpi_battery_resume(struct acpi_device *device)
Kyle McMartin 6406b98
 		return -EINVAL;
Kyle McMartin 6406b98
 	battery = acpi_driver_data(device);
Kyle McMartin 6406b98
 	battery->update_time = 0;
Kyle McMartin 6406b98
-	acpi_battery_update(battery);
Kyle McMartin 6406b98
+	acpi_battery_update(battery, true);
Kyle McMartin 6406b98
 	return 0;
Kyle McMartin 6406b98
 }
Kyle McMartin 6406b98