| 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 | 20 +++++++++++++++----- |
| 1 files changed, 15 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c |
| index 95649d3..2a774a8 100644 |
| |
| |
| @@ -605,9 +605,10 @@ 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; |
| @@ -628,6 +629,14 @@ static int acpi_battery_update(struct acpi_battery *battery) |
| sysfs_add_battery(battery); |
| result = acpi_battery_get_state(battery); |
| acpi_battery_quirks2(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); |
| + } |
| + } |
| return result; |
| } |
| |
| @@ -803,7 +812,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); |
| } |
| |
| @@ -914,7 +923,8 @@ 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 ? true |
| + : false)); |
| acpi_bus_generate_proc_event(device, event, |
| acpi_battery_present(battery)); |
| acpi_bus_generate_netlink_event(device->pnp.device_class, |
| @@ -943,7 +953,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 |
| @@ -984,7 +994,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; |
| } |
| |