linux/drivers/gpio
Marek Vasut 02188246b6 gpio: mxs: Allow for recursive enable_irq_wake() call
commit a585f87c86 upstream.

The scenario here is that someone calls enable_irq_wake() from somewhere
in the code. This will result in the lockdep producing a backtrace as can
be seen below. In my case, this problem is triggered when using the wl1271
(TI WlCore) driver found in drivers/net/wireless/ti/ .

The problem cause is rather obvious from the backtrace, but let's outline
the dependency. enable_irq_wake() grabs the IRQ buslock in irq_set_irq_wake(),
which in turns calls mxs_gpio_set_wake_irq() . But mxs_gpio_set_wake_irq()
calls enable_irq_wake() again on the one-level-higher IRQ , thus it tries to
grab the IRQ buslock again in irq_set_irq_wake() . Because the spinlock in
irq_set_irq_wake()->irq_get_desc_buslock()->__irq_get_desc_lock() is not
marked as recursive, lockdep will spew the stuff below.

We know we can safely re-enter the lock, so use IRQ_GC_INIT_NESTED_LOCK to
fix the spew.

 =============================================
 [ INFO: possible recursive locking detected ]
 3.10.33-00012-gf06b763-dirty #61 Not tainted
 ---------------------------------------------
 kworker/0:1/18 is trying to acquire lock:
  (&irq_desc_lock_class){-.-...}, at: [<c00685f0>] __irq_get_desc_lock+0x48/0x88

 but task is already holding lock:
  (&irq_desc_lock_class){-.-...}, at: [<c00685f0>] __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

 3 locks held by kworker/0:1/18:
  #0:  (events){.+.+.+}, at: [<c0036308>] process_one_work+0x134/0x4a4
  #1:  ((&fw_work->work)){+.+.+.}, at: [<c0036308>] process_one_work+0x134/0x4a4
  #2:  (&irq_desc_lock_class){-.-...}, at: [<c00685f0>] __irq_get_desc_lock+0x48/0x88

 stack backtrace:
 CPU: 0 PID: 18 Comm: kworker/0:1 Not tainted 3.10.33-00012-gf06b763-dirty #61
 Workqueue: events request_firmware_work_func
 [<c0013eb4>] (unwind_backtrace+0x0/0xf0) from [<c0011c74>] (show_stack+0x10/0x14)
 [<c0011c74>] (show_stack+0x10/0x14) from [<c005bb08>] (__lock_acquire+0x140c/0x1a64)
 [<c005bb08>] (__lock_acquire+0x140c/0x1a64) from [<c005c6a8>] (lock_acquire+0x9c/0x104)
 [<c005c6a8>] (lock_acquire+0x9c/0x104) from [<c051d5a4>] (_raw_spin_lock_irqsave+0x44/0x58)
 [<c051d5a4>] (_raw_spin_lock_irqsave+0x44/0x58) from [<c00685f0>] (__irq_get_desc_lock+0x48/0x88)
 [<c00685f0>] (__irq_get_desc_lock+0x48/0x88) from [<c0068e78>] (irq_set_irq_wake+0x20/0xf4)
 [<c0068e78>] (irq_set_irq_wake+0x20/0xf4) from [<c027260c>] (mxs_gpio_set_wake_irq+0x1c/0x24)
 [<c027260c>] (mxs_gpio_set_wake_irq+0x1c/0x24) from [<c0068cf4>] (set_irq_wake_real+0x30/0x44)
 [<c0068cf4>] (set_irq_wake_real+0x30/0x44) from [<c0068ee4>] (irq_set_irq_wake+0x8c/0xf4)
 [<c0068ee4>] (irq_set_irq_wake+0x8c/0xf4) from [<c0310748>] (wlcore_nvs_cb+0x10c/0x97c)
 [<c0310748>] (wlcore_nvs_cb+0x10c/0x97c) from [<c02be5e8>] (request_firmware_work_func+0x38/0x58)
 [<c02be5e8>] (request_firmware_work_func+0x38/0x58) from [<c0036394>] (process_one_work+0x1c0/0x4a4)
 [<c0036394>] (process_one_work+0x1c0/0x4a4) from [<c0036a4c>] (worker_thread+0x138/0x394)
 [<c0036a4c>] (worker_thread+0x138/0x394) from [<c003cb74>] (kthread+0xa4/0xb0)
 [<c003cb74>] (kthread+0xa4/0xb0) from [<c000ee00>] (ret_from_fork+0x14/0x34)
 wlcore: loaded

