Commit f58c41cc authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'acpi-battery'

* acpi-battery:
  ACPI / battery: wakeup the system only when necessary
  power_supply: allow power supply devices registered w/o wakeup source
  ACPI / battery: introduce support for POWER_SUPPLY_PROP_CAPACITY_LEVEL
  ACPI / battery: Accelerate battery resume callback
parents ee7f9d7c e0d1f09e
...@@ -56,6 +56,10 @@ ...@@ -56,6 +56,10 @@
/* Battery power unit: 0 means mW, 1 means mA */ /* Battery power unit: 0 means mW, 1 means mA */
#define ACPI_BATTERY_POWER_UNIT_MA 1 #define ACPI_BATTERY_POWER_UNIT_MA 1
#define ACPI_BATTERY_STATE_DISCHARGING 0x1
#define ACPI_BATTERY_STATE_CHARGING 0x2
#define ACPI_BATTERY_STATE_CRITICAL 0x4
#define _COMPONENT ACPI_BATTERY_COMPONENT #define _COMPONENT ACPI_BATTERY_COMPONENT
ACPI_MODULE_NAME("battery"); ACPI_MODULE_NAME("battery");
...@@ -169,7 +173,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery); ...@@ -169,7 +173,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery);
static int acpi_battery_is_charged(struct acpi_battery *battery) static int acpi_battery_is_charged(struct acpi_battery *battery)
{ {
/* either charging or discharging */ /* charging, discharging or critical low */
if (battery->state != 0) if (battery->state != 0)
return 0; return 0;
...@@ -204,9 +208,9 @@ static int acpi_battery_get_property(struct power_supply *psy, ...@@ -204,9 +208,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
return -ENODEV; return -ENODEV;
switch (psp) { switch (psp) {
case POWER_SUPPLY_PROP_STATUS: case POWER_SUPPLY_PROP_STATUS:
if (battery->state & 0x01) if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING; val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (battery->state & 0x02) else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
val->intval = POWER_SUPPLY_STATUS_CHARGING; val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (acpi_battery_is_charged(battery)) else if (acpi_battery_is_charged(battery))
val->intval = POWER_SUPPLY_STATUS_FULL; val->intval = POWER_SUPPLY_STATUS_FULL;
...@@ -269,6 +273,17 @@ static int acpi_battery_get_property(struct power_supply *psy, ...@@ -269,6 +273,17 @@ static int acpi_battery_get_property(struct power_supply *psy,
else else
val->intval = 0; val->intval = 0;
break; break;
case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
(battery->capacity_now <= battery->alarm))
val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
else if (acpi_battery_is_charged(battery))
val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
else
val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
break;
case POWER_SUPPLY_PROP_MODEL_NAME: case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = battery->model_number; val->strval = battery->model_number;
break; break;
...@@ -296,6 +311,7 @@ static enum power_supply_property charge_battery_props[] = { ...@@ -296,6 +311,7 @@ static enum power_supply_property charge_battery_props[] = {
POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_SERIAL_NUMBER, POWER_SUPPLY_PROP_SERIAL_NUMBER,
...@@ -313,6 +329,7 @@ static enum power_supply_property energy_battery_props[] = { ...@@ -313,6 +329,7 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_ENERGY_FULL, POWER_SUPPLY_PROP_ENERGY_FULL,
POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_ENERGY_NOW,
POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_SERIAL_NUMBER, POWER_SUPPLY_PROP_SERIAL_NUMBER,
...@@ -605,7 +622,8 @@ static int sysfs_add_battery(struct acpi_battery *battery) ...@@ -605,7 +622,8 @@ static int sysfs_add_battery(struct acpi_battery *battery)
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
battery->bat.get_property = acpi_battery_get_property; battery->bat.get_property = acpi_battery_get_property;
result = power_supply_register(&battery->device->dev, &battery->bat); result = power_supply_register_no_ws(&battery->device->dev, &battery->bat);
if (result) if (result)
return result; return result;
return device_create_file(battery->bat.dev, &alarm_attr); return device_create_file(battery->bat.dev, &alarm_attr);
...@@ -696,7 +714,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery) ...@@ -696,7 +714,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
} }
} }
static int acpi_battery_update(struct acpi_battery *battery) static int acpi_battery_update(struct acpi_battery *battery, bool resume)
{ {
int result, old_present = acpi_battery_present(battery); int result, old_present = acpi_battery_present(battery);
result = acpi_battery_get_status(battery); result = acpi_battery_get_status(battery);
...@@ -707,6 +725,10 @@ static int acpi_battery_update(struct acpi_battery *battery) ...@@ -707,6 +725,10 @@ static int acpi_battery_update(struct acpi_battery *battery)
battery->update_time = 0; battery->update_time = 0;
return 0; return 0;
} }
if (resume)
return 0;
if (!battery->update_time || if (!battery->update_time ||
old_present != acpi_battery_present(battery)) { old_present != acpi_battery_present(battery)) {
result = acpi_battery_get_info(battery); result = acpi_battery_get_info(battery);
...@@ -720,7 +742,19 @@ static int acpi_battery_update(struct acpi_battery *battery) ...@@ -720,7 +742,19 @@ static int acpi_battery_update(struct acpi_battery *battery)
return result; return result;
} }
result = acpi_battery_get_state(battery); result = acpi_battery_get_state(battery);
if (result)
return result;
acpi_battery_quirks(battery); acpi_battery_quirks(battery);
/*
* Wakeup the system if battery is critical low
* or lower than the alarm level
*/
if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
(test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
(battery->capacity_now <= battery->alarm)))
pm_wakeup_event(&battery->device->dev, 0);
return result; return result;
} }
...@@ -915,7 +949,7 @@ static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { ...@@ -915,7 +949,7 @@ static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
static int acpi_battery_read(int fid, struct seq_file *seq) static int acpi_battery_read(int fid, struct seq_file *seq)
{ {
struct acpi_battery *battery = seq->private; 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); return acpi_print_funcs[fid](seq, result);
} }
...@@ -1030,7 +1064,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) ...@@ -1030,7 +1064,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
old = battery->bat.dev; old = battery->bat.dev;
if (event == ACPI_BATTERY_NOTIFY_INFO) if (event == ACPI_BATTERY_NOTIFY_INFO)
acpi_battery_refresh(battery); acpi_battery_refresh(battery);
acpi_battery_update(battery); acpi_battery_update(battery, false);
acpi_bus_generate_netlink_event(device->pnp.device_class, acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, dev_name(&device->dev), event,
acpi_battery_present(battery)); acpi_battery_present(battery));
...@@ -1045,13 +1079,27 @@ static int battery_notify(struct notifier_block *nb, ...@@ -1045,13 +1079,27 @@ static int battery_notify(struct notifier_block *nb,
{ {
struct acpi_battery *battery = container_of(nb, struct acpi_battery, struct acpi_battery *battery = container_of(nb, struct acpi_battery,
pm_nb); pm_nb);
int result;
switch (mode) { switch (mode) {
case PM_POST_HIBERNATION: case PM_POST_HIBERNATION:
case PM_POST_SUSPEND: case PM_POST_SUSPEND:
if (battery->bat.dev) { if (!acpi_battery_present(battery))
sysfs_remove_battery(battery); return 0;
sysfs_add_battery(battery);
} if (!battery->bat.dev) {
result = acpi_battery_get_info(battery);
if (result)
return result;
result = sysfs_add_battery(battery);
if (result)
return result;
} else
acpi_battery_refresh(battery);
acpi_battery_init_alarm(battery);
acpi_battery_get_state(battery);
break; break;
} }
...@@ -1087,7 +1135,7 @@ static int acpi_battery_add(struct acpi_device *device) ...@@ -1087,7 +1135,7 @@ static int acpi_battery_add(struct acpi_device *device)
mutex_init(&battery->sysfs_lock); mutex_init(&battery->sysfs_lock);
if (acpi_has_method(battery->device->handle, "_BIX")) if (acpi_has_method(battery->device->handle, "_BIX"))
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
result = acpi_battery_update(battery); result = acpi_battery_update(battery, false);
if (result) if (result)
goto fail; goto fail;
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
...@@ -1107,6 +1155,8 @@ static int acpi_battery_add(struct acpi_device *device) ...@@ -1107,6 +1155,8 @@ static int acpi_battery_add(struct acpi_device *device)
battery->pm_nb.notifier_call = battery_notify; battery->pm_nb.notifier_call = battery_notify;
register_pm_notifier(&battery->pm_nb); register_pm_notifier(&battery->pm_nb);
device_init_wakeup(&device->dev, 1);
return result; return result;
fail: fail:
...@@ -1123,6 +1173,7 @@ static int acpi_battery_remove(struct acpi_device *device) ...@@ -1123,6 +1173,7 @@ static int acpi_battery_remove(struct acpi_device *device)
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return -EINVAL;
device_init_wakeup(&device->dev, 0);
battery = acpi_driver_data(device); battery = acpi_driver_data(device);
unregister_pm_notifier(&battery->pm_nb); unregister_pm_notifier(&battery->pm_nb);
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
...@@ -1149,7 +1200,7 @@ static int acpi_battery_resume(struct device *dev) ...@@ -1149,7 +1200,7 @@ static int acpi_battery_resume(struct device *dev)
return -EINVAL; return -EINVAL;
battery->update_time = 0; battery->update_time = 0;
acpi_battery_update(battery); acpi_battery_update(battery, true);
return 0; return 0;
} }
#else #else
......
...@@ -537,7 +537,7 @@ static void psy_unregister_cooler(struct power_supply *psy) ...@@ -537,7 +537,7 @@ static void psy_unregister_cooler(struct power_supply *psy)
} }
#endif #endif
int power_supply_register(struct device *parent, struct power_supply *psy) int __power_supply_register(struct device *parent, struct power_supply *psy, bool ws)
{ {
struct device *dev; struct device *dev;
int rc; int rc;
...@@ -568,7 +568,7 @@ int power_supply_register(struct device *parent, struct power_supply *psy) ...@@ -568,7 +568,7 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
} }
spin_lock_init(&psy->changed_lock); spin_lock_init(&psy->changed_lock);
rc = device_init_wakeup(dev, true); rc = device_init_wakeup(dev, ws);
if (rc) if (rc)
goto wakeup_init_failed; goto wakeup_init_failed;
...@@ -606,8 +606,19 @@ int power_supply_register(struct device *parent, struct power_supply *psy) ...@@ -606,8 +606,19 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
success: success:
return rc; return rc;
} }
int power_supply_register(struct device *parent, struct power_supply *psy)
{
return __power_supply_register(parent, psy, true);
}
EXPORT_SYMBOL_GPL(power_supply_register); EXPORT_SYMBOL_GPL(power_supply_register);
int power_supply_register_no_ws(struct device *parent, struct power_supply *psy)
{
return __power_supply_register(parent, psy, false);
}
EXPORT_SYMBOL_GPL(power_supply_register_no_ws);
void power_supply_unregister(struct power_supply *psy) void power_supply_unregister(struct power_supply *psy)
{ {
cancel_work_sync(&psy->changed_work); cancel_work_sync(&psy->changed_work);
......
...@@ -264,6 +264,8 @@ static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } ...@@ -264,6 +264,8 @@ static inline int power_supply_is_system_supplied(void) { return -ENOSYS; }
extern int power_supply_register(struct device *parent, extern int power_supply_register(struct device *parent,
struct power_supply *psy); struct power_supply *psy);
extern int power_supply_register_no_ws(struct device *parent,
struct power_supply *psy);
extern void power_supply_unregister(struct power_supply *psy); extern void power_supply_unregister(struct power_supply *psy);
extern int power_supply_powers(struct power_supply *psy, struct device *dev); extern int power_supply_powers(struct power_supply *psy, struct device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment