mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
commit
f58c41cc04
|
@ -56,6 +56,10 @@
|
|||
/* Battery power unit: 0 means mW, 1 means mA */
|
||||
#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
|
||||
|
||||
ACPI_MODULE_NAME("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)
|
||||
{
|
||||
/* either charging or discharging */
|
||||
/* charging, discharging or critical low */
|
||||
if (battery->state != 0)
|
||||
return 0;
|
||||
|
||||
|
@ -204,9 +208,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
|||
return -ENODEV;
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
if (battery->state & 0x01)
|
||||
if (battery->state & ACPI_BATTERY_STATE_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;
|
||||
else if (acpi_battery_is_charged(battery))
|
||||
val->intval = POWER_SUPPLY_STATUS_FULL;
|
||||
|
@ -269,6 +273,17 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
|||
else
|
||||
val->intval = 0;
|
||||
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:
|
||||
val->strval = battery->model_number;
|
||||
break;
|
||||
|
@ -296,6 +311,7 @@ static enum power_supply_property charge_battery_props[] = {
|
|||
POWER_SUPPLY_PROP_CHARGE_FULL,
|
||||
POWER_SUPPLY_PROP_CHARGE_NOW,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
|
@ -313,6 +329,7 @@ static enum power_supply_property energy_battery_props[] = {
|
|||
POWER_SUPPLY_PROP_ENERGY_FULL,
|
||||
POWER_SUPPLY_PROP_ENERGY_NOW,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
|
@ -605,7 +622,8 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
|||
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
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)
|
||||
return result;
|
||||
return device_create_file(battery->bat.dev, &alarm_attr);
|
||||
|
@ -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);
|
||||
result = acpi_battery_get_status(battery);
|
||||
|
@ -707,6 +725,10 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
|||
battery->update_time = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (resume)
|
||||
return 0;
|
||||
|
||||
if (!battery->update_time ||
|
||||
old_present != acpi_battery_present(battery)) {
|
||||
result = acpi_battery_get_info(battery);
|
||||
|
@ -720,7 +742,19 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
|||
return result;
|
||||
}
|
||||
result = acpi_battery_get_state(battery);
|
||||
if (result)
|
||||
return result;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -915,7 +949,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);
|
||||
}
|
||||
|
||||
|
@ -1030,7 +1064,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
|||
old = battery->bat.dev;
|
||||
if (event == ACPI_BATTERY_NOTIFY_INFO)
|
||||
acpi_battery_refresh(battery);
|
||||
acpi_battery_update(battery);
|
||||
acpi_battery_update(battery, false);
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev), event,
|
||||
acpi_battery_present(battery));
|
||||
|
@ -1045,13 +1079,27 @@ static int battery_notify(struct notifier_block *nb,
|
|||
{
|
||||
struct acpi_battery *battery = container_of(nb, struct acpi_battery,
|
||||
pm_nb);
|
||||
int result;
|
||||
|
||||
switch (mode) {
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
if (battery->bat.dev) {
|
||||
sysfs_remove_battery(battery);
|
||||
sysfs_add_battery(battery);
|
||||
}
|
||||
if (!acpi_battery_present(battery))
|
||||
return 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1087,7 +1135,7 @@ static int acpi_battery_add(struct acpi_device *device)
|
|||
mutex_init(&battery->sysfs_lock);
|
||||
if (acpi_has_method(battery->device->handle, "_BIX"))
|
||||
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
||||
result = acpi_battery_update(battery);
|
||||
result = acpi_battery_update(battery, false);
|
||||
if (result)
|
||||
goto fail;
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
|
@ -1107,6 +1155,8 @@ static int acpi_battery_add(struct acpi_device *device)
|
|||
battery->pm_nb.notifier_call = battery_notify;
|
||||
register_pm_notifier(&battery->pm_nb);
|
||||
|
||||
device_init_wakeup(&device->dev, 1);
|
||||
|
||||
return result;
|
||||
|
||||
fail:
|
||||
|
@ -1123,6 +1173,7 @@ static int acpi_battery_remove(struct acpi_device *device)
|
|||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
battery = acpi_driver_data(device);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
|
@ -1149,7 +1200,7 @@ static int acpi_battery_resume(struct device *dev)
|
|||
return -EINVAL;
|
||||
|
||||
battery->update_time = 0;
|
||||
acpi_battery_update(battery);
|
||||
acpi_battery_update(battery, true);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -537,7 +537,7 @@ static void psy_unregister_cooler(struct power_supply *psy)
|
|||
}
|
||||
#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;
|
||||
int rc;
|
||||
|
@ -568,7 +568,7 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
|
|||
}
|
||||
|
||||
spin_lock_init(&psy->changed_lock);
|
||||
rc = device_init_wakeup(dev, true);
|
||||
rc = device_init_wakeup(dev, ws);
|
||||
if (rc)
|
||||
goto wakeup_init_failed;
|
||||
|
||||
|
@ -606,8 +606,19 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
|
|||
success:
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
cancel_work_sync(&psy->changed_work);
|
||||
|
|
|
@ -264,6 +264,8 @@ static inline int power_supply_is_system_supplied(void) { return -ENOSYS; }
|
|||
|
||||
extern int power_supply_register(struct device *parent,
|
||||
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 int power_supply_powers(struct power_supply *psy, struct device *dev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue