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>
This commit is contained in:
Subhash Jadavani 2013-05-14 17:46:43 +05:30
parent f957bdbd79
commit cecd05aeb2

View file

@ -2050,7 +2050,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
struct resource *core_memres = NULL; struct resource *core_memres = NULL;
int ret = 0, pwr_irq = 0, dead = 0; int ret = 0, pwr_irq = 0, dead = 0;
u16 host_version; u16 host_version;
u32 pwr; u32 pwr, irq_status, irq_ctl;
pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__); pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__);
msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host), msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host),
@ -2177,6 +2177,27 @@ static int sdhci_msm_probe(struct platform_device *pdev)
/* Set HC_MODE_EN bit in HC_MODE register */ /* Set HC_MODE_EN bit in HC_MODE register */
writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE)); 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 - * Following are the deviations from SDHC spec v3.0 -
* 1. Card detection is handled using separate GPIO. * 1. Card detection is handled using separate GPIO.