aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/supply/bq24190_charger.c94
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 */
152struct bq24190_dev_info { 149struct 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);