mmc: tmio_mmc: handle missing HW interrupts
When doing excessive hotplug, e.g., repeated insert/eject operations,
the hardware may get confused to a point where no CMDTIMEOUT/CMDRESPEND
interrupts are generated any more. As a result requests get stuck, e.g.:
[ 360.351562] INFO: task kworker/u:0:5 blocked for more than 120 seconds.
[ 360.351562] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 360.359375] kworker/u:0 D
c020c2b4 0 5 2 0x00000000
[ 360.367187] Backtrace:
[ 360.367187] [<
c020bfb0>] (schedule+0x0/0x340) from [<
c020c480>] (schedule_timeout+0x20/0x190)
[ 360.375000] r8:
c702fd70 r7:
00000002 r6:
c702e000 r5:
c702fdc4 r4:
7fffffff
[ 360.375000] r3:
c701e040
[ 360.382812] [<
c020c460>] (schedule_timeout+0x0/0x190) from [<
c020be78>] (wait_for_common+0xc4/0x150)
[ 360.390625] r6:
c702e000 r5:
c702fdc4 r4:
7fffffff
[ 360.390625] [<
c020bdb4>] (wait_for_common+0x0/0x150) from [<
c020bfac>] (wait_for_completion+0x18/0x1c)
[ 360.398437] [<
c020bf94>] (wait_for_completion+0x0/0x1c) from [<
c0185590>] (mmc_wait_for_req+0x214/0x234)
[ 360.406250] [<
c018537c>] (mmc_wait_for_req+0x0/0x234) from [<
c01889d0>] (mmc_sd_switch+0xfc/0x114)
[ 360.414062] r7:
c702fe4c r6:
c702fe20 r5:
c7179800 r4:
00fffff0
[ 360.421875] [<
c01888d4>] (mmc_sd_switch+0x0/0x114) from [<
c0187f70>] (mmc_sd_setup_card+0x260/0x384)
[ 360.429687] [<
c0187d10>] (mmc_sd_setup_card+0x0/0x384) from [<
c01885e0>] (mmc_sd_init_card+0x13c/0x1e0)
[ 360.437500] [<
c01884a4>] (mmc_sd_init_card+0x0/0x1e0) from [<
c01887a8>] (mmc_attach_sd+0x124/0x1a8)
[ 360.445312] r8:
c02db404 r7:
ffffff92 r6:
c702ff34 r5:
c6007da8 r4:
c6007c00
[ 360.453125] [<
c0188684>] (mmc_attach_sd+0x0/0x1a8) from [<
c0185140>] (mmc_rescan+0x248/0x2f0)
[ 360.460937] r5:
c6007da8 r4:
c6007c00
[ 360.468750] [<
c0184ef8>] (mmc_rescan+0x0/0x2f0) from [<
c00467f0>] (process_one_work+0x1ec/0x318)
[ 360.476562] r7:
c6007da8 r6:
00000000 r5:
c710ec00 r4:
c701bde0
[ 360.484375] [<
c0046604>] (process_one_work+0x0/0x318) from [<
c0047fb0>] (worker_thread+0x1b0/0x2cc)
[ 360.492187] [<
c0047e00>] (worker_thread+0x0/0x2cc) from [<
c004b338>] (kthread+0x8c/0x94)
[ 360.500000] [<
c004b2ac>] (kthread+0x0/0x94) from [<
c0037fc4>] (do_exit+0x0/0x590)
[ 360.507812] r7:
00000013 r6:
c0037fc4 r5:
c004b2ac r4:
c7021f00
This patch addresses this problem by introducing timeouts for outstanding
interrupts. If a hardware interrupt is missing, a soft reset will be
performed to bring the hardware back to a working state.
Tested with the SDHI hardware block in sh7372 / AP4EVB.
Signed-off-by: Arnd Hannemann <arnd@arndnet.de>
Signed-off-by: Chris Ball <cjb@laptop.org>