diff options
-rw-r--r-- | drivers/power/supply/bq24190_charger.c | 94 |
1 files changed, 27 insertions, 67 deletions
diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 94d282286bfd..5659b831720f 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c | |||
@@ -144,10 +144,7 @@ | |||
144 | * so the first read after a fault returns the latched value and subsequent | 144 | * so the first read after a fault returns the latched value and subsequent |
145 | * reads return the current value. In order to return the fault status | 145 | * reads return the current value. In order to return the fault status |
146 | * to the user, have the interrupt handler save the reg's value and retrieve | 146 | * to the user, have the interrupt handler save the reg's value and retrieve |
147 | * it in the appropriate health/status routine. Each routine has its own | 147 | * it in the appropriate health/status routine. |
148 | * flag indicating whether it should use the value stored by the last run | ||
149 | * of the interrupt handler or do an actual reg read. That way each routine | ||
150 | * can report back whatever fault may have occured. | ||
151 | */ | 148 | */ |
152 | struct bq24190_dev_info { | 149 | struct bq24190_dev_info { |
153 | struct i2c_client *client; | 150 | struct i2c_client *client; |
@@ -159,9 +156,6 @@ struct bq24190_dev_info { | |||
159 | unsigned int gpio_int; | 156 | unsigned int gpio_int; |
160 | unsigned int irq; | 157 | unsigned int irq; |
161 | struct mutex f_reg_lock; | 158 | struct mutex f_reg_lock; |
162 | bool charger_health_valid; | ||
163 | bool battery_health_valid; | ||
164 | bool battery_status_valid; | ||
165 | u8 f_reg; | 159 | u8 f_reg; |
166 | u8 ss_reg; | 160 | u8 ss_reg; |
167 | u8 watchdog; | 161 | u8 watchdog; |
@@ -635,21 +629,11 @@ static int bq24190_charger_get_health(struct bq24190_dev_info *bdi, | |||
635 | union power_supply_propval *val) | 629 | union power_supply_propval *val) |
636 | { | 630 | { |
637 | u8 v; | 631 | u8 v; |
638 | int health, ret; | 632 | int health; |
639 | 633 | ||
640 | mutex_lock(&bdi->f_reg_lock); | 634 | mutex_lock(&bdi->f_reg_lock); |
641 | 635 | v = bdi->f_reg; | |
642 | if (bdi->charger_health_valid) { | 636 | mutex_unlock(&bdi->f_reg_lock); |
643 | v = bdi->f_reg; | ||
644 | bdi->charger_health_valid = false; | ||
645 | mutex_unlock(&bdi->f_reg_lock); | ||
646 | } else { | ||
647 | mutex_unlock(&bdi->f_reg_lock); | ||
648 | |||
649 | ret = bq24190_read(bdi, BQ24190_REG_F, &v); | ||
650 | if (ret < 0) | ||
651 | return ret; | ||
652 | } | ||
653 | 637 | ||
654 | if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { | 638 | if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { |
655 | /* | 639 | /* |
@@ -936,18 +920,8 @@ static int bq24190_battery_get_status(struct bq24190_dev_info *bdi, | |||
936 | int status, ret; | 920 | int status, ret; |
937 | 921 | ||
938 | mutex_lock(&bdi->f_reg_lock); | 922 | mutex_lock(&bdi->f_reg_lock); |
939 | 923 | chrg_fault = bdi->f_reg; | |
940 | if (bdi->battery_status_valid) { | 924 | mutex_unlock(&bdi->f_reg_lock); |
941 | chrg_fault = bdi->f_reg; | ||
942 | bdi->battery_status_valid = false; | ||
943 | mutex_unlock(&bdi->f_reg_lock); | ||
944 | } else { | ||
945 | mutex_unlock(&bdi->f_reg_lock); | ||
946 | |||
947 | ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault); | ||
948 | if (ret < 0) | ||
949 | return ret; | ||
950 | } | ||
951 | 925 | ||
952 | chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK; | 926 | chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK; |
953 | chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT; | 927 | chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT; |
@@ -995,21 +969,11 @@ static int bq24190_battery_get_health(struct bq24190_dev_info *bdi, | |||
995 | union power_supply_propval *val) | 969 | union power_supply_propval *val) |
996 | { | 970 | { |
997 | u8 v; | 971 | u8 v; |
998 | int health, ret; | 972 | int health; |
999 | 973 | ||
1000 | mutex_lock(&bdi->f_reg_lock); | 974 | mutex_lock(&bdi->f_reg_lock); |
1001 | 975 | v = bdi->f_reg; | |
1002 | if (bdi->battery_health_valid) { | 976 | mutex_unlock(&bdi->f_reg_lock); |
1003 | v = bdi->f_reg; | ||
1004 | bdi->battery_health_valid = false; | ||
1005 | mutex_unlock(&bdi->f_reg_lock); | ||
1006 | } else { | ||
1007 | mutex_unlock(&bdi->f_reg_lock); | ||
1008 | |||
1009 | ret = bq24190_read(bdi, BQ24190_REG_F, &v); | ||
1010 | if (ret < 0) | ||
1011 | return ret; | ||
1012 | } | ||
1013 | 977 | ||
1014 | if (v & BQ24190_REG_F_BAT_FAULT_MASK) { | 978 | if (v & BQ24190_REG_F_BAT_FAULT_MASK) { |
1015 | health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; | 979 | health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; |
@@ -1201,7 +1165,7 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) | |||
1201 | | BQ24190_REG_F_NTC_FAULT_MASK; | 1165 | | BQ24190_REG_F_NTC_FAULT_MASK; |
1202 | bool alert_charger = false, alert_battery = false; | 1166 | bool alert_charger = false, alert_battery = false; |
1203 | u8 ss_reg = 0, f_reg = 0; | 1167 | u8 ss_reg = 0, f_reg = 0; |
1204 | int ret; | 1168 | int i, ret; |
1205 | 1169 | ||
1206 | pm_runtime_get_sync(bdi->dev); | 1170 | pm_runtime_get_sync(bdi->dev); |
1207 | 1171 | ||
@@ -1231,33 +1195,35 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) | |||
1231 | alert_battery = true; | 1195 | alert_battery = true; |
1232 | if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) | 1196 | if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) |
1233 | alert_charger = true; | 1197 | alert_charger = true; |
1234 | |||
1235 | bdi->ss_reg = ss_reg; | 1198 | bdi->ss_reg = ss_reg; |
1236 | } | 1199 | } |
1237 | 1200 | ||
1238 | mutex_lock(&bdi->f_reg_lock); | 1201 | i = 0; |
1239 | 1202 | do { | |
1240 | ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg); | 1203 | ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg); |
1241 | if (ret < 0) { | 1204 | if (ret < 0) { |
1242 | mutex_unlock(&bdi->f_reg_lock); | 1205 | dev_err(bdi->dev, "Can't read F reg: %d\n", ret); |
1243 | dev_err(bdi->dev, "Can't read F reg: %d\n", ret); | 1206 | goto out; |
1244 | goto out; | 1207 | } |
1245 | } | 1208 | } while (f_reg && ++i < 2); |
1246 | 1209 | ||
1247 | if (f_reg != bdi->f_reg) { | 1210 | if (f_reg != bdi->f_reg) { |
1211 | dev_info(bdi->dev, | ||
1212 | "Fault: boost %d, charge %d, battery %d, ntc %d\n", | ||
1213 | !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK), | ||
1214 | !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK), | ||
1215 | !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK), | ||
1216 | !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK)); | ||
1217 | |||
1218 | mutex_lock(&bdi->f_reg_lock); | ||
1248 | if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f)) | 1219 | if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f)) |
1249 | alert_battery = true; | 1220 | alert_battery = true; |
1250 | if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f)) | 1221 | if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f)) |
1251 | alert_charger = true; | 1222 | alert_charger = true; |
1252 | |||
1253 | bdi->f_reg = f_reg; | 1223 | bdi->f_reg = f_reg; |
1254 | bdi->charger_health_valid = true; | 1224 | mutex_unlock(&bdi->f_reg_lock); |
1255 | bdi->battery_health_valid = true; | ||
1256 | bdi->battery_status_valid = true; | ||
1257 | } | 1225 | } |
1258 | 1226 | ||
1259 | mutex_unlock(&bdi->f_reg_lock); | ||
1260 | |||
1261 | if (alert_charger) | 1227 | if (alert_charger) |
1262 | power_supply_changed(bdi->charger); | 1228 | power_supply_changed(bdi->charger); |
1263 | if (alert_battery) | 1229 | if (alert_battery) |
@@ -1377,9 +1343,6 @@ static int bq24190_probe(struct i2c_client *client, | |||
1377 | mutex_init(&bdi->f_reg_lock); | 1343 | mutex_init(&bdi->f_reg_lock); |
1378 | bdi->f_reg = 0; | 1344 | bdi->f_reg = 0; |
1379 | bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ | 1345 | bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ |
1380 | bdi->charger_health_valid = false; | ||
1381 | bdi->battery_health_valid = false; | ||
1382 | bdi->battery_status_valid = false; | ||
1383 | 1346 | ||
1384 | i2c_set_clientdata(client, bdi); | 1347 | i2c_set_clientdata(client, bdi); |
1385 | 1348 | ||
@@ -1492,9 +1455,6 @@ static int bq24190_pm_resume(struct device *dev) | |||
1492 | 1455 | ||
1493 | bdi->f_reg = 0; | 1456 | bdi->f_reg = 0; |
1494 | bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ | 1457 | bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ |
1495 | bdi->charger_health_valid = false; | ||
1496 | bdi->battery_health_valid = false; | ||
1497 | bdi->battery_status_valid = false; | ||
1498 | 1458 | ||
1499 | pm_runtime_get_sync(bdi->dev); | 1459 | pm_runtime_get_sync(bdi->dev); |
1500 | bq24190_register_reset(bdi); | 1460 | bq24190_register_reset(bdi); |