From d5deb78db6db4a4a84e946ba955ca9b08949adaa Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 25 Mar 2013 00:09:49 +0800 Subject: mfd: hi6421: avoid to call irq handler with lock While hi6421 SoC interrupt occurs, it always locks spinlock even calling child irq handler. If child irq handler accesses pmic registers, it will be dead lock since accessing function also uses spinlock. Signed-off-by: Haojian Zhuang --- drivers/mfd/hi6421-pmic-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c index 043956076be..cce368b856d 100644 --- a/drivers/mfd/hi6421-pmic-core.c +++ b/drivers/mfd/hi6421-pmic-core.c @@ -115,21 +115,25 @@ static irqreturn_t hi6421_irq_handler(int irq, void *data) unsigned long pending; int i, offset; - spin_lock(&pmic->lock); for (i = HI6421_REG_IRQ1; i <= HI6421_REG_IRQ3; i++) { + spin_lock(&pmic->lock); pending = readl_relaxed(pmic->regs + (i << 2)); pending &= HI6421_MASK_FIELD; writel_relaxed(pending, pmic->regs + ((i + 3) << 2)); + spin_unlock(&pmic->lock); + if (pending) { for_each_set_bit(offset, &pending, HI6421_BITS) generic_handle_irq(hi6421_to_irq(pmic, offset)); } + + spin_lock(&pmic->lock); writel_relaxed(0, pmic->regs + ((i + 3) << 2)); writel_relaxed(pending, pmic->regs + (i << 2)); + spin_unlock(&pmic->lock); } - spin_unlock(&pmic->lock); return IRQ_HANDLED; } -- cgit v1.2.3