Signed-off-by: Marek Vasut <marex@denx.de>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-05-13 13:32:54 +02:00
..
devres.c gpiolib: devres: add missing headers 2013-10-29 18:26:14 -07:00
gpio-74x164.c gpio: 74x164: Driver cleanup 2013-12-12 14:28:12 +01:00
gpio-adnp.c Merge branch 'mark-irqs' into devel 2013-12-04 14:48:17 +01:00
gpio-adp5520.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-adp5588.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-amd8111.c gpio: remove DEFINE_PCI_DEVICE_TABLE macro 2013-12-03 13:16:09 +01:00
gpio-arizona.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-bcm-kona.c gpio: bcm281xx: Update MODULE_AUTHOR 2014-02-05 10:59:18 +01:00
gpio-bt8xx.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-clps711x.c gpio: clps711x: Add module alias to support module auto loading 2014-02-05 11:04:20 +01:00
gpio-cs5535.c
gpio-da9052.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-da9055.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-davinci.c gpio: davinci: don't create irq_domain in case of unbanked irqs 2013-12-26 00:02:12 +05:30
gpio-em.c Merge branch 'mark-irqs' into devel 2013-12-04 14:48:17 +01:00
gpio-ep93xx.c gpio: ep93xx: get rid of bogus __raw* accessors 2013-10-16 09:59:54 +02:00
gpio-f7188x.c gpio: f7188x: set can_sleep attribute 2014-01-07 19:02:01 +01:00
gpio-ge.c
gpio-generic.c
gpio-grgpio.c gpio: grgpio: Staticize local symbols 2013-06-19 21:40:38 +02:00
gpio-ich.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-intel-mid.c gpio: intel-mid: fix the incorrect return of idle callback 2014-02-05 10:37:06 +01:00
gpio-iop.c ARM: plat-iop: pass physical base for GPIO 2013-09-20 23:05:19 +02:00
gpio-it8761e.c
gpio-janz-ttl.c gpio: use dev_get_platdata() 2013-08-16 15:24:35 +02:00
gpio-kempld.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-ks8695.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-lp3943.c gpio: lp3943: Remove redundant of_match_ptr helper 2014-01-21 08:29:00 +00:00
gpio-lpc32xx.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-lynxpoint.c Merge branch 'mark-irqs' into devel 2013-12-04 14:48:17 +01:00
gpio-max730x.c gpio: max730x: Remove redundant dev_set_drvdata 2014-01-02 13:54:34 +01:00
gpio-max732x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-max7300.c
gpio-max7301.c gpio: max7301: Reverting "Do not force SPI speed when using OF Platform" 2013-08-23 19:44:28 +02:00
gpio-mc9s08dz60.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-mc33880.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-mcp23s08.c gpio: mcp23s08: fix casting caused build warning 2014-01-20 09:10:03 +01:00
gpio-ml-ioh.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-mm-lantiq.c
gpio-moxart.c gpio: moxart: remove redundant dev_err call in moxart_gpio_probe() 2013-12-20 10:22:19 +01:00
gpio-mpc8xxx.c powerpc/gpio: Fix the wrong GPIO input data on MPC8572/MPC8536 2013-12-03 13:10:48 +01:00
gpio-mpc5200.c
gpio-msic.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-msm-v1.c gpio_msm: Fix build error due to missing err.h 2013-07-31 00:34:31 +02:00
gpio-msm-v2.c GPIO tree bulk changes for v3.14 2014-01-21 10:09:12 -08:00
gpio-mvebu.c gpio: mvebu: Do not hard code error code 2014-01-02 13:57:10 +01:00
gpio-mxc.c gpio: mxc: Do not hard code return value 2014-01-02 13:55:53 +01:00
gpio-mxs.c gpio: mxs: Allow for recursive enable_irq_wake() call 2014-05-13 13:32:54 +02:00
gpio-octeon.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-omap.c gpio/omap: raw read and write endian fix 2013-11-25 09:03:39 +01:00
gpio-palmas.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-pca953x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-pcf857x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-pch.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-pl061.c gpio: pl061: move irqdomain initialization 2013-11-27 14:13:50 +01:00
gpio-pxa.c gpio: pxa: clamp gpio get value to [0,1] 2014-01-15 08:56:20 +01:00
gpio-rc5t583.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-rcar.c GPIO tree bulk changes for v3.14 2014-01-21 10:09:12 -08:00
gpio-rdc321x.c gpio: use dev_get_platdata() 2013-08-16 15:24:35 +02:00
gpio-sa1100.c ARM: 7841/1: sa1100: remove complex GPIO interface 2013-10-29 11:01:02 +00:00
gpio-samsung.c ARM: S5P[v210|c100|64x0]: Fix build error 2014-01-15 13:48:06 +01:00
gpio-sch311x.c gpio: sch311x: fix compilation error 2013-12-23 18:12:48 +01:00
gpio-sch.c
gpio-sodaville.c gpio: sodaville: fix some error return code on error path 2013-12-20 10:23:18 +01:00
gpio-spear-spics.c drivers/gpio: simplify use of devm_ioremap_resource 2013-08-16 17:16:31 +02:00
gpio-sta2x11.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-stmpe.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-stp-xway.c
gpio-sx150x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tb10x.c gpio: tb10x: Remove redundant of_match_ptr helper 2014-01-02 14:03:22 +01:00
gpio-tc3589x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tegra.c gpio: tegra: add missing error handling to probe 2013-12-11 13:37:48 +01:00
gpio-timberdale.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tnetv107x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tps6586x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tps65910.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tps65912.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-ts5500.c gpio: use dev_get_platdata() 2013-08-16 15:24:35 +02:00
gpio-twl4030.c GPIO tree bulk changes for v3.14 2014-01-21 10:09:12 -08:00
gpio-twl6040.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-tz1090-pdc.c gpio-tz1090-pdc: add TZ1090 PDC gpio driver 2013-07-20 19:03:48 +02:00
gpio-tz1090.c gpio-tz1090: convert to use generic irqchip 2013-07-20 19:05:15 +02:00
gpio-ucb1400.c Linux 3.13-rc3 2013-12-09 14:04:37 +01:00
gpio-viperboard.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-vr41xx.c
gpio-vx855.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-wm831x.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-wm8350.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-wm8994.c gpio/pinctrl: make gpio_chip members typed boolean 2013-12-04 14:42:46 +01:00
gpio-xilinx.c
gpio-xtensa.c gpio: xtensa: fix build when XCHAL_HAVE_CP is 0 2014-02-03 09:11:45 +01:00
gpiolib-acpi.c gpio / ACPI: get rid of acpi_gpio.h 2014-01-08 15:07:28 +01:00
gpiolib-of.c GPIO bulk changes for the v3.13 development cycle 2013-11-12 15:50:46 +09:00
gpiolib.c GPIO tree bulk changes for v3.14 2014-01-21 10:09:12 -08:00
gpiolib.h gpio / ACPI: get rid of acpi_gpio.h 2014-01-08 15:07:28 +01:00
Kconfig gpio: tb10x: GPIO_TB10X needs to select GENERIC_IRQ_CHIP 2014-02-05 11:13:59 +01:00
Makefile ARM: driver updates for 3.14 2014-01-23 18:49:36 -08:00