From 28f59b9d1f00cbac7d451588f708b908bd70a8dc Mon Sep 17 00:00:00 2001 From: Steve Twiss Date: Tue, 26 Feb 2019 15:32:18 +0000 Subject: regulator: lp8755: Fix notifier mutex lock warning [ Upstream commit 89b2758c192c35068b07766a6830433bfbdc1f44 ] The mutex for the regulator_dev must be controlled by the caller of the regulator_notifier_call_chain(), as described in the comment for that function. Failure to mutex lock and unlock surrounding the notifier call results in a kernel WARN_ON_ONCE() which will dump a backtrace for the regulator_notifier_call_chain() when that function call is first made. The mutex can be controlled using the regulator_lock/unlock() API. Fixes: b59320cc5a5e ("regulator: lp8755: new driver for LP8755") Suggested-by: Adam Thomson Signed-off-by: Steve Twiss Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/lp8755.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 14fd38807134..2e16a6ab491d 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -372,10 +372,13 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) if ((flag0 & (0x4 << icnt)) && (pchip->irqmask & (0x04 << icnt)) - && (pchip->rdev[icnt] != NULL)) + && (pchip->rdev[icnt] != NULL)) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_PWR_FAULT, NULL); + regulator_unlock(pchip->rdev[icnt]); + } /* read flag1 register */ ret = lp8755_read(pchip, 0x0E, &flag1); @@ -389,18 +392,24 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) /* send OCP event to all regulator devices */ if ((flag1 & 0x01) && (pchip->irqmask & 0x01)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - if (pchip->rdev[icnt] != NULL) + if (pchip->rdev[icnt] != NULL) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OCP, NULL); + regulator_unlock(pchip->rdev[icnt]); + } /* send OVP event to all regulator devices */ if ((flag1 & 0x02) && (pchip->irqmask & 0x02)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - if (pchip->rdev[icnt] != NULL) + if (pchip->rdev[icnt] != NULL) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OVP, NULL); + regulator_unlock(pchip->rdev[icnt]); + } return IRQ_HANDLED; err_i2c: -- cgit v1.2.3