From patchwork Tue Oct 25 11:27:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Machek X-Patchwork-Id: 9394365 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1952960762 for ; Tue, 25 Oct 2016 11:29:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A90C2952F for ; Tue, 25 Oct 2016 11:29:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F303129531; Tue, 25 Oct 2016 11:29:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6A9772952F for ; Tue, 25 Oct 2016 11:29:57 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1byzu6-0001Zt-89; Tue, 25 Oct 2016 11:28:26 +0000 Received: from atrey.karlin.mff.cuni.cz ([195.113.26.193]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1byzu0-0001Yr-Pr for linux-arm-kernel@lists.infradead.org; Tue, 25 Oct 2016 11:28:22 +0000 Received: by atrey.karlin.mff.cuni.cz (Postfix, from userid 512) id 880EA823AD; Tue, 25 Oct 2016 13:27:58 +0200 (CEST) Date: Tue, 25 Oct 2016 13:27:57 +0200 From: Pavel Machek To: Tony Lindgren Subject: Re: [RFC] shutdown machine when li-ion battery goes below 3V Message-ID: <20161025112757.GC25855@amd> References: <20161024212250.GA31336@amd> <20161024212932.uhjz752z2cy5hohl@atomide.com> MIME-Version: 1.0 In-Reply-To: <20161024212932.uhjz752z2cy5hohl@atomide.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161025_042821_218288_87EBD473 X-CRM114-Status: GOOD ( 20.25 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ivo.g.dimitrov.75@gmail.com, khilman@kernel.org, aaro.koskinen@iki.fi, kernel list , sre@kernel.org, abcloriens@gmail.com, pali.rohar@gmail.com, linux-omap@vger.kernel.org, patrikbachan@gmail.com, linux-arm-kernel , serge@hallyn.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP On Mon 2016-10-24 14:29:33, Tony Lindgren wrote: > * Pavel Machek [161024 14:24]: > > Hi! > > > > What about something like this? N900 will drain the battery down to > > system crash, which is quite uncool. > > Can't we make that generic and configurable for the voltage somehow? > > Also, the shutdown voltage can depend on external devices connected. > It could be for example 3.3V depending on eMMC on some devices while > devices with no eMMC could have it at 3.0V. Actually, do we need to make it configurable? It looks like we should respect hardware telling us battery is dead, and only use (low) hardcoded voltages as a fallback. Currently patch looks like this. generic_protect() should work for other batteries drivers, too. Pavel diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 0fe278b..04094ad 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -679,10 +680,10 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di) /* Unlikely but important to return first */ if (unlikely(bq27xxx_battery_overtemp(di, flags))) return POWER_SUPPLY_HEALTH_OVERHEAT; - if (unlikely(bq27xxx_battery_undertemp(di, flags))) - return POWER_SUPPLY_HEALTH_COLD; if (unlikely(bq27xxx_battery_dead(di, flags))) return POWER_SUPPLY_HEALTH_DEAD; + if (unlikely(bq27xxx_battery_undertemp(di, flags))) + return POWER_SUPPLY_HEALTH_COLD; return POWER_SUPPLY_HEALTH_GOOD; } @@ -740,6 +741,49 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di) } EXPORT_SYMBOL_GPL(bq27xxx_battery_update); +static void shutdown(char *reason) +{ + pr_alert("%s Forcing shutdown\n", reason); + orderly_poweroff(true); +} + +static int generic_protect(struct power_supply *psy) +{ + union power_supply_propval val; + int res; + int mV, mA, mOhm = 430, mVadj = 0; + + res = psy->desc->get_property(psy, POWER_SUPPLY_PROP_HEALTH, &val); + if (res) + return res; + + if (val.intval == POWER_SUPPLY_HEALTH_OVERHEAT) + shutdown("Battery overheat."); + if (val.intval == POWER_SUPPLY_HEALTH_DEAD) + shutdown("Battery dead."); + + res = psy->desc->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); + if (res) + return res; + mV = val.intval / 1000; + + if (mV < 2950) + shutdown("Battery below 2.95V."); + + res = psy->desc->get_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &val); + if (res) + return res; + mA = val.intval / 1000; + mVadj = mV + (mA * mOhm) / 1000; + + if (mVadj < 3150) + shutdown("Battery internal voltage below 3.15."); + + printk(KERN_INFO "Main battery %d mV, internal voltage %d mV\n", + mV, mVadj); + return 0; +} + static void bq27xxx_battery_poll(struct work_struct *work) { struct bq27xxx_device_info *di = @@ -747,6 +791,7 @@ static void bq27xxx_battery_poll(struct work_struct *work) work.work); bq27xxx_battery_update(di); + generic_protect(di->bat); if (poll_interval > 0) schedule_delayed_work(&di->work, poll_interval * HZ);