aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Breck <liam@networkimprov.net>2017-01-18 12:26:52 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-14 08:00:14 -0400
commit4b7dac0a23b7c416b30962362268e8e55da9eaff (patch)
treec786f8eb84239aee67b92567107932a873624601
parent63e1acc84d28d73107e72482e33dcca152bb5ea4 (diff)
power: supply: bq24190_charger: Call power_supply_changed() for relevant component
commit 2d9fee6a42ea170e4378b3363a7ad385d0e67281 upstream. We wrongly get uevents for bq24190-charger and bq24190-battery on every register change. Fix by checking the association with charger and battery before emitting uevent(s). Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") Signed-off-by: Liam Breck <kernel@networkimprov.net> Acked-by: Mark Greer <mgreer@animalcreek.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Sebastian Reichel <sre@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/power/supply/bq24190_charger.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
index d0afafd7b1cb..94d282286bfd 100644
--- a/drivers/power/supply/bq24190_charger.c
+++ b/drivers/power/supply/bq24190_charger.c
@@ -159,7 +159,6 @@ struct bq24190_dev_info {
159 unsigned int gpio_int; 159 unsigned int gpio_int;
160 unsigned int irq; 160 unsigned int irq;
161 struct mutex f_reg_lock; 161 struct mutex f_reg_lock;
162 bool first_time;
163 bool charger_health_valid; 162 bool charger_health_valid;
164 bool battery_health_valid; 163 bool battery_health_valid;
165 bool battery_status_valid; 164 bool battery_status_valid;
@@ -1197,7 +1196,10 @@ static const struct power_supply_desc bq24190_battery_desc = {
1197static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) 1196static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1198{ 1197{
1199 struct bq24190_dev_info *bdi = data; 1198 struct bq24190_dev_info *bdi = data;
1200 bool alert_userspace = false; 1199 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1200 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1201 | BQ24190_REG_F_NTC_FAULT_MASK;
1202 bool alert_charger = false, alert_battery = false;
1201 u8 ss_reg = 0, f_reg = 0; 1203 u8 ss_reg = 0, f_reg = 0;
1202 int ret; 1204 int ret;
1203 1205
@@ -1225,8 +1227,12 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1225 ret); 1227 ret);
1226 } 1228 }
1227 1229
1230 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1231 alert_battery = true;
1232 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1233 alert_charger = true;
1234
1228 bdi->ss_reg = ss_reg; 1235 bdi->ss_reg = ss_reg;
1229 alert_userspace = true;
1230 } 1236 }
1231 1237
1232 mutex_lock(&bdi->f_reg_lock); 1238 mutex_lock(&bdi->f_reg_lock);
@@ -1239,33 +1245,23 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1239 } 1245 }
1240 1246
1241 if (f_reg != bdi->f_reg) { 1247 if (f_reg != bdi->f_reg) {
1248 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1249 alert_battery = true;
1250 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1251 alert_charger = true;
1252
1242 bdi->f_reg = f_reg; 1253 bdi->f_reg = f_reg;
1243 bdi->charger_health_valid = true; 1254 bdi->charger_health_valid = true;
1244 bdi->battery_health_valid = true; 1255 bdi->battery_health_valid = true;
1245 bdi->battery_status_valid = true; 1256 bdi->battery_status_valid = true;
1246
1247 alert_userspace = true;
1248 } 1257 }
1249 1258
1250 mutex_unlock(&bdi->f_reg_lock); 1259 mutex_unlock(&bdi->f_reg_lock);
1251 1260
1252 /* 1261 if (alert_charger)
1253 * Sometimes bq24190 gives a steady trickle of interrupts even 1262 power_supply_changed(bdi->charger);
1254 * though the watchdog timer is turned off and neither the STATUS 1263 if (alert_battery)
1255 * nor FAULT registers have changed. Weed out these sprurious 1264 power_supply_changed(bdi->battery);
1256 * interrupts so userspace isn't alerted for no reason.
1257 * In addition, the chip always generates an interrupt after
1258 * register reset so we should ignore that one (the very first
1259 * interrupt received).
1260 */
1261 if (alert_userspace) {
1262 if (!bdi->first_time) {
1263 power_supply_changed(bdi->charger);
1264 power_supply_changed(bdi->battery);
1265 } else {
1266 bdi->first_time = false;
1267 }
1268 }
1269 1265
1270out: 1266out:
1271 pm_runtime_put_sync(bdi->dev); 1267 pm_runtime_put_sync(bdi->dev);
@@ -1300,6 +1296,10 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1300 goto out; 1296 goto out;
1301 1297
1302 ret = bq24190_set_mode_host(bdi); 1298 ret = bq24190_set_mode_host(bdi);
1299 if (ret < 0)
1300 goto out;
1301
1302 ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1303out: 1303out:
1304 pm_runtime_put_sync(bdi->dev); 1304 pm_runtime_put_sync(bdi->dev);
1305 return ret; 1305 return ret;
@@ -1375,7 +1375,8 @@ static int bq24190_probe(struct i2c_client *client,
1375 bdi->model = id->driver_data; 1375 bdi->model = id->driver_data;
1376 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE); 1376 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1377 mutex_init(&bdi->f_reg_lock); 1377 mutex_init(&bdi->f_reg_lock);
1378 bdi->first_time = true; 1378 bdi->f_reg = 0;
1379 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1379 bdi->charger_health_valid = false; 1380 bdi->charger_health_valid = false;
1380 bdi->battery_health_valid = false; 1381 bdi->battery_health_valid = false;
1381 bdi->battery_status_valid = false; 1382 bdi->battery_status_valid = false;
@@ -1489,6 +1490,8 @@ static int bq24190_pm_resume(struct device *dev)
1489 struct i2c_client *client = to_i2c_client(dev); 1490 struct i2c_client *client = to_i2c_client(dev);
1490 struct bq24190_dev_info *bdi = i2c_get_clientdata(client); 1491 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1491 1492
1493 bdi->f_reg = 0;
1494 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1492 bdi->charger_health_valid = false; 1495 bdi->charger_health_valid = false;
1493 bdi->battery_health_valid = false; 1496 bdi->battery_health_valid = false;
1494 bdi->battery_status_valid = false; 1497 bdi->battery_status_valid = false;
@@ -1496,6 +1499,7 @@ static int bq24190_pm_resume(struct device *dev)
1496 pm_runtime_get_sync(bdi->dev); 1499 pm_runtime_get_sync(bdi->dev);
1497 bq24190_register_reset(bdi); 1500 bq24190_register_reset(bdi);
1498 bq24190_set_mode_host(bdi); 1501 bq24190_set_mode_host(bdi);
1502 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1499 pm_runtime_put_sync(bdi->dev); 1503 pm_runtime_put_sync(bdi->dev);
1500 1504
1501 /* Things may have changed while suspended so alert upper layer */ 1505 /* Things may have changed while suspended so alert upper layer */