From: Jonathan Cameron <jic23@cam.ac.uk>
To: Jonathan Cameron <Jonathan.Cameron@gmail.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>,
Liam Girdwood <lrg@slimlogic.co.uk>,
LKML <linux-kernel@vger.kernel.org>
Subject: [RFC] Regulator: Push lock out of _notifier_call_chain + add voltage change event.
Date: Mon, 19 Jan 2009 18:20:58 +0000 [thread overview]
Message-ID: <4974C48A.1000103@cam.ac.uk> (raw)
In-Reply-To: <4974C182.1090902@cam.ac.uk>
From: Jonathan Cameron <jic23@cam.ac.uk>
Regulator: Push lock out of _notifier_call_chain and into caller functions
(side effect of fixing deadlock in regulator_force_disable)
+ Add a voltage changed event.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
Follow up to Mark Brown's suggestion of moving the regulator lock out
of the notifier code. This avoids cases where it was previously necessary
to unlock the regulator before notification occured.
Any scenarios where this will cause trouble?
I'll do a documentation patch when we've pinned down how to do this.
+ can break the patch into one for pushing the lock out and one for
adding the event.
drivers/regulator/core.c | 15 ++++++++++-----
drivers/regulator/wm8350-regulator.c | 2 ++
drivers/regulator/wm8400-regulator.c | 2 +-
include/linux/regulator/consumer.h | 2 ++
4 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f511a40..2a8a294 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1243,6 +1243,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
out:
+ _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1543,20 +1544,23 @@ int regulator_unregister_notifier(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
-/* notify regulator consumers and downstream regulator consumers */
+/* notify regulator consumers and downstream regulator consumers.
+ * Note mutex must be held by caller.
+ */
static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
struct regulator_dev *_rdev;
/* call rdev chain first */
- mutex_lock(&rdev->mutex);
blocking_notifier_call_chain(&rdev->notifier, event, NULL);
- mutex_unlock(&rdev->mutex);
/* now notify regulator we supply */
- list_for_each_entry(_rdev, &rdev->supply_list, slist)
- _notifier_call_chain(_rdev, event, data);
+ list_for_each_entry(_rdev, &rdev->supply_list, slist) {
+ mutex_lock(&_rdev->mutex);
+ _notifier_call_chain(_rdev, event, data);
+ mutex_unlock(&_rdev->mutex);
+ }
}
/**
@@ -1703,6 +1707,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
*
* Called by regulator drivers to notify clients a regulator event has
* occurred. We also notify regulator clients downstream.
+ * Note lock must be held by caller.
*/
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 7aa3524..c975664 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1293,6 +1293,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
+ mutex_lock(&rdev->mutex);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT,
@@ -1301,6 +1302,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE,
wm8350);
+ mutex_unlock(&rdev->mutex);
}
static int wm8350_regulator_probe(struct platform_device *pdev)
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 801bf77..6107a70 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -88,6 +88,7 @@
* FAIL Regulator output has failed.
* OVER_TEMP Regulator over temp.
* FORCE_DISABLE Regulator shut down by software.
+ * VOLTAGE_CHANGE Regulator voltage changed.
*
* NOTE: These events can be OR'ed together when passed into handler.
*/
@@ -98,6 +99,7 @@
#define REGULATOR_EVENT_FAIL 0x08
#define REGULATOR_EVENT_OVER_TEMP 0x10
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
+#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
struct regulator;
next prev parent reply other threads:[~2009-01-19 18:21 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-03 21:11 [RFC] Regulator: Possibility of passing notifications of non alarm events Jonathan Cameron
2009-01-04 10:31 ` Liam Girdwood
2009-01-18 18:47 ` [RFC] Regulator: Add a voltage changed event to notify consumers Jonathan Cameron
2009-01-19 15:29 ` Mark Brown
2009-01-19 16:57 ` Jonathan Cameron
2009-01-19 18:08 ` Jonathan Cameron
2009-01-19 18:20 ` Jonathan Cameron [this message]
2009-01-20 20:09 ` [RFC] Regulator: Push lock out of _notifier_call_chain + add voltage change event Liam Girdwood
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=4974C48A.1000103@cam.ac.uk \
--to=jic23@cam.ac.uk \
--cc=Jonathan.Cameron@gmail.com \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lrg@slimlogic.co.uk \
/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