mmc: host: If clock gating is going-on treat card irq as async-irq.
In some scenarios, it is observed that mmc clock gate work is
racing with sdhci_host->clock flag in sdhci irq handler resulting
in unclocked register access.
Sequence of events:
1) Received an interrupt on one core.
2) This Interrupt is being handled in sdhci irq handler.
3) A schedule delayed work of clock gating is scheduled on other core
just after the reception of interrupt.
4) As a part of scheduled work,clocks are gated prior the completion
interrupt handling.
5) This results in unclocked register access during interrupt context.
Logs:
[22054.371299] LOGK_READL from address base+0h gic_cpu_if_up of
drivers/irqchip/irq-gic.c ==> Received Interrupt on core0.
[22054.371332] LOGK_READL from address base+30h sdhci_irq of
drivers/mmc/host/sdhci.h ==> Interrupt handler is invoked on core0.
[22054.371322] LOGK_READL from address base+30h sdhci_do_set_ios
of drivers/mmc/host/sdhci.h ==> clock gating work is in progress on
core2.
[22054.371333]LOGK_WRITEL from address base+ch sdhci_msm_set_clock
of drivers/mmc/host/sdhci-msm.c ==> clock gating is progress on core2.
[22054.371353] LOGK_READL from address base+1ch
branch_clk_halt_check of drivers/clk/msm/clock-local2.c ==> clock gating
is about to done on core2.
[22054.371353] LOGK_READL from address base+30h sdhci_irq Line of
drivers/mmc/host/sdhci.h ==> got unclocked register access error on core0.
Check for host->mmc->clk_gated too along with host->clock before handling
the interrupt further.
As of now, we are treating SDIO interrupt that got triggered when clocks
are completely turned off as an async-interrupt. This extra check ensures
that any SDIO interrupt that gets triggered while clocking gating is
progressing also as async-interrupt. So that we don't get into the
above-explained issue.
Change-Id: I6c2f516718a52a1ae95b59d75d26175ad230a303
Signed-off-by:
Pradeep P V K <ppvk@codeaurora.org>
Loading
Please register or sign in to comment