mmc: sdhci: fix lockdep error in tuning routine
commit
2b35bd83467df6f8284b9148d6f768148c3a5e5f upstream.
The sdhci_execute_tuning routine gets lock separately by
disable_irq(host->irq);
spin_lock(&host->lock);
It will cause the following lockdep error message since the &host->lock
could also be got in irq context.
Use spin_lock_irqsave/spin_unlock_restore instead to get rid of
this error message.
[ INFO: inconsistent lock state ]
3.13.0-rc1+ #287 Not tainted
---------------------------------
inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
kworker/u2:1/33 [HC0[0]:SC0[0]:HE1:SE1] takes:
(&(&host->lock)->rlock){?.-...}, at: [<
8045f7f4>] sdhci_execute_tuning+0x4c/0x710
{IN-HARDIRQ-W} state was registered at:
[<
8005f030>] mark_lock+0x140/0x6ac
[<
80060760>] __lock_acquire+0xb30/0x1cbc
[<
800620d0>] lock_acquire+0x70/0x84
[<
8061d1c8>] _raw_spin_lock+0x30/0x40
[<
804605cc>] sdhci_irq+0x24/0xa68
[<
8006b1d4>] handle_irq_event_percpu+0x54/0x18c
[<
8006b350>] handle_irq_event+0x44/0x64
[<
8006e50c>] handle_fasteoi_irq+0xa0/0x170
[<
8006a8f0>] generic_handle_irq+0x30/0x44
[<
8000f238>] handle_IRQ+0x54/0xbc
[<
8000864c>] gic_handle_irq+0x30/0x64
[<
80013024>] __irq_svc+0x44/0x5c
[<
80329bf4>] dev_vprintk_emit+0x50/0x58
[<
80329c24>] dev_printk_emit+0x28/0x30
[<
80329fec>] __dev_printk+0x4c/0x90
[<
8032a180>] dev_err+0x3c/0x48
[<
802dd4f0>] _regulator_get+0x158/0x1cc
[<
802dd5b4>] regulator_get_optional+0x18/0x1c
[<
80461df4>] sdhci_add_host+0x42c/0xbd8
[<
80464820>] sdhci_esdhc_imx_probe+0x378/0x67c
[<
8032ee88>] platform_drv_probe+0x20/0x50
[<
8032d48c>] driver_probe_device+0x118/0x234
[<
8032d690>] __driver_attach+0x9c/0xa0
[<
8032b89c>] bus_for_each_dev+0x68/0x9c
[<
8032cf44>] driver_attach+0x20/0x28
[<
8032cbc8>] bus_add_driver+0x148/0x1f4
[<
8032dce0>] driver_register+0x80/0x100
[<
8032ee54>] __platform_driver_register+0x50/0x64
[<
8084b094>] sdhci_esdhc_imx_driver_init+0x18/0x20
[<
80008980>] do_one_initcall+0x108/0x16c
[<
8081cca4>] kernel_init_freeable+0x10c/0x1d0
[<
80611b28>] kernel_init+0x10/0x120
[<
8000e9c8>] ret_from_fork+0x14/0x2c
irq event stamp: 805
hardirqs last enabled at (805): [<
8061d43c>] _raw_spin_unlock_irqrestore+0x38/0x4c
hardirqs last disabled at (804): [<
8061d2c8>] _raw_spin_lock_irqsave+0x24/0x54
softirqs last enabled at (570): [<
8002b824>] __do_softirq+0x1c4/0x290
softirqs last disabled at (561): [<
8002bcf4>] irq_exit+0xb4/0x10c
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&(&host->lock)->rlock);
<Interrupt>
lock(&(&host->lock)->rlock);
*** DEADLOCK ***
2 locks held by kworker/u2:1/33:
#0: (kmmcd){.+.+..}, at: [<
8003db18>] process_one_work+0x128/0x468
#1: ((&(&host->detect)->work)){+.+...}, at: [<
8003db18>] process_one_work+0x128/0x468
stack backtrace:
CPU: 0 PID: 33 Comm: kworker/u2:1 Not tainted 3.13.0-rc1+ #287
Workqueue: kmmcd mmc_rescan
Backtrace:
[<
80012160>] (dump_backtrace+0x0/0x10c) from [<
80012438>] (show_stack+0x18/0x1c)
r6:
bfad0900 r5:
00000000 r4:
8088ecc8 r3:
bfad0900
[<
80012420>] (show_stack+0x0/0x1c) from [<
806169ec>] (dump_stack+0x84/0x9c)
[<
80616968>] (dump_stack+0x0/0x9c) from [<
806147b4>] (print_usage_bug+0x260/0x2d0)
r5:
8076ba88 r4:
80977410
[<
80614554>] (print_usage_bug+0x0/0x2d0) from [<
8005f0d0>] (mark_lock+0x1e0/0x6ac)
r9:
8005e678 r8:
00000000 r7:
bfad0900 r6:
00001015 r5:
bfad0cd0
r4:
00000002
[<
8005eef0>] (mark_lock+0x0/0x6ac) from [<
80060234>] (__lock_acquire+0x604/0x1cbc)
[<
8005fc30>] (__lock_acquire+0x0/0x1cbc) from [<
800620d0>] (lock_acquire+0x70/0x84)
[<
80062060>] (lock_acquire+0x0/0x84) from [<
8061d1c8>] (_raw_spin_lock+0x30/0x40)
r7:
00000000 r6:
bfb63000 r5:
00000000 r4:
bfb60568
[<
8061d198>] (_raw_spin_lock+0x0/0x40) from [<
8045f7f4>] (sdhci_execute_tuning+0x4c/0x710)
r4:
bfb60000
[<
8045f7a8>] (sdhci_execute_tuning+0x0/0x710) from [<
80453454>] (mmc_sd_init_card+0x5f8/0x660)
[<
80452e5c>] (mmc_sd_init_card+0x0/0x660) from [<
80453748>] (mmc_attach_sd+0xb4/0x180)
r9:
bf92d400 r8:
8065f364 r7:
00061a80 r6:
bfb60000 r5:
8065f358
r4:
bfb60000
[<
80453694>] (mmc_attach_sd+0x0/0x180) from [<
8044d9f8>] (mmc_rescan+0x284/0x2f0)
r5:
8065f358 r4:
bfb602f8
[<
8044d774>] (mmc_rescan+0x0/0x2f0) from [<
8003db94>] (process_one_work+0x1a4/0x468)
r8:
00000000 r7:
bfb55eb0 r6:
bf80dc00 r5:
bfb602f8 r4:
bfb35980
r3:
8044d774
[<
8003d9f0>] (process_one_work+0x0/0x468) from [<
8003e850>] (worker_thread+0x118/0x3e0)
[<
8003e738>] (worker_thread+0x0/0x3e0) from [<
80044de0>] (kthread+0xd4/0xf0)
[<
80044d0c>] (kthread+0x0/0xf0) from [<
8000e9c8>] (ret_from_fork+0x14/0x2c)
r7:
00000000 r6:
00000000 r5:
80044d0c r4:
bfb37b40
Signed-off-by: Dong Aisheng <b29396@freescale.com>
Signed-off-by: Chris Ball <chris@printf.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>