Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b136fb44 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Liam Girdwood
Browse files

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: default avatarJonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent 9485397a
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -1284,6 +1284,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;
}
@@ -1584,20 +1585,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)
	list_for_each_entry(_rdev, &rdev->supply_list, slist) {
	  mutex_lock(&_rdev->mutex);
	  _notifier_call_chain(_rdev, event, data);
	  mutex_unlock(&_rdev->mutex);
	}
}

/**
@@ -1744,6 +1748,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)
+2 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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;