summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2013-05-14 17:46:43 +0530
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-27 10:28:39 -0700
commitcecd05aeb2f39469e505a61235a9e566f1a32a42 (patch)
treed6b4fec5f3dbfb92bf31113501b62adb8437d9f7 /drivers/mmc
parentf957bdbd793ed262bf43a2a3059ff75f17b89c83 (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>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-msm.c23
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.