Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752046AbdFAPot (ORCPT ); Thu, 1 Jun 2017 11:44:49 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:33251 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751852AbdFAPon (ORCPT ); Thu, 1 Jun 2017 11:44:43 -0400 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Sebastian Reichel" , "Liam Breck" , "Liam Breck" , "Mark Greer" , "Tony Lindgren" Date: Thu, 01 Jun 2017 16:43:15 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 062/212] power: supply: bq24190_charger: Call power_supply_changed() for relevant component In-Reply-To: X-SA-Exim-Connect-IP: 82.70.136.246 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4632 Lines: 142 3.16.44-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Liam Breck 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 Acked-by: Mark Greer Acked-by: Tony Lindgren Signed-off-by: Sebastian Reichel [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings --- drivers/power/bq24190_charger.c | 50 ++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 23 deletions(-) --- a/drivers/power/bq24190_charger.c +++ b/drivers/power/bq24190_charger.c @@ -159,7 +159,6 @@ struct bq24190_dev_info { unsigned int gpio_int; unsigned int irq; struct mutex f_reg_lock; - bool first_time; bool charger_health_valid; bool battery_health_valid; bool battery_status_valid; @@ -1207,7 +1206,10 @@ static void bq24190_battery_init(struct static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) { struct bq24190_dev_info *bdi = data; - bool alert_userspace = false; + const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK; + const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK + | BQ24190_REG_F_NTC_FAULT_MASK; + bool alert_charger = false, alert_battery = false; u8 ss_reg = 0, f_reg = 0; int ret; @@ -1235,8 +1237,12 @@ static irqreturn_t bq24190_irq_handler_t ret); } + if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss)) + alert_battery = true; + if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) + alert_charger = true; + bdi->ss_reg = ss_reg; - alert_userspace = true; } mutex_lock(&bdi->f_reg_lock); @@ -1249,33 +1255,23 @@ static irqreturn_t bq24190_irq_handler_t } if (f_reg != bdi->f_reg) { + 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; - - alert_userspace = true; } mutex_unlock(&bdi->f_reg_lock); - /* - * Sometimes bq24190 gives a steady trickle of interrupts even - * though the watchdog timer is turned off and neither the STATUS - * nor FAULT registers have changed. Weed out these sprurious - * interrupts so userspace isn't alerted for no reason. - * In addition, the chip always generates an interrupt after - * register reset so we should ignore that one (the very first - * interrupt received). - */ - if (alert_userspace) { - if (!bdi->first_time) { - power_supply_changed(&bdi->charger); - power_supply_changed(&bdi->battery); - } else { - bdi->first_time = false; - } - } + if (alert_charger) + power_supply_changed(&bdi->charger); + if (alert_battery) + power_supply_changed(&bdi->battery); out: pm_runtime_put_sync(bdi->dev); @@ -1310,6 +1306,10 @@ static int bq24190_hw_init(struct bq2419 goto out; ret = bq24190_set_mode_host(bdi); + if (ret < 0) + goto out; + + ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); out: pm_runtime_put_sync(bdi->dev); return ret; @@ -1384,7 +1384,8 @@ static int bq24190_probe(struct i2c_clie bdi->model = id->driver_data; strncpy(bdi->model_name, id->name, I2C_NAME_SIZE); mutex_init(&bdi->f_reg_lock); - bdi->first_time = true; + 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; @@ -1494,6 +1495,8 @@ static int bq24190_pm_resume(struct devi struct i2c_client *client = to_i2c_client(dev); struct bq24190_dev_info *bdi = i2c_get_clientdata(client); + 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; @@ -1501,6 +1504,7 @@ static int bq24190_pm_resume(struct devi pm_runtime_get_sync(bdi->dev); bq24190_register_reset(bdi); bq24190_set_mode_host(bdi); + bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); pm_runtime_put_sync(bdi->dev); /* Things may have changed while suspended so alert upper layer */