pinctrl: msm: Silence recursive lockdep warning
authorStephen Boyd <sboyd@codeaurora.org>
Fri, 7 Mar 2014 06:44:40 +0000 (22:44 -0800)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 12 Mar 2014 14:12:19 +0000 (15:12 +0100)
If a driver calls enable_irq_wake() on a gpio turned interrupt
from the msm pinctrl driver we'll get a lockdep warning like so:

=============================================
[ INFO: possible recursive locking detected ]
3.14.0-rc3 #2 Not tainted
---------------------------------------------
modprobe/52 is trying to acquire lock:
 (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88

but task is already holding lock:
 (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&irq_desc_lock_class);
  lock(&irq_desc_lock_class);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

4 locks held by modprobe/52:
 #0:  (&__lockdep_no_validate__){......}, at: [<c04f2864>] __driver_attach+0x48/0x98
 #1:  (&__lockdep_no_validate__){......}, at: [<c04f2874>] __driver_attach+0x58/0x98
 #2:  (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
 #3:  (&(&pctrl->lock)->rlock){......}, at: [<c04bb4b8>] msm_gpio_irq_set_wake+0x20/0xa8

Silence it by putting the gpios into their own lock class.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/pinctrl-msm.c

index 9b6b3a79a80949bfe7d971373ecacf55e62b07cd..2df3a48974f3feeb47b15bcb9327d0478408dd78 100644 (file)
@@ -884,6 +884,12 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        chained_irq_exit(chip, desc);
 }
 
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
 static int msm_gpio_init(struct msm_pinctrl *pctrl)
 {
        struct gpio_chip *chip;
@@ -922,6 +928,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
 
        for (i = 0; i < chip->ngpio; i++) {
                irq = irq_create_mapping(pctrl->domain, i);
+               irq_set_lockdep_class(irq, &gpio_lock_class);
                irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
                irq_set_chip_data(irq, pctrl);
        }