summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-esdhc-imx.c
AgeCommit message (Collapse)Author
2014-05-22mmc: sdhci-esdhc-imx: fix mmc ddr mode regression issueAisheng Dong
It's caused by the platform driver was still using MMC_TIMING_UHS_DDR50 for MMC DDR mode which needs update too. Reported-by: Fabio Estevam <fabio.estevam@freescale.com> Reported-by: Shawn Guo <shawn.guo@freescale.com> Signed-off-by: Dong Aisheng <b29396@freescale.com> Tested-by: Fabio Estevam <fabio.estevam@freescale.com> [Ulf Hansson] Resolved conflict Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci-esdhc-imx: remove emulation of uhs_modeRussell King
We no longer need to emulate the uhs_mode field of the host control2 register - the main sdhci driver never reads this back to evaluate the current mode as it caches the current mode instead. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: set_uhs_signaling() need not return a valueRussell King
The set_uhs_signaling() method gives the impression that it can fail, but anything returned from the method is entirely ignored by the sdhci driver. So returning failure has no effect. So, kill the idea that it's possible for this to return an error by removing the returned value. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci-esdhc-imx: fix lockdep splat upon tuningRussell King
================================= [ INFO: inconsistent lock state ] 3.14.0-rc1+ #490 Not tainted --------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. kworker/u8:0/6 [HC0[0]:SC0[0]:HE1:SE1] takes: (&(&host->lock)->rlock#2){?.-...}, at: [<c04b57a4>] esdhc_send_tuning_cmd+0x104/0x14c {IN-HARDIRQ-W} state was registered at: [<c00652fc>] mark_lock+0x15c/0x6f8 [<c0066354>] __lock_acquire+0xabc/0x1ca0 [<c0067ad8>] lock_acquire+0xa0/0x130 [<c0697a44>] _raw_spin_lock+0x34/0x44 [<c04b0dbc>] sdhci_irq+0x20/0xa40 [<c0071b1c>] handle_irq_event_percpu+0x74/0x284 [<c0071d70>] handle_irq_event+0x44/0x64 [<c0074db8>] handle_fasteoi_irq+0xac/0x140 [<c007147c>] generic_handle_irq+0x28/0x38 [<c000efd4>] handle_IRQ+0x40/0x98 [<c0008584>] gic_handle_irq+0x30/0x64 [<c0013144>] __irq_svc+0x44/0x58 [<c0028fc8>] irq_exit+0xc0/0x120 [<c000efd8>] handle_IRQ+0x44/0x98 [<c0008584>] gic_handle_irq+0x30/0x64 [<c0013144>] __irq_svc+0x44/0x58 [<c068f398>] printk+0x3c/0x44 [<c03191d0>] _regulator_get+0x1b4/0x1e0 [<c031924c>] regulator_get+0x18/0x1c [<c049fbc4>] mmc_add_host+0x30/0x1c0 [<c04b2e10>] sdhci_add_host+0x804/0xbbc [<c04b5318>] sdhci_esdhc_imx_probe+0x380/0x674 [<c036d530>] platform_drv_probe+0x20/0x50 [<c036b948>] driver_probe_device+0x120/0x234 [<c036baf8>] __driver_attach+0x9c/0xa0 [<c036a04c>] bus_for_each_dev+0x5c/0x90 [<c036b418>] driver_attach+0x24/0x28 [<c036b018>] bus_add_driver+0xe4/0x1d8 [<c036c1b0>] driver_register+0x80/0xfc [<c036ce28>] __platform_driver_register+0x50/0x64 [<c093706c>] sdhci_esdhc_imx_driver_init+0x18/0x20 [<c0008834>] do_one_initcall+0x3c/0x164 [<c0901c94>] kernel_init_freeable+0x104/0x1d0 [<c068c45c>] kernel_init+0x10/0x118 [<c000e768>] ret_from_fork+0x14/0x2c irq event stamp: 5933 hardirqs last enabled at (5933): [<c069813c>] _raw_spin_unlock_irqrestore+0x38/0x4c hardirqs last disabled at (5932): [<c0697b04>] _raw_spin_lock_irqsave+0x24/0x60 softirqs last enabled at (5914): [<c0028ba0>] __do_softirq+0x260/0x360 softirqs last disabled at (5909): [<c0028fc8>] irq_exit+0xc0/0x120 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&host->lock)->rlock#2); <Interrupt> lock(&(&host->lock)->rlock#2); *** DEADLOCK *** 2 locks held by kworker/u8:0/6: #0: (kmmcd){.+.+.+}, at: [<c003d890>] process_one_work+0x134/0x4e8 #1: ((&(&host->detect)->work)){+.+.+.}, at: [<c003d890>] process_one_work+0x134/0x4e8 stack backtrace: CPU: 2 PID: 6 Comm: kworker/u8:0 Not tainted 3.14.0-rc1+ #490 Workqueue: kmmcd mmc_rescan Backtrace: [<c00124a0>] (dump_backtrace) from [<c0012640>] (show_stack+0x18/0x1c) [<c0012628>] (show_stack) from [<c069164c>] (dump_stack+0x70/0x8c) [<c06915dc>] (dump_stack) from [<c068f080>] (print_usage_bug+0x274/0x2e4) [<c068ee0c>] (print_usage_bug) from [<c0065774>] (mark_lock+0x5d4/0x6f8) [<c00651a0>] (mark_lock) from [<c0065e6c>] (__lock_acquire+0x5d4/0x1ca0) [<c0065898>] (__lock_acquire) from [<c0067ad8>] (lock_acquire+0xa0/0x130) [<c0067a38>] (lock_acquire) from [<c0697a44>] (_raw_spin_lock+0x34/0x44) [<c0697a10>] (_raw_spin_lock) from [<c04b57a4>] (esdhc_send_tuning_cmd+0x104/0x14c) [<c04b56a0>] (esdhc_send_tuning_cmd) from [<c04b582c>] (esdhc_executing_tuning+0x40/0x100) [<c04b57ec>] (esdhc_executing_tuning) from [<c04afa54>] (sdhci_execute_tuning+0xcc/0x754) [<c04af988>] (sdhci_execute_tuning) from [<c04a4684>] (mmc_sd_init_card+0x65c/0x694) [<c04a4028>] (mmc_sd_init_card) from [<c04a48f0>] (mmc_attach_sd+0xb0/0x184) [<c04a4840>] (mmc_attach_sd) from [<c049eb28>] (mmc_rescan+0x26c/0x2e8) [<c049e8bc>] (mmc_rescan) from [<c003d914>] (process_one_work+0x1b8/0x4e8) [<c003d75c>] (process_one_work) from [<c003e090>] (worker_thread+0x13c/0x3f8) [<c003df54>] (worker_thread) from [<c00449bc>] (kthread+0xcc/0xe8) [<c00448f0>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c) Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci-esdhc-imx: comment runtime_pm_get_sync() in esdhc_prepare_tuning()Russell King
It is far from obvious what this is doing, and it looks like it's an unbalanced runtime_pm_get() call. However, the put is inside sdhci_tasklet_finish(), so it's not unbalanced at all. This should be documented so people know what's going on here. Do so. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci-esdhc-imx: avoid DMA to kernel stackRussell King
sdhci-esdhc-imx tries to DMA to the kernel stack when tuning the interface, which causes dma-debug to complain. Fix this by kmallocing a buffer to hold the received tuning pattern. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: move setting mmc->actual_clock into set_clock handlersRussell King
Move the setting of mmc->actual_clock to zero into the set_clock handlers themselves. This will allow us to clean up the calling logic for the set_clock() method, and turn sdhci_set_clock() into a library function. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: move setting host->clock into sdhci_do_set_ios()Russell King
We don't need implementations to do this, since the only time it's necessary is when we change the clock, and the only place that happens is in sdhci_do_set_ios(). So, move it there, and remove it from the iMX platform backend. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: move FSL ESDHC reset handling quirk into esdhc codeRussell King
The Freescale esdhc driver is the only driver which needs the interrupt registers restored after a reset. Move this quirk to be part of the ESDHC driver implementation. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: convert reset into a library functionRussell King
Rather than having platform_reset_enter/platform_reset_exit methods, turn the core of the reset handling into a library function which platforms can call at the appropriate moment in their (new) reset method. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: convert generic bus width setup to library functionRussell King
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-05-22mmc: sdhci: allow sdio interrupts while sdhci runtime suspendedRussell King
Allow SDIO interrupts to be received while the SDHCI host is runtime suspended. We do this by leaving the AHB clock enabled while the host is runtime suspended so we can access the SDHCI registers, and so read and raise the SDIO card interrupt. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-01-13mmc: sdhci-esdhc-imx: fix warning during module remove functionDong Aisheng
Since the clock is managed by runtime pm currently, we do not need disable it again during driver remove function, or it will cause clock disable count mismatch issue since the clocks have already been disabled. The issue can be simply reproduced by unbind the devices via sysfs. mx6slevk:/sys/bus/platform/drivers/sdhci-esdhc-imx# echo 2194000.usdhc > unbind mmc1: card aaaa removed ------------[ cut here ]------------ WARNING: CPU: 0 PID: 657 at drivers/clk/clk.c:842 __clk_disable+0x68/0x88() Modules linked in: CPU: 0 PID: 657 Comm: sh Not tainted 3.13.0-rc1+ #285 Backtrace: [<80012160>] (dump_backtrace+0x0/0x10c) from [<80012438>] (show_stack+0x18/0x1c) r6:80481370 r5:00000000 r4:8088ecc8 r3:00000000 [<80012420>] (show_stack+0x0/0x1c) from [<80616b14>] (dump_stack+0x84/0x9c) [<80616a90>] (dump_stack+0x0/0x9c) from [<80027158>] (warn_slowpath_common+0x70/0x94) r5:00000009 r4:00000000 [<800270e8>] (warn_slowpath_common+0x0/0x94) from [<80027220>] (warn_slowpath_null+0x24/0x2c) r8:bec4ff78 r7:0000000e r6:bf91d800 r5:bf81d080 r4:bf81d080 [<800271fc>] (warn_slowpath_null+0x0/0x2c) from [<80481370>] (__clk_disable+0x68/0x88) [<80481308>] (__clk_disable+0x0/0x88) from [<8048148c>] (clk_disable+0x20/0x2c) r4:200f0113 r3:bf95ec00 [<8048146c>] (clk_disable+0x0/0x2c) from [<80463bd8>] (sdhci_esdhc_imx_remove+0x64/0xa4) r5:bf81d080 r4:bfabb010 [<80463b74>] (sdhci_esdhc_imx_remove+0x0/0xa4) from [<8032e82c>] (platform_drv_remove+0x20/0x24) r6:808ae0e0 r5:808ae0e0 r4:bf91d810 r3:80463b74 [<8032e80c>] (platform_drv_remove+0x0/0x24) from [<8032d010>] (__device_release_driver+0x78/0xd0) [<8032cf98>] (__device_release_driver+0x0/0xd0) from [<8032d090>] (device_release_driver+0x28/0x34) r5:bf91d810 r4:bf91d844 [<8032d068>] (device_release_driver+0x0/0x34) from [<8032c0c8>] (unbind_store+0x80/0xc4) r5:bf91d810 r4:80899ba0 [<8032c048>] (unbind_store+0x0/0xc4) from [<8032b648>] (drv_attr_store+0x28/0x34) r7:bed73100 r6:0000000e r5:00000000 r4:8032b620 [<8032b620>] (drv_attr_store+0x0/0x34) from [<80140580>] (sysfs_write_file+0x1b0/0x1e4) [<801403d0>] (sysfs_write_file+0x0/0x1e4) from [<800dcda0>] (vfs_write+0xb4/0x190) [<800dccec>] (vfs_write+0x0/0x190) from [<800dd3e4>] (SyS_write+0x44/0x80) r9:0000000e r8:00000000 r7:01a00408 r6:bf3b1c00 r5:00000000 r4:00000000 [<800dd3a0>] (SyS_write+0x0/0x80) from [<8000e900>] (ret_fast_syscall+0x0/0x48) r9:bec4e000 r8:8000eac4 r7:00000004 r6:76f5fb40 r5:01a00408 r4:0000000e ---[ end trace a0897d268e6233b2 ]--- If without runtime pm, we just run as before to match the clock enable in probe function. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
2014-01-13mmc: sdhci-esdhc-imx: fix access hardirq-unsafe lock in atomic contextDong Aisheng
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> Cc: stable <stable@vger.kernel.org> # 3.13 Signed-off-by: Chris Ball <chris@printf.net>
2014-01-13mmc: sdhci-esdhc-imx: Use NULL instead of zeroFabio Estevam
Fix the following sparse warning: drivers/mmc/host/sdhci-esdhc-imx.c:617:35: warning: Using plain integer as NULL pointer Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: sdhci-esdhc-imx: add runtime pm supportDong Aisheng
The root clock will be disabled in runtime pm to save power. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: sdhci-esdhc-imx: fix runtime pm unbalance issueDong Aisheng
Since we're using common esdhc_send_command for tuning commands and the core code will call pm_runtime_put after command is finished. So we add a pm_runtime_get_sync here to get the balance. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: esdhc-imx: clearing SDHCI_CTRL_EXEC_TUNING should not affect other bitsDong Aisheng
Current code will clear all turning related bits like ESDHC_STD_TUNING_EN and ESDHC_MIX_CTRL_FBCLK_SEL when clear SDHCI_CTRL_EXEC_TUNING. This may cause the card which has already passed the turning to become unwork since the turning status lost. We observed this failure when enable runtime pm. BTW, imx needs to enable ESDHC_MIX_CTRL_FBCLK_SEL bit for turned clock. The FBCLK_SEL will be cleared when SDHCI_CTRL_TUNED_CLK is cleared and SDHCI_CTRL_EXEC_TUNING is not set. This is used in case we change to another normal card from a UHS card in the same slot. FBCLK_SEL is not needed for normal card. After that, SDHCI_CTRL_EXEC_TUNING will only affect ESDHC_MIX_CTRL_EXE_TUNE. Clearing it does not affect the turned card to remain working on UHS mode. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: sdhci-esdhc-imx: tuning bits should not be cleared during resetDong Aisheng
We should not clear tuning bits during reset or the SD3.0/eMMC4.5 card working on UHS mode may not work after reset since the former tuning settings was lost. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: sdhci-esdhc-imx: add eMMC HS200 mode supportDong Aisheng
Add support for eMMC 4.5 cards to work on hs200 mode. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: sdhci-esdhc-imx: add MMC_CAP_1_8V_DDR for mx6Dong Aisheng
The i.MX6 supports 1.8v/3.3v eMMC DDR mode, so add this flag. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2014-01-13mmc: sdhci-esdhc-imx: fix cpas over write issueDong Aisheng
We should use '|=' instead '=', or it may over write the original caps assigned before this line. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-11-26mmc: sdhci-esdhc-imx: add SDHCI_TRANSFER_MODE read functionDong Aisheng
Used to read out the correct value of SDHCI_TRANSFER_MODE register for upper layer. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: add preset value quirk for mx6Dong Aisheng
The i.MX6 does not support preset value feature. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: enable SDR50 tuning for imx6q/dlDong Aisheng
The imx6q/dl supports SDR50 tunning, enable it for a better timing on SDR50 mode. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: add delay line setting supportDong Aisheng
The DLL(Delay Line) is newly added to assist in sampling read data. The DLL provides the ability to programmatically select a quantized delay (in fractions of the clock period) regardless of on-chip variations such as process, voltage and temperature (PVT). This patch adds a user interface to set slave delay line via device tree. It's usually used in high speed mode like mmc DDR mode when the signal quality is not good caused by board design, e.g. the signal path is too long. User can manually set delay line to find a suitable data sampling window for card to work properly. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: add DDR mode support for mx6Dong Aisheng
When DDR mode is enabled, the initial pre_div should be 2. And the pre_div value should be changed accordingly from ... 02h) Base clock divided by 4 01h) Base clock divided by 2 00h) Base clock divided by 1 to .. 02h) Base clock divided by 8 01h) Base clock divided by 4 00h) Base clock divided by 2 Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: fix reading cap_1 register value for mx6slDong Aisheng
When reading CAP_1 register for mx6sl, ignore bit[0-15] as it stores CAP_2 register value which is new introduced in mx6sl. Without this fix, the max clock for mx6sl may not be correct since it's wrongly calculated by reading CAP_1 register. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: add std tuning support for mx6slDong Aisheng
The mx6sl supports standard sdhci tuning, then esdhc_executing_tuning is only needed for mx6q/dl. We introduce is_imx6_usdhc() and is_imx6sl_usdhc() to handle the difference. The standard tuning is enabled by setting ESDHC_TUNE_CTRL_STD_TUNING_EN bit in new register ESDHC_TUNE_CTRL and operates with new tuning bits defined in SDHCI_ACMD12_ERR register. Note: mx6sl can also work on the old manually tuning mode as mx6q/dl if not enable standard tuning mode. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: create struct esdhc_soc_dataShawn Guo
Create a struct esdhc_soc_data with moving 'flags' field from pltfm_imx_data into it, and pass the pointer of this SoC specific data structure through of_device_id.data directly, so that the translation from enum imx_esdhc_type to flags can be saved. With the change, enum imx_esdhc_type can be eliminated, since we can implement the is_imx*_esdhc() by checking the esdhc_soc_data pointer. The unused is_imx35_esdhc() and is_imx51_esdhc() are also removed, and the others are kept there as we will need to use them to handle some small register differences later, where use of new flags might be a little overkilled. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Dong Aisheng <b29396@freescale.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: pdev->id_entry should be immutableShawn Guo
As a good practice, device driver should not modify pdev->id_entry but keep it immutable. Let's assign of_device_id.data with imx_esdhc_type constants directly, so that we do not have to manipulate pdev->id_entry in .probe(). As the result, sdhci-esdhc-imx53 and sdhci-usdhc-imx6q can be removed from platform_device_id table now, since they will only probe from device tree. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Dong Aisheng <b29396@freescale.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: add flag ESDHC_FLAG_USDHCShawn Guo
Add flag ESDHC_FLAG_USDHC to tell that the ESDHC is actually an USDHC block, and replace the is_imx6q_usdhc() occurrences with inline function esdhc_is_usdhc() which checks the flag. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Dong Aisheng <b29396@freescale.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-10-21mmc: sdhci-esdhc-imx: add flag ESDHC_FLAG_ENGCM07207Shawn Guo
Just like the use of the flag ESDHC_FLAG_MULTIBLK_NO_INT, let's add another flag ESDHC_FLAG_ENGCM07207 to enable the workaround for errata ENGcm07207 and set the flag for i.MX25 and i.MX35 ESDHC. While at it, let's use BIT() macro for ESDHC_FLAG_MULTIBLK_NO_INT as well. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Dong Aisheng <b29396@freescale.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-09-27mmc: sdhci-esdhc-imx: set actual_clock in clock settingDong Aisheng
This enables access the actual_clock via sys. root@imx6qsabreauto:~# cat /sys/kernel/debug/mmc0/ios clock: 198000000 Hz actual clock: 198000000 Hz vdd: 17 (2.9 ~ 3.0 V) bus mode: 2 (push-pull) chip select: 0 (don't care) power mode: 2 (on) bus width: 2 (4 bits) timing spec: 6 (sd uhs SDR104) signal voltage: 0 (1.80 V) Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-09-26mmc: sdhci-esdhc-imx: correct pre_div for imx6qDong Aisheng
According to spec, the pre_div for imx6q should be 1, or the biggest clock rate we can get is a half of host clock rate. This may cause we can not get the proper clock rate as we want. e.g. if the desired clock is 200Mhz, however, the host clock is 200Mhz too, then it causes the actual clock we get is 100Mhz due to pre_div is 2. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-09-26mmc: sdhci-esdhc-imx: change pinctrl state according to uhs modeDong Aisheng
Without proper pinctrl state, the card may not be able to work on high speed stablely. e.g. SDR104. This patch add pinctrl state switch code according to different uhs mode include 100mhz sate, 200mhz sate and normal state (50Mhz and below). Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-09-26mmc: sdhci-esdhc-imx: add sd3.0 SDR clock tuning supportDong Aisheng
Freescale i.MX6Q/DL uSDHC clock tuning progress is a little different from the standard tuning process defined in host controller spec v3.0. Thus we use platform_execute_tuning instead of standard sdhci tuning. The main difference are: 1) not only generate Buffer Read Ready interrupt when tuning is performing. It generates all other DATA interrupts like the normal data command. 2) SDHCI_CTRL_EXEC_TUNING is not automatically cleared by HW, instead it's controlled by SW. 3) SDHCI_CTRL_TUNED_CLK is not automatically set by HW, it's controlled by SW. 4) the clock delay for every tuning is set by SW. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-09-26mmc: sdhci-esdhc-imx: support real clock on and off for imx6qDong Aisheng
The signal voltage switch flow requires to shutdown and output clock in a specific sequence according to standard host controller v3.0 spec. In that timing, the card must really receive clock or not. However, for i.MX6Q, the uSDHC will not output clock even the clock is enabled until there is command or data in transfer on the bus, which will then cause singal voltage switch always to fail. For i.MX6Q, we clear ESDHC_VENDOR_SPEC_FRC_SDCLK_ON bit to let controller to gate off clock automatically and set that bit to force clock output if clock is on. This is required by SD3.0 support. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-09-26mmc: sdhci-esdhc: move common esdhc_set_clock to platform driverDong Aisheng
We need a lot of imx6 specific things into common esdhc_set_clock for support SD3.0 and eMMC DDR mode which is not needed for power pc platforms, so esdhc_set_clock seems not so common anymore. Instead of keeping add platform specfics things into this common API, we choose to move that code into platform driver itself to handle. This can also exclude the dependency between imx and power pc on this headfile and is easy for maintain in the future. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-08-24mmc: slot-gpio: Add debouncing capability to mmc_gpio_request_cd()Laurent Pinchart
Add a debounce parameter to the mmc_gpio_request_cd() function that enables GPIO debouncing when set to a non-zero value. This can be used by MMC host drivers to enable debouncing on the card detect signal. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-06-27mmc: esdhc-imx: parse max-frequency from devicetreeLucas Stach
In order to make it possible to reduce the SD bus frequency, parse the optional "max-frequency" attribute as documented in devicetree/bindings/mmc/mmc.txt Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-06-27mmc: sdhci-esdhc: calculate sdclk divider from controller clockLucas Stach
The SDCLK is divided down from the host controller clock. Host controller clock may be different from the maximum SDCLK, so get it from the platform, instead of just using the max SDCLK. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-05-31mmc: sdhci: Add size for caller in init+registerChristian Daudt
Add a param to allow users of sdhci_pltfm to allocate private space in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented in the same way as sdhci does for its users. None of the users have been migrated yet and are passing in zero to retain their private allocation. - todo: migrate clients to using allocation this way - todo: remove priv variable once migration is complete Also removed unused variable in sdhci_pltfm_init fn Signed-off-by: Christian Daudt <csd@broadcom.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-05-26mmc: sdhci-esdhc-imx: fix multiblock reads on i.MX53Lucas Stach
The eSDHC controller on the i.MX53 needs an additional, non spec compliant CMD12 after a multiblock read with a predefined number of blocks. Otherwise the internal state machine won't go back to the idle state. This commit effectively reverts 5b6b0ad6 (mmc: sdhci-esdhc-imx: fix for mmc cards on i.MX5), which fixed part of the problem by making multiblock reads work, however this fix was not sufficient when multi- and singleblock reads got intermixed. This implements the recommended workaround (Freescale i.MX Reference Manual, section 29.6.8 "Multi-block Read") by manually sending a CMD12 with the RSPTYP bits cleared. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-05-26mmc: sdhci-esdhc-imx: Fix SDIO interruptsMartin Fuzzey
Currently SDIO interrupts do not work on i.MX53 and maybe others. This was observed with a Marvell 8787 based SDIO wifi adapter using the mwifiex driver and firmware from the Marvell git repository. The symptom was a timeout after firmware download. Observing the SDIO_DAT1 line showed that an interrupt was requested (level 0) but no interrupt was generated in software, the line stayed low until a timeout ocurred and the card was reset. There is a Freescale errata ENGcm11186 "eSDHC misses SDIO interrupt when CINT is disabled" The workaround suggested by this errata is already implemented and involves clearing and then setting the D3CD bit in the host control register [see esdhc_writel_le()] However, when esdhc_writeb_le() is later used to write to SDHCI_HOST_CONTROL it always resets the D3CD bit. To fix this simply add the D3CD bit to the set of bits not modified by esdhc_writeb_le(). Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-03-22mmc: sdhci: Constify sdhci_ops structs where possibleLars-Peter Clausen
Basically all drivers can have sdhci_ops struct const, but almost none do. This patch constifies all sdhci_ops struct declarations where possible. The patch was auto-generated with the following coccinelle semantic patch: // <smpl> @r1@ identifier ops; identifier fld; @@ ops.fld = ...; @disable optional_qualifier@ identifier ops != r1.ops; @@ static +const struct sdhci_ops ops = { ... }; // </smpl> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-03-22mmc: sdhci_pltfm: Constify sdhci_pltfm_dataLars-Peter Clausen
The sdhci_pltfm_data struct is never modified within the sdhci_pltfm module. So make the pdata parameter to sdhci_pltfm_init and sdhci_pltfm_register const. This allows drivers to declare their sdhci_pltfm_data struct as const. This patch also makes the sdhci_pltfm_data declarations const where possible. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-02-24mmc: sdhci-pltfm: Add a common clk API implementation of get_timeout_clockLars-Peter Clausen
Quite a few drivers have a implementation of the get_timeout_clock callback which simply returns the result of clk_get_rate on the device's clock. This patch adds a common implementation of this to the sdhci-pltfm module and replaces all custom implementations with the common one. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Tested-by: Stephen Warren <swarren@wwwdotorg.org> Acked-by: Shawn Guo <shawn.guo@linaro.org> Tested-by: Kevin Liu <kliu5@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-02-24mmc: sdhci-esdhc-imx: support 8bit modeSascha Hauer
The i.MX esdhc has a nonstandard bit layout for the SDHCI_HOST_CONTROL register. To support 8bit bus width on i.MX populate the platform_bus_width callback. This is tested on an i.MX25, but should according to the datasheets work on the other i.MX using this hardware aswell. The i.MX6, while having a SDHCI_SPEC_300 controller, still uses the same nonstandard register layout. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Chris Ball <cjb@laptop.org>
2013-02-24mmc: sdhci-esdhc-imx: Auto CMD23 support for usdhcShawn Guo
SDHCI core will try to use Auto CMD23 for mmc card. Currently, we will see the following message with mmc card on usdhc due to the lacking of Auto CMD23 support in the driver. $ mmc0: new high speed MMC card at address 0001 mmcblk1: mmc0:0001 MMC02G 1.87 GiB mmcblk1: error -84 transferring data, sector 0, nr 8, cmd response 0x900, card status 0xb00 mmcblk1: retrying using single block read mmcblk1: Enable Auto CMD23 support for usdhc so that mmc card can work in multiple block mode. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Chris Ball <cjb@laptop.org>