diff options
author | Mark Brown <broonie@linaro.org> | 2013-12-09 11:37:00 +0000 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-09 11:37:00 +0000 |
commit | eed4bafd63b5584adb832a582a931ecba41dec55 (patch) | |
tree | 5855807caaf53aec80037b2635eb2e2c0744565b /drivers/power | |
parent | 8bb495e3f02401ee6f76d1b1d77f3ac9f079e376 (diff) | |
parent | 2c06cb20454795a38876be5bd93dd6a8ddcc9d98 (diff) |
Merge branch 'android-3.10' of https://android.googlesource.com/kernel/common into lsk-v3.10-aosp
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/power_supply_core.c | 31 | ||||
-rw-r--r-- | drivers/power/power_supply_sysfs.c | 4 |
2 files changed, 31 insertions, 4 deletions
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 1c517c34e4b..082d3c2714e 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -67,23 +67,40 @@ static int __power_supply_changed_work(struct device *dev, void *data) static void power_supply_changed_work(struct work_struct *work) { + unsigned long flags; struct power_supply *psy = container_of(work, struct power_supply, changed_work); dev_dbg(psy->dev, "%s\n", __func__); - class_for_each_device(power_supply_class, NULL, psy, - __power_supply_changed_work); + spin_lock_irqsave(&psy->changed_lock, flags); + if (psy->changed) { + psy->changed = false; + spin_unlock_irqrestore(&psy->changed_lock, flags); - power_supply_update_leds(psy); + class_for_each_device(power_supply_class, NULL, psy, + __power_supply_changed_work); - kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); + power_supply_update_leds(psy); + + kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); + spin_lock_irqsave(&psy->changed_lock, flags); + } + if (!psy->changed) + pm_relax(psy->dev); + spin_unlock_irqrestore(&psy->changed_lock, flags); } void power_supply_changed(struct power_supply *psy) { + unsigned long flags; + dev_dbg(psy->dev, "%s\n", __func__); + spin_lock_irqsave(&psy->changed_lock, flags); + psy->changed = true; + pm_stay_awake(psy->dev); + spin_unlock_irqrestore(&psy->changed_lock, flags); schedule_work(&psy->changed_work); } EXPORT_SYMBOL_GPL(power_supply_changed); @@ -504,6 +521,11 @@ int power_supply_register(struct device *parent, struct power_supply *psy) if (rc) goto device_add_failed; + spin_lock_init(&psy->changed_lock); + rc = device_init_wakeup(dev, true); + if (rc) + goto wakeup_init_failed; + rc = psy_register_thermal(psy); if (rc) goto register_thermal_failed; @@ -525,6 +547,7 @@ create_triggers_failed: register_cooler_failed: psy_unregister_thermal(psy); register_thermal_failed: +wakeup_init_failed: device_del(dev); kobject_set_name_failed: device_add_failed: diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 29178f78d73..5a5fef4447e 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -189,6 +189,10 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(time_to_full_avg), POWER_SUPPLY_ATTR(type), POWER_SUPPLY_ATTR(scope), + /* Local extensions */ + POWER_SUPPLY_ATTR(usb_hc), + POWER_SUPPLY_ATTR(usb_otg), + POWER_SUPPLY_ATTR(charge_enabled), /* Properties of type `const char *' */ POWER_SUPPLY_ATTR(model_name), POWER_SUPPLY_ATTR(manufacturer), |