--- /dev/null
+From a974862faee199cba3ff36b5a148df5fd34bd1e7 Mon Sep 17 00:00:00 2001
+From: Dong Aisheng <b29396@freescale.com>
+Date: Thu, 26 Dec 2013 15:23:53 +0800
+Subject: mmc: sdhci-esdhc-imx: fix access hardirq-unsafe lock in atomic context
+
+From: Dong Aisheng <b29396@freescale.com>
+
+commit a974862faee199cba3ff36b5a148df5fd34bd1e7 upstream.
+
+Sometimes we may meet the following lockdep issue.
+The root cause is .set_clock callback is executed with spin_lock_irqsave
+in sdhci_do_set_ios. However, the IMX set_clock callback will try to access
+clk_get_rate which is using a mutex lock.
+
+The fix avoids access mutex in .set_clock callback by initializing the
+pltfm_host->clock at probe time and use it later instead of calling
+clk_get_rate again in atomic context.
+
+[ INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected ]
+3.13.0-rc1+ #285 Not tainted
+------------------------------------------------------
+kworker/u8:1/29 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
+ (prepare_lock){+.+...}, at: [<80480b08>] clk_prepare_lock+0x44/0xe4
+
+and this task is already holding:
+ (&(&host->lock)->rlock#2){-.-...}, at: [<804611f4>] sdhci_do_set_ios+0x20/0x720
+which would create a new lock dependency:
+ (&(&host->lock)->rlock#2){-.-...} -> (prepare_lock){+.+...}
+
+but this new dependency connects a HARDIRQ-irq-safe lock:
+ (&(&host->lock)->rlock#2){-.-...}
+... which became HARDIRQ-irq-safe at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<80060760>] __lock_acquire+0xb30/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061d2f0>] _raw_spin_lock+0x30/0x40
+ [<80460668>] 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
+ [<80614c58>] printk+0x38/0x40
+ [<804622a8>] sdhci_add_host+0x844/0xbcc
+ [<80464948>] 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
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+
+to a HARDIRQ-irq-unsafe lock:
+ (prepare_lock){+.+...}
+... which became HARDIRQ-irq-unsafe at:
+... [<8005f030>] mark_lock+0x140/0x6ac
+ [<8005f604>] mark_held_locks+0x68/0x12c
+ [<8005f780>] trace_hardirqs_on_caller+0xb8/0x1d8
+ [<8005f8b4>] trace_hardirqs_on+0x14/0x18
+ [<8061a130>] mutex_trylock+0x180/0x20c
+ [<80480ad8>] clk_prepare_lock+0x14/0xe4
+ [<804816a4>] clk_notifier_register+0x28/0xf0
+ [<80015120>] twd_clk_init+0x50/0x68
+ [<80008980>] do_one_initcall+0x108/0x16c
+ [<8081cca4>] kernel_init_freeable+0x10c/0x1d0
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+
+other info that might help us debug this:
+
+ Possible interrupt unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(prepare_lock);
+ local_irq_disable();
+ lock(&(&host->lock)->rlock#2);
+ lock(prepare_lock);
+ <Interrupt>
+ lock(&(&host->lock)->rlock#2);
+
+ *** DEADLOCK ***
+
+3 locks held by kworker/u8:1/29:
+ #0: (kmmcd){.+.+.+}, at: [<8003db18>] process_one_work+0x128/0x468
+ #1: ((&(&host->detect)->work)){+.+.+.}, at: [<8003db18>] process_one_work+0x128/0x468
+ #2: (&(&host->lock)->rlock#2){-.-...}, at: [<804611f4>] sdhci_do_set_ios+0x20/0x720
+
+the dependencies between HARDIRQ-irq-safe lock and the holding lock:
+-> (&(&host->lock)->rlock#2){-.-...} ops: 330 {
+ IN-HARDIRQ-W at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<80060760>] __lock_acquire+0xb30/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061d2f0>] _raw_spin_lock+0x30/0x40
+ [<80460668>] 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
+ [<80614c58>] printk+0x38/0x40
+ [<804622a8>] sdhci_add_host+0x844/0xbcc
+ [<80464948>] 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
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+ IN-SOFTIRQ-W at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<80060204>] __lock_acquire+0x5d4/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061d40c>] _raw_spin_lock_irqsave+0x40/0x54
+ [<8045e4a4>] sdhci_tasklet_finish+0x1c/0x120
+ [<8002b538>] tasklet_action+0xa0/0x15c
+ [<8002b778>] __do_softirq+0x118/0x290
+ [<8002bcf4>] irq_exit+0xb4/0x10c
+ [<8000f240>] handle_IRQ+0x5c/0xbc
+ [<8000864c>] gic_handle_irq+0x30/0x64
+ [<80013024>] __irq_svc+0x44/0x5c
+ [<80614c58>] printk+0x38/0x40
+ [<804622a8>] sdhci_add_host+0x844/0xbcc
+ [<80464948>] 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
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+ INITIAL USE at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<8005ff0c>] __lock_acquire+0x2dc/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061d40c>] _raw_spin_lock_irqsave+0x40/0x54
+ [<804611f4>] sdhci_do_set_ios+0x20/0x720
+ [<80461924>] sdhci_set_ios+0x30/0x3c
+ [<8044cea0>] mmc_power_up+0x6c/0xd0
+ [<8044dac4>] mmc_start_host+0x60/0x70
+ [<8044eb3c>] mmc_add_host+0x60/0x88
+ [<8046225c>] sdhci_add_host+0x7f8/0xbcc
+ [<80464948>] 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
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+ }
+ ... key at: [<80e040e8>] __key.26952+0x0/0x8
+ ... acquired at:
+ [<8005eb60>] check_usage+0x3d0/0x5c0
+ [<8005edac>] check_irq_usage+0x5c/0xb8
+ [<80060d38>] __lock_acquire+0x1108/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061a210>] mutex_lock_nested+0x54/0x3c0
+ [<80480b08>] clk_prepare_lock+0x44/0xe4
+ [<8048188c>] clk_get_rate+0x14/0x64
+ [<8046374c>] esdhc_pltfm_set_clock+0x20/0x2a4
+ [<8045d70c>] sdhci_set_clock+0x4c/0x498
+ [<80461518>] sdhci_do_set_ios+0x344/0x720
+ [<80461924>] sdhci_set_ios+0x30/0x3c
+ [<8044c390>] __mmc_set_clock+0x44/0x60
+ [<8044cd4c>] mmc_set_clock+0x10/0x14
+ [<8044f8f4>] mmc_init_card+0x1b4/0x1520
+ [<80450f00>] mmc_attach_mmc+0xb4/0x194
+ [<8044da08>] mmc_rescan+0x294/0x2f0
+ [<8003db94>] process_one_work+0x1a4/0x468
+ [<8003e850>] worker_thread+0x118/0x3e0
+ [<80044de0>] kthread+0xd4/0xf0
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+
+the dependencies between the lock to be acquired and HARDIRQ-irq-unsafe lock:
+-> (prepare_lock){+.+...} ops: 395 {
+ HARDIRQ-ON-W at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<8005f604>] mark_held_locks+0x68/0x12c
+ [<8005f780>] trace_hardirqs_on_caller+0xb8/0x1d8
+ [<8005f8b4>] trace_hardirqs_on+0x14/0x18
+ [<8061a130>] mutex_trylock+0x180/0x20c
+ [<80480ad8>] clk_prepare_lock+0x14/0xe4
+ [<804816a4>] clk_notifier_register+0x28/0xf0
+ [<80015120>] twd_clk_init+0x50/0x68
+ [<80008980>] do_one_initcall+0x108/0x16c
+ [<8081cca4>] kernel_init_freeable+0x10c/0x1d0
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+ SOFTIRQ-ON-W at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<8005f604>] mark_held_locks+0x68/0x12c
+ [<8005f7c8>] trace_hardirqs_on_caller+0x100/0x1d8
+ [<8005f8b4>] trace_hardirqs_on+0x14/0x18
+ [<8061a130>] mutex_trylock+0x180/0x20c
+ [<80480ad8>] clk_prepare_lock+0x14/0xe4
+ [<804816a4>] clk_notifier_register+0x28/0xf0
+ [<80015120>] twd_clk_init+0x50/0x68
+ [<80008980>] do_one_initcall+0x108/0x16c
+ [<8081cca4>] kernel_init_freeable+0x10c/0x1d0
+ [<80611c50>] kernel_init+0x10/0x120
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+ INITIAL USE at:
+ [<8005f030>] mark_lock+0x140/0x6ac
+ [<8005ff0c>] __lock_acquire+0x2dc/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061a0c8>] mutex_trylock+0x118/0x20c
+ [<80480ad8>] clk_prepare_lock+0x14/0xe4
+ [<80482af8>] __clk_init+0x1c/0x45c
+ [<8048306c>] _clk_register+0xd0/0x170
+ [<80483148>] clk_register+0x3c/0x7c
+ [<80483b4c>] clk_register_fixed_rate+0x88/0xd8
+ [<80483c04>] of_fixed_clk_setup+0x68/0x94
+ [<8084c6fc>] of_clk_init+0x44/0x68
+ [<808202b0>] time_init+0x2c/0x38
+ [<8081ca14>] start_kernel+0x1e4/0x368
+ [<10008074>] 0x10008074
+ }
+ ... key at: [<808afebc>] prepare_lock+0x38/0x48
+ ... acquired at:
+ [<8005eb94>] check_usage+0x404/0x5c0
+ [<8005edac>] check_irq_usage+0x5c/0xb8
+ [<80060d38>] __lock_acquire+0x1108/0x1cbc
+ [<800620d0>] lock_acquire+0x70/0x84
+ [<8061a210>] mutex_lock_nested+0x54/0x3c0
+ [<80480b08>] clk_prepare_lock+0x44/0xe4
+ [<8048188c>] clk_get_rate+0x14/0x64
+ [<8046374c>] esdhc_pltfm_set_clock+0x20/0x2a4
+ [<8045d70c>] sdhci_set_clock+0x4c/0x498
+ [<80461518>] sdhci_do_set_ios+0x344/0x720
+ [<80461924>] sdhci_set_ios+0x30/0x3c
+ [<8044c390>] __mmc_set_clock+0x44/0x60
+ [<8044cd4c>] mmc_set_clock+0x10/0x14
+ [<8044f8f4>] mmc_init_card+0x1b4/0x1520
+ [<80450f00>] mmc_attach_mmc+0xb4/0x194
+ [<8044da08>] mmc_rescan+0x294/0x2f0
+ [<8003db94>] process_one_work+0x1a4/0x468
+ [<8003e850>] worker_thread+0x118/0x3e0
+ [<80044de0>] kthread+0xd4/0xf0
+ [<8000e9c8>] ret_from_fork+0x14/0x2c
+
+stack backtrace:
+CPU: 2 PID: 29 Comm: kworker/u8:1 Not tainted 3.13.0-rc1+ #285
+Workqueue: kmmcd mmc_rescan
+Backtrace:
+[<80012160>] (dump_backtrace+0x0/0x10c) from [<80012438>] (show_stack+0x18/0x1c)
+ r6:00000000 r5:00000000 r4:8088ecc8 r3:bfa11200
+[<80012420>] (show_stack+0x0/0x1c) from [<80616b14>] (dump_stack+0x84/0x9c)
+[<80616a90>] (dump_stack+0x0/0x9c) from [<8005ebb4>] (check_usage+0x424/0x5c0)
+ r5:80979940 r4:bfa29b44
+[<8005e790>] (check_usage+0x0/0x5c0) from [<8005edac>] (check_irq_usage+0x5c/0xb8)
+[<8005ed50>] (check_irq_usage+0x0/0xb8) from [<80060d38>] (__lock_acquire+0x1108/0x1cbc)
+ r8:bfa115e8 r7:80df9884 r6:80dafa9c r5:00000003 r4:bfa115d0
+[<8005fc30>] (__lock_acquire+0x0/0x1cbc) from [<800620d0>] (lock_acquire+0x70/0x84)
+[<80062060>] (lock_acquire+0x0/0x84) from [<8061a210>] (mutex_lock_nested+0x54/0x3c0)
+ r7:bfa11200 r6:80dafa9c r5:00000000 r4:80480b08
+[<8061a1bc>] (mutex_lock_nested+0x0/0x3c0) from [<80480b08>] (clk_prepare_lock+0x44/0xe4)
+[<80480ac4>] (clk_prepare_lock+0x0/0xe4) from [<8048188c>] (clk_get_rate+0x14/0x64)
+ r6:03197500 r5:bf0e9aa8 r4:bf827400 r3:808ae128
+[<80481878>] (clk_get_rate+0x0/0x64) from [<8046374c>] (esdhc_pltfm_set_clock+0x20/0x2a4)
+ r5:bf0e9aa8 r4:bf0e9c40
+[<8046372c>] (esdhc_pltfm_set_clock+0x0/0x2a4) from [<8045d70c>] (sdhci_set_clock+0x4c/0x498)
+[<8045d6c0>] (sdhci_set_clock+0x0/0x498) from [<80461518>] (sdhci_do_set_ios+0x344/0x720)
+ r8:0000003b r7:20000113 r6:bf0e9d68 r5:bf0e9aa8 r4:bf0e9c40
+r3:00000000
+[<804611d4>] (sdhci_do_set_ios+0x0/0x720) from [<80461924>] (sdhci_set_ios+0x30/0x3c)
+ r9:00000004 r8:bf131000 r7:bf131048 r6:00000000 r5:bf0e9aa8
+r4:bf0e9800
+[<804618f4>] (sdhci_set_ios+0x0/0x3c) from [<8044c390>] (__mmc_set_clock+0x44/0x60)
+ r5:03197500 r4:bf0e9800
+[<8044c34c>] (__mmc_set_clock+0x0/0x60) from [<8044cd4c>] (mmc_set_clock+0x10/0x14)
+ r5:00000000 r4:bf0e9800
+[<8044cd3c>] (mmc_set_clock+0x0/0x14) from [<8044f8f4>] (mmc_init_card+0x1b4/0x1520)
+[<8044f740>] (mmc_init_card+0x0/0x1520) from [<80450f00>] (mmc_attach_mmc+0xb4/0x194)
+[<80450e4c>] (mmc_attach_mmc+0x0/0x194) from [<8044da08>] (mmc_rescan+0x294/0x2f0)
+ r5:8065f358 r4:bf0e9af8
+[<8044d774>] (mmc_rescan+0x0/0x2f0) from [<8003db94>] (process_one_work+0x1a4/0x468)
+ r8:00000000 r7:bfa29eb0 r6:bf80dc00 r5:bf0e9af8 r4:bf9e3f00
+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:bf9e7f00
+
+Fixes: 0ddf03c mmc: esdhc-imx: parse max-frequency from devicetree
+Signed-off-by: Dong Aisheng <b29396@freescale.com>
+Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Tested-by: Philippe De Muyter <phdm@macqel.be>
+Signed-off-by: Chris Ball <chris@printf.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -558,19 +558,17 @@ static unsigned int esdhc_pltfm_get_max_
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+ struct esdhc_platform_data *boarddata = &imx_data->boarddata;
+
+- u32 f_host = clk_get_rate(pltfm_host->clk);
+-
+- if (boarddata->f_max && (boarddata->f_max < f_host))
++ if (boarddata->f_max && (boarddata->f_max < pltfm_host->clock))
+ return boarddata->f_max;
+ else
+- return f_host;
++ return pltfm_host->clock;
+ }
+
+ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
+ {
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+- return clk_get_rate(pltfm_host->clk) / 256 / 16;
++ return pltfm_host->clock / 256 / 16;
+ }
+
+ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
+@@ -578,7 +576,7 @@ static inline void esdhc_pltfm_set_clock
+ {
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+- unsigned int host_clock = clk_get_rate(pltfm_host->clk);
++ unsigned int host_clock = pltfm_host->clock;
+ int pre_div = 2;
+ int div = 1;
+ u32 temp, val;
+@@ -976,7 +974,7 @@ static int sdhci_esdhc_imx_probe(struct
+ }
+
+ pltfm_host->clk = imx_data->clk_per;
+-
++ pltfm_host->clock = clk_get_rate(pltfm_host->clk);
+ clk_prepare_enable(imx_data->clk_per);
+ clk_prepare_enable(imx_data->clk_ipg);
+ clk_prepare_enable(imx_data->clk_ahb);
--- /dev/null
+From 2b35bd83467df6f8284b9148d6f768148c3a5e5f Mon Sep 17 00:00:00 2001
+From: Aisheng Dong <b29396@freescale.com>
+Date: Mon, 23 Dec 2013 19:13:04 +0800
+Subject: mmc: sdhci: fix lockdep error in tuning routine
+
+From: Aisheng Dong <b29396@freescale.com>
+
+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>
+
+---
+ drivers/mmc/host/sdhci.c | 20 +++++++-------------
+ 1 file changed, 7 insertions(+), 13 deletions(-)
+
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1845,12 +1845,12 @@ static int sdhci_execute_tuning(struct m
+ unsigned long timeout;
+ int err = 0;
+ bool requires_tuning_nonuhs = false;
++ unsigned long flags;
+
+ host = mmc_priv(mmc);
+
+ sdhci_runtime_pm_get(host);
+- disable_irq(host->irq);
+- spin_lock(&host->lock);
++ spin_lock_irqsave(&host->lock, flags);
+
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+@@ -1870,15 +1870,13 @@ static int sdhci_execute_tuning(struct m
+ requires_tuning_nonuhs)
+ ctrl |= SDHCI_CTRL_EXEC_TUNING;
+ else {
+- spin_unlock(&host->lock);
+- enable_irq(host->irq);
++ spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_runtime_pm_put(host);
+ return 0;
+ }
+
+ if (host->ops->platform_execute_tuning) {
+- spin_unlock(&host->lock);
+- enable_irq(host->irq);
++ spin_unlock_irqrestore(&host->lock, flags);
+ err = host->ops->platform_execute_tuning(host, opcode);
+ sdhci_runtime_pm_put(host);
+ return err;
+@@ -1951,15 +1949,12 @@ static int sdhci_execute_tuning(struct m
+ host->cmd = NULL;
+ host->mrq = NULL;
+
+- spin_unlock(&host->lock);
+- enable_irq(host->irq);
+-
++ spin_unlock_irqrestore(&host->lock, flags);
+ /* Wait for Buffer Read Ready interrupt */
+ wait_event_interruptible_timeout(host->buf_ready_int,
+ (host->tuning_done == 1),
+ msecs_to_jiffies(50));
+- disable_irq(host->irq);
+- spin_lock(&host->lock);
++ spin_lock_irqsave(&host->lock, flags);
+
+ if (!host->tuning_done) {
+ pr_info(DRIVER_NAME ": Timeout waiting for "
+@@ -2034,8 +2029,7 @@ out:
+ err = 0;
+
+ sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
+- spin_unlock(&host->lock);
+- enable_irq(host->irq);
++ spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_runtime_pm_put(host);
+
+ return err;
--- /dev/null
+From 390145f9adcf2730fcee81c8a51fd7c6c08f705f Mon Sep 17 00:00:00 2001
+From: David Cohen <david.a.cohen@linux.intel.com>
+Date: Tue, 29 Oct 2013 10:58:27 -0700
+Subject: mmc: sdhci-pci: add broken HS200 quirk for Intel Merrifield
+
+From: David Cohen <david.a.cohen@linux.intel.com>
+
+commit 390145f9adcf2730fcee81c8a51fd7c6c08f705f upstream.
+
+Due to unknown hw issue so far, Merrifield is unable to enable HS200
+support. This patch adds quirk to avoid SDHCI to initialize with error
+below:
+
+[ 53.850132] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W
+3.12.0-rc6-00037-g3d7c8d9-dirty #36
+[ 53.850150] Hardware name: Intel Corporation Merrifield/SALT BAY,
+BIOS 397 2013.09.12:11.51.40
+[ 53.850167] 00000000 00000000 ee409e48 c18816d2 00000000 ee409e78
+c123e254 c1acc9b0
+[ 53.850227] 00000000 00000000 c1b14148 000003de c16c03bf c16c03bf
+ee75b480 ed97c54c
+[ 53.850282] ee75b480 ee409e88 c123e292 00000009 00000000 ee409ef8
+c16c03bf c1207fac
+[ 53.850339] Call Trace:
+[ 53.850376] [<c18816d2>] dump_stack+0x4b/0x79
+[ 53.850408] [<c123e254>] warn_slowpath_common+0x84/0xa0
+[ 53.850436] [<c16c03bf>] ? sdhci_send_command+0xb4f/0xc50
+[ 53.850462] [<c16c03bf>] ? sdhci_send_command+0xb4f/0xc50
+[ 53.850490] [<c123e292>] warn_slowpath_null+0x22/0x30
+[ 53.850516] [<c16c03bf>] sdhci_send_command+0xb4f/0xc50
+[ 53.850545] [<c1207fac>] ? native_sched_clock+0x2c/0xb0
+[ 53.850575] [<c14c1f93>] ? delay_tsc+0x73/0xb0
+[ 53.850601] [<c14c1ebe>] ? __const_udelay+0x1e/0x20
+[ 53.850626] [<c16bdeb3>] ? sdhci_reset+0x93/0x190
+[ 53.850654] [<c16c05b0>] sdhci_finish_data+0xf0/0x2e0
+[ 53.850683] [<c16c130f>] sdhci_irq+0x31f/0x930
+[ 53.850713] [<c12cb080>] ? __buffer_unlock_commit+0x10/0x20
+[ 53.850740] [<c12cbcd7>] ? trace_buffer_unlock_commit+0x37/0x50
+[ 53.850773] [<c1288f3c>] handle_irq_event_percpu+0x5c/0x220
+[ 53.850800] [<c128bc96>] ? handle_fasteoi_irq+0x16/0xd0
+[ 53.850827] [<c128913a>] handle_irq_event+0x3a/0x60
+[ 53.850852] [<c128bc80>] ? unmask_irq+0x30/0x30
+[ 53.850878] [<c128bcce>] handle_fasteoi_irq+0x4e/0xd0
+[ 53.850895] <IRQ> [<c1890b52>] ? do_IRQ+0x42/0xb0
+[ 53.850943] [<c1890a31>] ? common_interrupt+0x31/0x38
+[ 53.850973] [<c12b00d8>] ? cgroup_mkdir+0x4e8/0x580
+[ 53.851001] [<c1208d32>] ? default_idle+0x22/0xf0
+[ 53.851029] [<c1209576>] ? arch_cpu_idle+0x26/0x30
+[ 53.851054] [<c1288505>] ? cpu_startup_entry+0x65/0x240
+[ 53.851082] [<c18793d5>] ? rest_init+0xb5/0xc0
+[ 53.851108] [<c1879320>] ? __read_lock_failed+0x18/0x18
+[ 53.851138] [<c1bf6a15>] ? start_kernel+0x31b/0x321
+[ 53.851164] [<c1bf652f>] ? repair_env_string+0x51/0x51
+[ 53.851190] [<c1bf6363>] ? i386_start_kernel+0x139/0x13c
+[ 53.851209] ---[ end trace 92777f5fe48d33f2 ]---
+[ 53.853449] mmcblk0: error -84 transferring data, sector 11142162, nr
+304, cmd response 0x0, card status 0x0
+[ 53.853476] mmcblk0: retrying using single block read
+[ 55.937863] sdhci: Timeout waiting for Buffer Read Ready interrupt
+during tuning procedure, falling back to fixed sampling clock
+[ 56.207951] sdhci: Timeout waiting for Buffer Read Ready interrupt
+during tuning procedure, falling back to fixed sampling clock
+[ 66.228785] mmc0: Timeout waiting for hardware interrupt.
+[ 66.230855] ------------[ cut here ]------------
+
+Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
+Reviewed-by: Chuanxiao Dong <chuanxiao.dong@intel.com>
+Acked-by: Dong Aisheng <b29396@freescale.com>
+Signed-off-by: Chris Ball <chris@printf.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mmc/host/sdhci-pci.c
++++ b/drivers/mmc/host/sdhci-pci.c
+@@ -381,6 +381,7 @@ static int intel_mrfl_mmc_probe_slot(str
+
+ static const struct sdhci_pci_fixes sdhci_intel_mrfl_mmc = {
+ .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
++ .quirks2 = SDHCI_QUIRK2_BROKEN_HS200,
+ .probe_slot = intel_mrfl_mmc_probe_slot,
+ };
+