86 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			3.0 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 |   20 +++++++++++++++-----
 | |
|  1 files changed, 15 insertions(+), 5 deletions(-)
 | |
| 
 | |
| diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
 | |
| index 95649d3..2a774a8 100644
 | |
| --- a/drivers/acpi/battery.c
 | |
| +++ b/drivers/acpi/battery.c
 | |
| @@ -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;
 | |
|  }
 | |
|  
 |