From 4c41d3ad6544f1c9aec37c441af04f5d0ad3a731 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 7 Nov 2007 15:09:09 -0800 Subject: ACPI: Always return valid 'status' from acpi_battery_get_property() If a battery is at a critical charge level and not being charged or discharged, then the ACPI _BST method will return a state of 4, and the current acpi_battery_get_property() code will not set any property value for POWER_SUPPLY_PROP_STATUS. This will cause an oops in power_supply_show_property() when it reads off the end of the status_text array. This actually was causing a 100% reproducible crash on boot on my laptop with two batteries, when one battery was completely drained and the laptop was not plugged in. Fix this by making sure acpi_battery_get_property() returns POWER_SUPPLY_STATUS_UNKNOWN for any battery state it doesn't already handle explicitly. There doesn't seem to be any status enum value defined that makes more sense than 'unknown' for a battery at a critical charge level. Signed-off-by: Roland Dreier Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/battery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index c2ce0ad2169..cbb27b4ddea 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -152,6 +152,8 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_STATUS_CHARGING; else if (battery->state == 0) val->intval = POWER_SUPPLY_STATUS_FULL; + else + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; break; case POWER_SUPPLY_PROP_PRESENT: val->intval = acpi_battery_present(battery); -- cgit v1.2.3 From 037cbc63fd83162a8ee0c69680207ce4609adbea Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 18 Nov 2007 00:32:31 +0300 Subject: ACPI: SBS: Fix retval warning drivers/acpi/sbs.c: In function acpi_battery_add: drivers/acpi/sbs.c:811: warning: ignoring return value of device_create_file, declared with attribute warn_unused_result Additional cleanups: * use struct acpi_battery in acpi_battery_remove() to clean up function calls, just like acpi_battery_add() already does. * put braces around unregister call, as it depends on dev being not NULL. * remove unneeded braces Signed-off-by: Jeff Garzik Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 90fd09c65f9..73c1ba31429 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -113,6 +113,7 @@ struct acpi_battery { u16 spec; u8 id; u8 present:1; + u8 have_sysfs_alarm:1; }; #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); @@ -808,7 +809,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) } battery->bat.get_property = acpi_sbs_battery_get_property; result = power_supply_register(&sbs->device->dev, &battery->bat); - device_create_file(battery->bat.dev, &alarm_attr); + if (result) + goto end; + result = device_create_file(battery->bat.dev, &alarm_attr); + if (result) + goto end; + battery->have_sysfs_alarm = 1; + end: printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), battery->name, sbs->battery->present ? "present" : "absent"); @@ -817,14 +824,16 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) static void acpi_battery_remove(struct acpi_sbs *sbs, int id) { - if (sbs->battery[id].bat.dev) - device_remove_file(sbs->battery[id].bat.dev, &alarm_attr); - power_supply_unregister(&sbs->battery[id].bat); -#ifdef CONFIG_ACPI_PROCFS - if (sbs->battery[id].proc_entry) { - acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry), - acpi_battery_dir); + struct acpi_battery *battery = &sbs->battery[id]; + + if (battery->bat.dev) { + if (battery->have_sysfs_alarm) + device_remove_file(battery->bat.dev, &alarm_attr); + power_supply_unregister(&battery->bat); } +#ifdef CONFIG_ACPI_PROCFS + if (battery->proc_entry) + acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); #endif } -- cgit v1.2.3