From patchwork Sun Apr 30 18:27:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 9706169 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 BBC99603F5 for ; Sun, 30 Apr 2017 18:29:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B127B262FF for ; Sun, 30 Apr 2017 18:29:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A626B26419; Sun, 30 Apr 2017 18:29:44 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 49C7E26490 for ; Sun, 30 Apr 2017 18:29:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S969951AbdD3S3K (ORCPT ); Sun, 30 Apr 2017 14:29:10 -0400 Received: from gagarine.paulk.fr ([109.190.93.129]:53522 "EHLO gagarine.paulk.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1162712AbdD3S3D (ORCPT ); Sun, 30 Apr 2017 14:29:03 -0400 Received: by gagarine.paulk.fr (Postfix, from userid 65534) id 60B49204E6; Sun, 30 Apr 2017 20:29:01 +0200 (CEST) Received: from localhost.localdomain (collins [192.168.1.129]) by gagarine.paulk.fr (Postfix) with ESMTP id CEF08207F0; Sun, 30 Apr 2017 20:28:32 +0200 (CEST) From: Paul Kocialkowski To: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Pali=20Roh=C3=A1r?= , "Andrew F . Davis" , Sebastian Reichel , Chris Lapa , Matt Ranostay , Paul Kocialkowski Subject: [PATCH 4/5] power: supply: bq27xxx: Look for status change on external power change Date: Sun, 30 Apr 2017 20:27:26 +0200 Message-Id: <20170430182727.24412-4-contact@paulk.fr> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20170430182727.24412-1-contact@paulk.fr> References: <20170430182727.24412-1-contact@paulk.fr> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This introduces a dedicated status change work to look for power status change. It is triggered by external power change notifications and periodically retries detecting a power status change for 5 seconds. This is largely inspired by a similar mechanism from the sbs-battery driver. Signed-off-by: Paul Kocialkowski --- drivers/power/supply/bq27xxx_battery.c | 38 ++++++++++++++++++++++++++++++++-- include/linux/power/bq27xxx_battery.h | 3 +++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 926bd58344d9..cade00df6162 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1190,6 +1190,11 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, status = POWER_SUPPLY_STATUS_CHARGING; } + if (di->status_retry == 0 && di->status_change_reference != status) { + di->status_change_reference = status; + power_supply_changed(di->bat); + } + val->intval = status; return 0; @@ -1340,12 +1345,38 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, return ret; } +static void bq27xxx_status_change(struct work_struct *work) +{ + struct bq27xxx_device_info *di = + container_of(work, struct bq27xxx_device_info, + status_work.work); + union power_supply_propval val; + int ret; + + bq27xxx_battery_update(di); + + ret = bq27xxx_battery_status(di, &val); + if (ret < 0) + return; + + if (di->status_change_reference != val.intval) { + di->status_change_reference = val.intval; + power_supply_changed(di->bat); + } + + if (di->status_retry > 0) { + di->status_retry--; + schedule_delayed_work(&di->status_work, HZ); + } +} + static void bq27xxx_external_power_changed(struct power_supply *psy) { struct bq27xxx_device_info *di = power_supply_get_drvdata(psy); - cancel_delayed_work_sync(&di->poll_work); - schedule_delayed_work(&di->poll_work, 0); + cancel_delayed_work_sync(&di->status_work); + schedule_delayed_work(&di->status_work, HZ); + di->status_retry = 5; } int bq27xxx_battery_setup(struct bq27xxx_device_info *di) @@ -1357,8 +1388,10 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di) psy_cfg.of_node = di->of_node; INIT_DELAYED_WORK(&di->poll_work, bq27xxx_battery_poll); + INIT_DELAYED_WORK(&di->status_work, bq27xxx_status_change); mutex_init(&di->lock); di->regs = bq27xxx_regs[di->chip]; + di->status_change_reference = POWER_SUPPLY_STATUS_UNKNOWN; psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL); if (!psy_desc) @@ -1400,6 +1433,7 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di) poll_interval = 0; cancel_delayed_work_sync(&di->poll_work); + cancel_delayed_work_sync(&di->status_work); power_supply_unregister(di->bat); diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index 0a9af513165a..16d604681ace 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -67,6 +67,9 @@ struct bq27xxx_device_info { int charge_design_full; unsigned long last_update; struct delayed_work poll_work; + struct delayed_work status_work; + int status_retry; + int status_change_reference; struct power_supply *bat; struct list_head list; struct mutex lock;