diff options
author | Pritesh Raithatha <praithatha@nvidia.com> | 2011-12-28 19:21:44 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2012-01-04 11:44:26 +0530 |
commit | d42874773d71b8f71225adba714f6d12ccacd31f (patch) | |
tree | 483f4823179afc414bdfa61b46e48c5b525c8c98 /drivers/power | |
parent | c2f7bb5e2296f227d4fe0afcf71d8ce1bfca6ee8 (diff) |
power: bq27x00: add charging status update delay
bq27x00 takes 3 to 4 second to update charging/discharging
status so it requires to schedule work after 4 second on
external powersupply change.
Bug 902678
Change-Id: Ic5b42804ee3cd98ffab762c042bad447934eba85
Signed-off-by: Pritesh Raithatha <praithatha@nvidia.com>
Reviewed-on: http://git-master/r/72411
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/bq27x00_battery.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index fc2923dc03d6..e392f4dc77de 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -78,6 +78,8 @@ #define BQ27510_CNTL_SET_SLEEP 0x0013 #define BQ27510_CNTL_CLEAR_SLEEP 0x0014 +/* bq27x00 requires 3 to 4 second to update charging status */ +#define CHARGING_STATUS_UPDATE_DELAY_SECS 4 struct bq27x00_device_info; struct bq27x00_access_methods { @@ -113,12 +115,14 @@ struct bq27x00_device_info { unsigned long last_update; struct delayed_work work; + struct delayed_work external_power_changed_work; struct power_supply bat; struct bq27x00_access_methods bus; struct mutex lock; + struct mutex update_lock; }; static enum power_supply_property bq27x00_battery_props[] = { @@ -319,6 +323,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) struct bq27x00_reg_cache cache = {0, }; bool is_bq27500 = (di->chip == BQ27500 || di->chip == BQ27510); + mutex_lock(&di->update_lock); cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500); if (cache.flags >= 0) { cache.capacity = bq27x00_battery_read_rsoc(di); @@ -345,6 +350,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) } di->last_update = jiffies; + mutex_unlock(&di->update_lock); } static void bq27x00_battery_poll(struct work_struct *work) @@ -361,6 +367,14 @@ static void bq27x00_battery_poll(struct work_struct *work) } } +static void bq27x00_external_power_changed_work(struct work_struct *work) +{ + struct bq27x00_device_info *di = + container_of(work, struct bq27x00_device_info, + external_power_changed_work.work); + + bq27x00_update(di); +} /* * Return the battery temperature in tenths of degree Celsius @@ -631,12 +645,19 @@ static int bq27x00_battery_get_property(struct power_supply *psy, return ret; } +static unsigned int charging_update_delay_secs = + CHARGING_STATUS_UPDATE_DELAY_SECS; +module_param(charging_update_delay_secs, uint, 0644); +MODULE_PARM_DESC(charging_update_delay_secs, "battery charging " \ + "status update delay in seconds"); + static void bq27x00_external_power_changed(struct power_supply *psy) { struct bq27x00_device_info *di = to_bq27x00_device_info(psy); - cancel_delayed_work_sync(&di->work); - schedule_delayed_work(&di->work, 0); + cancel_delayed_work_sync(&di->external_power_changed_work); + schedule_delayed_work(&di->external_power_changed_work, + charging_update_delay_secs * HZ); } static int bq27x00_powersupply_init(struct bq27x00_device_info *di) @@ -650,7 +671,10 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di) di->bat.external_power_changed = bq27x00_external_power_changed; INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll); + INIT_DELAYED_WORK(&di->external_power_changed_work, + bq27x00_external_power_changed_work); mutex_init(&di->lock); + mutex_init(&di->update_lock); ret = power_supply_register(di->dev, &di->bat); if (ret) { @@ -668,10 +692,11 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di) static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di) { cancel_delayed_work_sync(&di->work); - + cancel_delayed_work_sync(&di->external_power_changed_work); power_supply_unregister(&di->bat); mutex_destroy(&di->lock); + mutex_destroy(&di->update_lock); } |