forked from rpms/kernel
		
	
		
			
				
	
	
		
			105 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From kyle@infradead.org Wed Sep 22 18:35:38 2010
 | 
						|
From: Matthew Garrett <mjg@redhat.com>
 | 
						|
To: linux-acpi@vger.kernel.org
 | 
						|
Cc: linux-kernel@vger.kernel.org, Matthew Garrett <mjg@redhat.com>
 | 
						|
Subject: [PATCH] acpi: Update battery information on notification 0x81
 | 
						|
Date: 	Mon, 16 Aug 2010 16:32:19 -0400
 | 
						|
 | 
						|
A notification event 0x81 from an ACPI battery device requires us to
 | 
						|
re-read the battery information structure. Do so, and if the battery's
 | 
						|
reporting units have changed (as is the case on some Thinkpads) destroy
 | 
						|
and recreate the battery in order to populate the fields correctly.
 | 
						|
 | 
						|
Signed-off-by: Matthew Garrett <mjg@redhat.com>
 | 
						|
---
 | 
						|
 | 
						|
 drivers/acpi/battery.c |   24 +++++++++++++++++-------
 | 
						|
 1 files changed, 17 insertions(+), 7 deletions(-)
 | 
						|
 | 
						|
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
 | 
						|
index 9fb9d5a..8da9c88 100644
 | 
						|
--- a/drivers/acpi/battery.c
 | 
						|
+++ b/drivers/acpi/battery.c
 | 
						|
@@ -130,7 +130,7 @@ struct acpi_battery {
 | 
						|
 	unsigned long flags;
 | 
						|
 };
 | 
						|
 
 | 
						|
-static int acpi_battery_update(struct acpi_battery *battery);
 | 
						|
+static int acpi_battery_update(struct acpi_battery *battery, bool get_info);
 | 
						|
 
 | 
						|
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
 | 
						|
 
 | 
						|
@@ -186,7 +186,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
 | 
						|
 	int ret = 0;
 | 
						|
 	struct acpi_battery *battery = to_acpi_battery(psy);
 | 
						|
 
 | 
						|
-	if (acpi_battery_update(battery))
 | 
						|
+	if (acpi_battery_update(battery, false))
 | 
						|
 		return -ENODEV;
 | 
						|
 
 | 
						|
 	if (acpi_battery_present(battery)) {
 | 
						|
@@ -610,9 +610,11 @@ static void acpi_battery_quirks2(struct acpi_battery *battery)
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int acpi_battery_update(struct acpi_battery *battery)
 | 
						|
+static int acpi_battery_update(struct acpi_battery *battery, bool get_info)
 | 
						|
 {
 | 
						|
 	int result, old_present = acpi_battery_present(battery);
 | 
						|
+	int old_power_unit = battery->power_unit;
 | 
						|
+
 | 
						|
 	result = acpi_battery_get_status(battery);
 | 
						|
 	if (result)
 | 
						|
 		return result;
 | 
						|
@@ -631,6 +633,14 @@ static int acpi_battery_update(struct acpi_battery *battery)
 | 
						|
 	}
 | 
						|
 	if (!battery->bat.dev)
 | 
						|
 		sysfs_add_battery(battery);
 | 
						|
+	if (get_info) {
 | 
						|
+		acpi_battery_get_info(battery);
 | 
						|
+		if (old_power_unit != battery->power_unit) {
 | 
						|
+			/* The battery has changed its reporting units */
 | 
						|
+			sysfs_remove_battery(battery);
 | 
						|
+			sysfs_add_battery(battery);
 | 
						|
+		}
 | 
						|
+	}
 | 
						|
 	result = acpi_battery_get_state(battery);
 | 
						|
 	acpi_battery_quirks2(battery);
 | 
						|
 	return result;
 | 
						|
@@ -808,7 +818,7 @@ static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
 | 
						|
 static int acpi_battery_read(int fid, struct seq_file *seq)
 | 
						|
 {
 | 
						|
 	struct acpi_battery *battery = seq->private;
 | 
						|
-	int result = acpi_battery_update(battery);
 | 
						|
+	int result = acpi_battery_update(battery, false);
 | 
						|
 	return acpi_print_funcs[fid](seq, result);
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -919,7 +929,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
 | 
						|
 	if (!battery)
 | 
						|
 		return;
 | 
						|
 	old = battery->bat.dev;
 | 
						|
-	acpi_battery_update(battery);
 | 
						|
+	acpi_battery_update(battery, (event == ACPI_BATTERY_NOTIFY_INFO));
 | 
						|
 	acpi_bus_generate_proc_event(device, event,
 | 
						|
 				     acpi_battery_present(battery));
 | 
						|
 	acpi_bus_generate_netlink_event(device->pnp.device_class,
 | 
						|
@@ -948,7 +958,7 @@ 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);
 | 
						|
-	acpi_battery_update(battery);
 | 
						|
+	acpi_battery_update(battery, false);
 | 
						|
 #ifdef CONFIG_ACPI_PROCFS_POWER
 | 
						|
 	result = acpi_battery_add_fs(device);
 | 
						|
 #endif
 | 
						|
@@ -989,7 +999,7 @@ static int acpi_battery_resume(struct acpi_device *device)
 | 
						|
 		return -EINVAL;
 | 
						|
 	battery = acpi_driver_data(device);
 | 
						|
 	battery->update_time = 0;
 | 
						|
-	acpi_battery_update(battery);
 | 
						|
+	acpi_battery_update(battery, true);
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 |