|
@@ -144,10 +144,7 @@
|
|
|
* so the first read after a fault returns the latched value and subsequent
|
|
|
* reads return the current value. In order to return the fault status
|
|
|
* to the user, have the interrupt handler save the reg's value and retrieve
|
|
|
- * it in the appropriate health/status routine. Each routine has its own
|
|
|
- * flag indicating whether it should use the value stored by the last run
|
|
|
- * of the interrupt handler or do an actual reg read. That way each routine
|
|
|
- * can report back whatever fault may have occured.
|
|
|
+ * it in the appropriate health/status routine.
|
|
|
*/
|
|
|
struct bq24190_dev_info {
|
|
|
struct i2c_client *client;
|
|
@@ -159,9 +156,6 @@ struct bq24190_dev_info {
|
|
|
unsigned int gpio_int;
|
|
|
unsigned int irq;
|
|
|
struct mutex f_reg_lock;
|
|
|
- bool charger_health_valid;
|
|
|
- bool battery_health_valid;
|
|
|
- bool battery_status_valid;
|
|
|
u8 f_reg;
|
|
|
u8 ss_reg;
|
|
|
u8 watchdog;
|
|
@@ -635,21 +629,11 @@ static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
|
|
|
union power_supply_propval *val)
|
|
|
{
|
|
|
u8 v;
|
|
|
- int health, ret;
|
|
|
+ int health;
|
|
|
|
|
|
mutex_lock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- if (bdi->charger_health_valid) {
|
|
|
- v = bdi->f_reg;
|
|
|
- bdi->charger_health_valid = false;
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
- } else {
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- ret = bq24190_read(bdi, BQ24190_REG_F, &v);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ v = bdi->f_reg;
|
|
|
+ mutex_unlock(&bdi->f_reg_lock);
|
|
|
|
|
|
if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
|
|
|
/*
|
|
@@ -936,18 +920,8 @@ static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
|
|
|
int status, ret;
|
|
|
|
|
|
mutex_lock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- if (bdi->battery_status_valid) {
|
|
|
- chrg_fault = bdi->f_reg;
|
|
|
- bdi->battery_status_valid = false;
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
- } else {
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ chrg_fault = bdi->f_reg;
|
|
|
+ mutex_unlock(&bdi->f_reg_lock);
|
|
|
|
|
|
chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
|
|
|
chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
|
|
@@ -995,21 +969,11 @@ static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
|
|
|
union power_supply_propval *val)
|
|
|
{
|
|
|
u8 v;
|
|
|
- int health, ret;
|
|
|
+ int health;
|
|
|
|
|
|
mutex_lock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- if (bdi->battery_health_valid) {
|
|
|
- v = bdi->f_reg;
|
|
|
- bdi->battery_health_valid = false;
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
- } else {
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- ret = bq24190_read(bdi, BQ24190_REG_F, &v);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ v = bdi->f_reg;
|
|
|
+ mutex_unlock(&bdi->f_reg_lock);
|
|
|
|
|
|
if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
|
|
|
health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
|
|
@@ -1201,7 +1165,7 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
|
|
|
| BQ24190_REG_F_NTC_FAULT_MASK;
|
|
|
bool alert_charger = false, alert_battery = false;
|
|
|
u8 ss_reg = 0, f_reg = 0;
|
|
|
- int ret;
|
|
|
+ int i, ret;
|
|
|
|
|
|
pm_runtime_get_sync(bdi->dev);
|
|
|
|
|
@@ -1231,33 +1195,35 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
|
|
|
alert_battery = true;
|
|
|
if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
|
|
|
alert_charger = true;
|
|
|
-
|
|
|
bdi->ss_reg = ss_reg;
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
- ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
|
|
|
- if (ret < 0) {
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
- dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ i = 0;
|
|
|
+ do {
|
|
|
+ ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
|
|
|
+ if (ret < 0) {
|
|
|
+ dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ } while (f_reg && ++i < 2);
|
|
|
|
|
|
if (f_reg != bdi->f_reg) {
|
|
|
+ dev_info(bdi->dev,
|
|
|
+ "Fault: boost %d, charge %d, battery %d, ntc %d\n",
|
|
|
+ !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
|
|
|
+ !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
|
|
|
+ !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
|
|
|
+ !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
|
|
|
+
|
|
|
+ mutex_lock(&bdi->f_reg_lock);
|
|
|
if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
|
|
|
alert_battery = true;
|
|
|
if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
|
|
|
alert_charger = true;
|
|
|
-
|
|
|
bdi->f_reg = f_reg;
|
|
|
- bdi->charger_health_valid = true;
|
|
|
- bdi->battery_health_valid = true;
|
|
|
- bdi->battery_status_valid = true;
|
|
|
+ mutex_unlock(&bdi->f_reg_lock);
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&bdi->f_reg_lock);
|
|
|
-
|
|
|
if (alert_charger)
|
|
|
power_supply_changed(bdi->charger);
|
|
|
if (alert_battery)
|
|
@@ -1377,9 +1343,6 @@ static int bq24190_probe(struct i2c_client *client,
|
|
|
mutex_init(&bdi->f_reg_lock);
|
|
|
bdi->f_reg = 0;
|
|
|
bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
|
|
|
- bdi->charger_health_valid = false;
|
|
|
- bdi->battery_health_valid = false;
|
|
|
- bdi->battery_status_valid = false;
|
|
|
|
|
|
i2c_set_clientdata(client, bdi);
|
|
|
|
|
@@ -1492,9 +1455,6 @@ static int bq24190_pm_resume(struct device *dev)
|
|
|
|
|
|
bdi->f_reg = 0;
|
|
|
bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
|
|
|
- bdi->charger_health_valid = false;
|
|
|
- bdi->battery_health_valid = false;
|
|
|
- bdi->battery_status_valid = false;
|
|
|
|
|
|
pm_runtime_get_sync(bdi->dev);
|
|
|
bq24190_register_reset(bdi);
|