diff options
author | Arnd Bergmann <arnd@arndb.de> | 2017-08-04 12:54:41 +0200 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2017-08-04 12:54:41 +0200 |
commit | 264e22afa3aee4017ef5be42c7d5069560334c44 (patch) | |
tree | 4222a7d89b66f6a730799382f006e84cfc307530 | |
parent | 48cb953e6d899f2b0fb38c8b69c260929107ad4c (diff) | |
parent | fce8dc5e50e44d8f644e0f7854e6d7d518fedb68 (diff) | |
download | lwn-264e22afa3aee4017ef5be42c7d5069560334c44.tar.gz lwn-264e22afa3aee4017ef5be42c7d5069560334c44.zip |
Merge tag 'renesas-fixes3-for-v4.13' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into fixes
Pull "Third Round of Renesas ARM Based SoC Fixes for v4.13" from Simon Horman:
Fix deadlock in regulator quirk for R-Car Gen 2 SoCs
The da9063/da9210 regulator quirk for R-Car Gen2 boards uses a bus
notifier, and unregisters the notifier when it is no longer needed.
However, a notifier must not be unregistered from within the call chain.
This bug went unnoticed, as blocking_notifier_chain_unregister() didn't
take the semaphore during early boot. This is no longer the case as of
upstream commit 1c3c5eab171590f8 ("sched/core: Enable might_sleep() and
smp_processor_id() checks early") and a deadlock occurs.
* tag 'renesas-fixes3-for-v4.13' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
ARM: shmobile: rcar-gen2: Fix deadlock in regulator quirk
-rw-r--r-- | arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 73e3adbc1330..44438f344dc8 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -67,8 +67,12 @@ static int regulator_quirk_notify(struct notifier_block *nb, { struct device *dev = data; struct i2c_client *client; + static bool done; u32 mon; + if (done) + return 0; + mon = ioread32(irqc + IRQC_MONITOR); dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon); if (mon & REGULATOR_IRQ_MASK) @@ -99,7 +103,7 @@ static int regulator_quirk_notify(struct notifier_block *nb, remove: dev_info(dev, "IRQ2 is not asserted, removing quirk\n"); - bus_unregister_notifier(&i2c_bus_type, nb); + done = true; iounmap(irqc); return 0; } |