diff options
author | Jonathan Cameron <jic23@cam.ac.uk> | 2009-01-19 13:20:58 -0500 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2009-03-31 04:56:20 -0400 |
commit | b136fb4463d13eea129bf090a8a465bba6bf0003 (patch) | |
tree | 48de26101e37833a79f6b3d62f4526dcca8f91fe | |
parent | 9485397aa2195e82da6373586a66689526675ad4 (diff) |
Regulator: Push lock out of _notifier_call_chain + add voltage change event.
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>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r-- | drivers/regulator/core.c | 15 | ||||
-rw-r--r-- | drivers/regulator/wm8350-regulator.c | 2 | ||||
-rw-r--r-- | include/linux/regulator/consumer.h | 2 |
3 files changed, 14 insertions, 5 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0ff95c3ccf5b..96c877dd9daf 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -1284,6 +1284,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
1284 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV); | 1284 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV); |
1285 | 1285 | ||
1286 | out: | 1286 | out: |
1287 | _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL); | ||
1287 | mutex_unlock(&rdev->mutex); | 1288 | mutex_unlock(&rdev->mutex); |
1288 | return ret; | 1289 | return ret; |
1289 | } | 1290 | } |
@@ -1584,20 +1585,23 @@ int regulator_unregister_notifier(struct regulator *regulator, | |||
1584 | } | 1585 | } |
1585 | EXPORT_SYMBOL_GPL(regulator_unregister_notifier); | 1586 | EXPORT_SYMBOL_GPL(regulator_unregister_notifier); |
1586 | 1587 | ||
1587 | /* notify regulator consumers and downstream regulator consumers */ | 1588 | /* notify regulator consumers and downstream regulator consumers. |
1589 | * Note mutex must be held by caller. | ||
1590 | */ | ||
1588 | static void _notifier_call_chain(struct regulator_dev *rdev, | 1591 | static void _notifier_call_chain(struct regulator_dev *rdev, |
1589 | unsigned long event, void *data) | 1592 | unsigned long event, void *data) |
1590 | { | 1593 | { |
1591 | struct regulator_dev *_rdev; | 1594 | struct regulator_dev *_rdev; |
1592 | 1595 | ||
1593 | /* call rdev chain first */ | 1596 | /* call rdev chain first */ |
1594 | mutex_lock(&rdev->mutex); | ||
1595 | blocking_notifier_call_chain(&rdev->notifier, event, NULL); | 1597 | blocking_notifier_call_chain(&rdev->notifier, event, NULL); |
1596 | mutex_unlock(&rdev->mutex); | ||
1597 | 1598 | ||
1598 | /* now notify regulator we supply */ | 1599 | /* now notify regulator we supply */ |
1599 | list_for_each_entry(_rdev, &rdev->supply_list, slist) | 1600 | list_for_each_entry(_rdev, &rdev->supply_list, slist) { |
1600 | _notifier_call_chain(_rdev, event, data); | 1601 | mutex_lock(&_rdev->mutex); |
1602 | _notifier_call_chain(_rdev, event, data); | ||
1603 | mutex_unlock(&_rdev->mutex); | ||
1604 | } | ||
1601 | } | 1605 | } |
1602 | 1606 | ||
1603 | /** | 1607 | /** |
@@ -1744,6 +1748,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); | |||
1744 | * | 1748 | * |
1745 | * Called by regulator drivers to notify clients a regulator event has | 1749 | * Called by regulator drivers to notify clients a regulator event has |
1746 | * occurred. We also notify regulator clients downstream. | 1750 | * occurred. We also notify regulator clients downstream. |
1751 | * Note lock must be held by caller. | ||
1747 | */ | 1752 | */ |
1748 | int regulator_notifier_call_chain(struct regulator_dev *rdev, | 1753 | int regulator_notifier_call_chain(struct regulator_dev *rdev, |
1749 | unsigned long event, void *data) | 1754 | unsigned long event, void *data) |
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 5056e23e4414..afad611fbb80 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) | |||
1293 | { | 1293 | { |
1294 | struct regulator_dev *rdev = (struct regulator_dev *)data; | 1294 | struct regulator_dev *rdev = (struct regulator_dev *)data; |
1295 | 1295 | ||
1296 | mutex_lock(&rdev->mutex); | ||
1296 | if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2) | 1297 | if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2) |
1297 | regulator_notifier_call_chain(rdev, | 1298 | regulator_notifier_call_chain(rdev, |
1298 | REGULATOR_EVENT_REGULATION_OUT, | 1299 | REGULATOR_EVENT_REGULATION_OUT, |
@@ -1301,6 +1302,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data) | |||
1301 | regulator_notifier_call_chain(rdev, | 1302 | regulator_notifier_call_chain(rdev, |
1302 | REGULATOR_EVENT_UNDER_VOLTAGE, | 1303 | REGULATOR_EVENT_UNDER_VOLTAGE, |
1303 | wm8350); | 1304 | wm8350); |
1305 | mutex_unlock(&rdev->mutex); | ||
1304 | } | 1306 | } |
1305 | 1307 | ||
1306 | static int wm8350_regulator_probe(struct platform_device *pdev) | 1308 | static int wm8350_regulator_probe(struct platform_device *pdev) |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 801bf77ff4e2..533f4e26db96 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
@@ -88,6 +88,7 @@ | |||
88 | * FAIL Regulator output has failed. | 88 | * FAIL Regulator output has failed. |
89 | * OVER_TEMP Regulator over temp. | 89 | * OVER_TEMP Regulator over temp. |
90 | * FORCE_DISABLE Regulator shut down by software. | 90 | * FORCE_DISABLE Regulator shut down by software. |
91 | * VOLTAGE_CHANGE Regulator voltage changed. | ||
91 | * | 92 | * |
92 | * NOTE: These events can be OR'ed together when passed into handler. | 93 | * NOTE: These events can be OR'ed together when passed into handler. |
93 | */ | 94 | */ |
@@ -98,6 +99,7 @@ | |||
98 | #define REGULATOR_EVENT_FAIL 0x08 | 99 | #define REGULATOR_EVENT_FAIL 0x08 |
99 | #define REGULATOR_EVENT_OVER_TEMP 0x10 | 100 | #define REGULATOR_EVENT_OVER_TEMP 0x10 |
100 | #define REGULATOR_EVENT_FORCE_DISABLE 0x20 | 101 | #define REGULATOR_EVENT_FORCE_DISABLE 0x20 |
102 | #define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40 | ||
101 | 103 | ||
102 | struct regulator; | 104 | struct regulator; |
103 | 105 | ||