Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+64 −13
Original line number Original line Diff line number Diff line
@@ -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);


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,
		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,
		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[] = {
	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[] = {
	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)
	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)
	}
	}
}
}


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)
		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)
			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] = {
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)
	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,
{
{
	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)
	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)
	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)


	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)
		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
+13 −2
Original line number Original line Diff line number Diff line
@@ -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)
	}
	}


	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)
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);
+2 −0
Original line number Original line Diff line number Diff line
@@ -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);