diff options
author | Subhash Jadavani <subhashj@codeaurora.org> | 2013-05-14 17:46:43 +0530 |
---|---|---|
committer | Subhash Jadavani <subhashj@codeaurora.org> | 2016-05-27 10:28:39 -0700 |
commit | cecd05aeb2f39469e505a61235a9e566f1a32a42 (patch) | |
tree | d6b4fec5f3dbfb92bf31113501b62adb8437d9f7 | |
parent | f957bdbd793ed262bf43a2a3059ff75f17b89c83 (diff) |
mmc: sdhci-msm: fix issue with power irq
SDCC controller reset (SW_RST) during probe may trigger power irq if
previous status of PWRCTL was either BUS_ON or IO_HIGH_V. So before we
enable the power irq interrupt in GIC (by registering the interrupt
handler), we need to ensure that any pending power irq interrupt status
is acknowledged otherwise power irq interrupt handler would be fired
prematurely.
CRs-Fixed: 487962
Change-Id: If4693869210bc8b361dadb2b68a47b6ac8707e0f
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
-rw-r--r-- | drivers/mmc/host/sdhci-msm.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index ea8614707ca5..11ecd98fcbb1 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2050,7 +2050,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) struct resource *core_memres = NULL; int ret = 0, pwr_irq = 0, dead = 0; u16 host_version; - u32 pwr; + u32 pwr, irq_status, irq_ctl; pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__); msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host), @@ -2178,6 +2178,27 @@ static int sdhci_msm_probe(struct platform_device *pdev) writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE)); /* + * CORE_SW_RST above may trigger power irq if previous status of PWRCTL + * was either BUS_ON or IO_HIGH_V. So before we enable the power irq + * interrupt in GIC (by registering the interrupt handler), we need to + * ensure that any pending power irq interrupt status is acknowledged + * otherwise power irq interrupt handler would be fired prematurely. + */ + irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); + writel_relaxed(irq_status, (msm_host->core_mem + CORE_PWRCTL_CLEAR)); + irq_ctl = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL); + if (irq_status & (CORE_PWRCTL_BUS_ON | CORE_PWRCTL_BUS_OFF)) + irq_ctl |= CORE_PWRCTL_BUS_SUCCESS; + if (irq_status & (CORE_PWRCTL_IO_HIGH | CORE_PWRCTL_IO_LOW)) + irq_ctl |= CORE_PWRCTL_IO_SUCCESS; + writel_relaxed(irq_ctl, (msm_host->core_mem + CORE_PWRCTL_CTL)); + /* + * Ensure that above writes are propogated before interrupt enablement + * in GIC. + */ + mb(); + + /* * Following are the deviations from SDHC spec v3.0 - * 1. Card detection is handled using separate GPIO. * 2. Bus power control is handled by interacting with PMIC. |