From: "Michał Mirosław" <mirq-linux@rere.qmqm.pl>
To: Rob Herring <robh+dt@kernel.org>, Sebastian Reichel <sre@kernel.org>
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-pm@vger.kernel.org
Subject: [PATCH v2 04/11] power: bq25890: protect view of the chip's state
Date: Sun, 03 May 2020 17:21:11 +0200 [thread overview]
Message-ID: <3291ca81bf8eb1b0401579ae08e7835e71dfc1ff.1588517058.git.mirq-linux@rere.qmqm.pl> (raw)
In-Reply-To: <cover.1588517058.git.mirq-linux@rere.qmqm.pl>
Extend bq->lock over whole updating of the chip's state. Might get
useful later for switching ADC modes correctly.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/power/supply/bq25890_charger.c | 82 ++++++++------------------
1 file changed, 26 insertions(+), 56 deletions(-)
diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
index c4a69fd69f34..9339e216651f 100644
--- a/drivers/power/supply/bq25890_charger.c
+++ b/drivers/power/supply/bq25890_charger.c
@@ -510,74 +510,50 @@ static int bq25890_get_chip_state(struct bq25890_device *bq,
return 0;
}
-static bool bq25890_state_changed(struct bq25890_device *bq,
- struct bq25890_state *new_state)
-{
- struct bq25890_state old_state;
-
- mutex_lock(&bq->lock);
- old_state = bq->state;
- mutex_unlock(&bq->lock);
-
- return (old_state.chrg_status != new_state->chrg_status ||
- old_state.chrg_fault != new_state->chrg_fault ||
- old_state.online != new_state->online ||
- old_state.bat_fault != new_state->bat_fault ||
- old_state.boost_fault != new_state->boost_fault ||
- old_state.vsys_status != new_state->vsys_status);
-}
-
-static void bq25890_handle_state_change(struct bq25890_device *bq,
- struct bq25890_state *new_state)
+static irqreturn_t __bq25890_handle_irq(struct bq25890_device *bq)
{
+ struct bq25890_state new_state;
int ret;
- struct bq25890_state old_state;
- mutex_lock(&bq->lock);
- old_state = bq->state;
- mutex_unlock(&bq->lock);
+ ret = bq25890_get_chip_state(bq, &new_state);
+ if (ret < 0)
+ return IRQ_NONE;
- if (!new_state->online) { /* power removed */
+ if (!memcmp(&bq->state, &new_state, sizeof(new_state)))
+ return IRQ_NONE;
+
+ if (!new_state.online && bq->state.online) { /* power removed */
/* disable ADC */
ret = bq25890_field_write(bq, F_CONV_START, 0);
if (ret < 0)
goto error;
- } else if (!old_state.online) { /* power inserted */
+ } else if (new_state.online && !bq->state.online) { /* power inserted */
/* enable ADC, to have control of charge current/voltage */
ret = bq25890_field_write(bq, F_CONV_START, 1);
if (ret < 0)
goto error;
}
- return;
+ bq->state = new_state;
+ power_supply_changed(bq->charger);
+ return IRQ_HANDLED;
error:
- dev_err(bq->dev, "Error communicating with the chip.\n");
+ dev_err(bq->dev, "Error communicating with the chip: %pe\n",
+ ERR_PTR(ret));
+ return IRQ_HANDLED;
}
static irqreturn_t bq25890_irq_handler_thread(int irq, void *private)
{
struct bq25890_device *bq = private;
- int ret;
- struct bq25890_state state;
-
- ret = bq25890_get_chip_state(bq, &state);
- if (ret < 0)
- goto handled;
-
- if (!bq25890_state_changed(bq, &state))
- goto handled;
-
- bq25890_handle_state_change(bq, &state);
+ irqreturn_t ret;
mutex_lock(&bq->lock);
- bq->state = state;
+ ret = __bq25890_handle_irq(bq);
mutex_unlock(&bq->lock);
- power_supply_changed(bq->charger);
-
-handled:
- return IRQ_HANDLED;
+ return ret;
}
static int bq25890_chip_reset(struct bq25890_device *bq)
@@ -607,7 +583,6 @@ static int bq25890_hw_init(struct bq25890_device *bq)
{
int ret;
int i;
- struct bq25890_state state;
const struct {
enum bq25890_fields id;
@@ -655,16 +630,12 @@ static int bq25890_hw_init(struct bq25890_device *bq)
return ret;
}
- ret = bq25890_get_chip_state(bq, &state);
+ ret = bq25890_get_chip_state(bq, &bq->state);
if (ret < 0) {
dev_dbg(bq->dev, "Get state failed %d\n", ret);
return ret;
}
- mutex_lock(&bq->lock);
- bq->state = state;
- mutex_unlock(&bq->lock);
-
return 0;
}
@@ -1001,19 +972,16 @@ static int bq25890_suspend(struct device *dev)
static int bq25890_resume(struct device *dev)
{
int ret;
- struct bq25890_state state;
struct bq25890_device *bq = dev_get_drvdata(dev);
- ret = bq25890_get_chip_state(bq, &state);
+ mutex_lock(&bq->lock);
+
+ ret = bq25890_get_chip_state(bq, &bq->state);
if (ret < 0)
return ret;
- mutex_lock(&bq->lock);
- bq->state = state;
- mutex_unlock(&bq->lock);
-
/* Re-enable ADC only if charger is plugged in. */
- if (state.online) {
+ if (bq->state.online) {
ret = bq25890_field_write(bq, F_CONV_START, 1);
if (ret < 0)
return ret;
@@ -1022,6 +990,8 @@ static int bq25890_resume(struct device *dev)
/* signal userspace, maybe state changed while suspended */
power_supply_changed(bq->charger);
+ mutex_unlock(&bq->lock);
+
return 0;
}
#endif
--
2.20.1
next prev parent reply other threads:[~2020-05-03 15:21 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-03 15:21 [PATCH v2 00/11] power: supply: bq25890: fix and extend Michał Mirosław
2020-05-03 15:21 ` [PATCH v2 03/11] power: bq25890: make property table const Michał Mirosław
2020-05-03 19:55 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 01/11] power: bq25890: remove redundant I2C bus check Michał Mirosław
2020-05-03 19:56 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 02/11] power: bq25890: simplify chip name property getter Michał Mirosław
2020-05-03 19:55 ` Sebastian Reichel
2020-05-03 15:21 ` Michał Mirosław [this message]
2020-05-03 21:10 ` [PATCH v2 04/11] power: bq25890: protect view of the chip's state Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 05/11] power: bq25890: fix ADC mode configuration Michał Mirosław
2020-05-03 20:01 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 07/11] power: bq25890: implement CHARGE_TYPE property Michał Mirosław
2020-05-03 21:14 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 06/11] power: bq25890: update state on property read Michał Mirosław
2020-05-03 21:14 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 09/11] power: bq25890: implement INPUT_CURRENT_LIMIT property Michał Mirosław
2020-05-03 21:16 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 08/11] power: bq25890: implement PRECHARGE_CURRENT property Michał Mirosław
2020-05-03 21:15 ` Sebastian Reichel
2020-05-03 15:21 ` [PATCH v2 10/11] power: bq25890: support IBAT compensation Michał Mirosław
2020-05-03 15:21 ` [PATCH v2 11/11] power: bq25890: document IBAT compensation DT properties Michał Mirosław
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3291ca81bf8eb1b0401579ae08e7835e71dfc1ff.1588517058.git.mirq-linux@rere.qmqm.pl \
--to=mirq-linux@rere.qmqm.pl \
--cc=devicetree@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=robh+dt@kernel.org \
--cc=sre@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).