Skip to content

Commit f8702f9

Browse files
digetxbroonie
authored andcommittedNov 19, 2018
regulator: core: Use ww_mutex for regulators locking
Wait/wound mutex shall be used in order to avoid lockups on locking of coupled regulators. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Suggested-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 6303f3e commit f8702f9

File tree

5 files changed

+317
-104
lines changed

5 files changed

+317
-104
lines changed
 

‎drivers/regulator/core.c

+306-97
Large diffs are not rendered by default.

‎drivers/regulator/da9210-regulator.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
131131
if (error < 0)
132132
goto error_i2c;
133133

134-
mutex_lock(&chip->rdev->mutex);
134+
regulator_lock(chip->rdev);
135135

136136
if (val & DA9210_E_OVCURR) {
137137
regulator_notifier_call_chain(chip->rdev,
@@ -157,7 +157,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
157157
handled |= DA9210_E_VMAX;
158158
}
159159

160-
mutex_unlock(&chip->rdev->mutex);
160+
regulator_unlock(chip->rdev);
161161

162162
if (handled) {
163163
/* Clear handled events */

‎drivers/regulator/stpmic1_regulator.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -489,14 +489,14 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
489489
{
490490
struct regulator_dev *rdev = (struct regulator_dev *)data;
491491

492-
mutex_lock(&rdev->mutex);
492+
regulator_lock(rdev, NULL);
493493

494494
/* Send an overcurrent notification */
495495
regulator_notifier_call_chain(rdev,
496496
REGULATOR_EVENT_OVER_CURRENT,
497497
NULL);
498498

499-
mutex_unlock(&rdev->mutex);
499+
regulator_unlock(rdev);
500500

501501
return IRQ_HANDLED;
502502
}

‎drivers/regulator/wm8350-regulator.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
11531153
{
11541154
struct regulator_dev *rdev = (struct regulator_dev *)data;
11551155

1156-
mutex_lock(&rdev->mutex);
1156+
regulator_lock(rdev);
11571157
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
11581158
regulator_notifier_call_chain(rdev,
11591159
REGULATOR_EVENT_REGULATION_OUT,
@@ -1162,7 +1162,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
11621162
regulator_notifier_call_chain(rdev,
11631163
REGULATOR_EVENT_UNDER_VOLTAGE,
11641164
NULL);
1165-
mutex_unlock(&rdev->mutex);
1165+
regulator_unlock(rdev);
11661166

11671167
return IRQ_HANDLED;
11681168
}

‎include/linux/regulator/driver.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/device.h>
2121
#include <linux/notifier.h>
2222
#include <linux/regulator/consumer.h>
23+
#include <linux/ww_mutex.h>
2324

2425
struct gpio_desc;
2526
struct regmap;
@@ -462,7 +463,7 @@ struct regulator_dev {
462463
struct coupling_desc coupling_desc;
463464

464465
struct blocking_notifier_head notifier;
465-
struct mutex mutex; /* consumer lock */
466+
struct ww_mutex mutex; /* consumer lock */
466467
struct task_struct *mutex_owner;
467468
int ref_cnt;
468469
struct module *owner;
@@ -545,4 +546,7 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
545546
bool enable);
546547
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
547548

549+
void regulator_lock(struct regulator_dev *rdev);
550+
void regulator_unlock(struct regulator_dev *rdev);
551+
548552
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.