From: Vijay Viswanath <vviswana@codeaurora.org> To: adrian.hunter@intel.com, ulf.hansson@linaro.org, will.deacon@arm.com Cc: linux-arm-kernel@lists.infradead.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, asutoshd@codeaurora.org, stummala@codeaurora.org, riteshh@codeaurora.org, subhashj@codeaurora.org, Vijay Viswanath <vviswana@codeaurora.org> Subject: [PATCH 2/5] mmc: sdhci-msm: Fix HW issue with power IRQ handling during reset Date: Fri, 18 Aug 2017 10:49:39 +0530 [thread overview] Message-ID: <1503033582-48703-3-git-send-email-vviswana@codeaurora.org> (raw) In-Reply-To: <1503033582-48703-1-git-send-email-vviswana@codeaurora.org> From: Sahitya Tummala <stummala@codeaurora.org> There is a rare scenario in HW, where the first clear pulse could be lost when the actual reset and clear/read of status register are happening at the same time. Fix this by retrying upto 10 times to ensure the status register gets cleared. Otherwise, this will lead to a spurious power IRQ which results in system instability. Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org> --- drivers/mmc/host/sdhci-msm.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 0957199..f3e0489 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -995,17 +995,51 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, sdhci_msm_hs400(host, &mmc->ios); } -static void sdhci_msm_voltage_switch(struct sdhci_host *host) +static void sdhci_msm_dump_pwr_ctrl_regs(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); + + pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x\n", + mmc_hostname(host->mmc), + readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS), + readl_relaxed(msm_host->core_mem + CORE_PWRCTL_MASK), + readl_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL)); +} + +static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); u32 irq_status, irq_ack = 0; + int retry = 10; irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); irq_status &= INT_MASK; writel_relaxed(irq_status, msm_host->core_mem + CORE_PWRCTL_CLEAR); + /* + * There is a rare HW scenario where the first clear pulse could be + * lost when actual reset and clear/read of status register is + * happening at a time. Hence, retry for at least 10 times to make + * sure status register is cleared. Otherwise, this will result in + * a spurious power IRQ resulting in system instability. + */ + while (irq_status & readl_relaxed(msm_host->core_mem + + CORE_PWRCTL_STATUS)) { + if (retry == 0) { + pr_err("%s: Timedout clearing (0x%x) pwrctl status register\n", + mmc_hostname(host->mmc), irq_status); + sdhci_msm_dump_pwr_ctrl_regs(host); + WARN_ON(1); + } + writel_relaxed(irq_status, + msm_host->core_mem + CORE_PWRCTL_CLEAR); + retry--; + udelay(10); + } + if (irq_status & (CORE_PWRCTL_BUS_ON | CORE_PWRCTL_BUS_OFF)) irq_ack |= CORE_PWRCTL_BUS_SUCCESS; if (irq_status & (CORE_PWRCTL_IO_LOW | CORE_PWRCTL_IO_HIGH)) @@ -1017,13 +1051,17 @@ static void sdhci_msm_voltage_switch(struct sdhci_host *host) * switches are handled by the sdhci core, so just report success. */ writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); + + pr_debug("%s: %s: Handled IRQ(%d), irq_status=0x%x, ack=0x%x\n", + mmc_hostname(msm_host->mmc), __func__, irq, irq_status, + irq_ack); } static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) { struct sdhci_host *host = (struct sdhci_host *)data; - sdhci_msm_voltage_switch(host); + sdhci_msm_handle_pwr_irq(host, irq); return IRQ_HANDLED; } @@ -1106,7 +1144,6 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) .get_max_clock = sdhci_msm_get_max_clock, .set_bus_width = sdhci_set_bus_width, .set_uhs_signaling = sdhci_msm_set_uhs_signaling, - .voltage_switch = sdhci_msm_voltage_switch, }; static const struct sdhci_pltfm_data sdhci_msm_pdata = { -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
WARNING: multiple messages have this Message-ID (diff)
From: vviswana@codeaurora.org (Vijay Viswanath) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/5] mmc: sdhci-msm: Fix HW issue with power IRQ handling during reset Date: Fri, 18 Aug 2017 10:49:39 +0530 [thread overview] Message-ID: <1503033582-48703-3-git-send-email-vviswana@codeaurora.org> (raw) In-Reply-To: <1503033582-48703-1-git-send-email-vviswana@codeaurora.org> From: Sahitya Tummala <stummala@codeaurora.org> There is a rare scenario in HW, where the first clear pulse could be lost when the actual reset and clear/read of status register are happening at the same time. Fix this by retrying upto 10 times to ensure the status register gets cleared. Otherwise, this will lead to a spurious power IRQ which results in system instability. Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org> --- drivers/mmc/host/sdhci-msm.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 0957199..f3e0489 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -995,17 +995,51 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, sdhci_msm_hs400(host, &mmc->ios); } -static void sdhci_msm_voltage_switch(struct sdhci_host *host) +static void sdhci_msm_dump_pwr_ctrl_regs(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); + + pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x\n", + mmc_hostname(host->mmc), + readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS), + readl_relaxed(msm_host->core_mem + CORE_PWRCTL_MASK), + readl_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL)); +} + +static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); u32 irq_status, irq_ack = 0; + int retry = 10; irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); irq_status &= INT_MASK; writel_relaxed(irq_status, msm_host->core_mem + CORE_PWRCTL_CLEAR); + /* + * There is a rare HW scenario where the first clear pulse could be + * lost when actual reset and clear/read of status register is + * happening at a time. Hence, retry for at least 10 times to make + * sure status register is cleared. Otherwise, this will result in + * a spurious power IRQ resulting in system instability. + */ + while (irq_status & readl_relaxed(msm_host->core_mem + + CORE_PWRCTL_STATUS)) { + if (retry == 0) { + pr_err("%s: Timedout clearing (0x%x) pwrctl status register\n", + mmc_hostname(host->mmc), irq_status); + sdhci_msm_dump_pwr_ctrl_regs(host); + WARN_ON(1); + } + writel_relaxed(irq_status, + msm_host->core_mem + CORE_PWRCTL_CLEAR); + retry--; + udelay(10); + } + if (irq_status & (CORE_PWRCTL_BUS_ON | CORE_PWRCTL_BUS_OFF)) irq_ack |= CORE_PWRCTL_BUS_SUCCESS; if (irq_status & (CORE_PWRCTL_IO_LOW | CORE_PWRCTL_IO_HIGH)) @@ -1017,13 +1051,17 @@ static void sdhci_msm_voltage_switch(struct sdhci_host *host) * switches are handled by the sdhci core, so just report success. */ writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); + + pr_debug("%s: %s: Handled IRQ(%d), irq_status=0x%x, ack=0x%x\n", + mmc_hostname(msm_host->mmc), __func__, irq, irq_status, + irq_ack); } static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) { struct sdhci_host *host = (struct sdhci_host *)data; - sdhci_msm_voltage_switch(host); + sdhci_msm_handle_pwr_irq(host, irq); return IRQ_HANDLED; } @@ -1106,7 +1144,6 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) .get_max_clock = sdhci_msm_get_max_clock, .set_bus_width = sdhci_set_bus_width, .set_uhs_signaling = sdhci_msm_set_uhs_signaling, - .voltage_switch = sdhci_msm_voltage_switch, }; static const struct sdhci_pltfm_data sdhci_msm_pdata = { -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
next prev parent reply other threads:[~2017-08-18 5:19 UTC|newest] Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-08-18 5:19 [PATCH 0/5] mmc: sdhci-msm: Corrections to implementation of power irq Vijay Viswanath 2017-08-18 5:19 ` Vijay Viswanath 2017-08-18 5:19 ` [PATCH 1/5] mmc: sdhci-msm: fix issue with " Vijay Viswanath 2017-08-18 5:19 ` Vijay Viswanath 2017-08-24 7:40 ` Adrian Hunter 2017-08-24 7:40 ` Adrian Hunter 2017-08-28 12:33 ` Vijay Viswanath 2017-08-28 12:33 ` Vijay Viswanath 2017-08-18 5:19 ` Vijay Viswanath [this message] 2017-08-18 5:19 ` [PATCH 2/5] mmc: sdhci-msm: Fix HW issue with power IRQ handling during reset Vijay Viswanath 2017-08-24 7:42 ` Adrian Hunter 2017-08-24 7:42 ` Adrian Hunter 2017-08-28 12:34 ` Vijay Viswanath 2017-08-28 12:34 ` Vijay Viswanath 2017-08-18 5:19 ` [PATCH 3/5] mmc: sdhci-msm: Add support to wait for power irq Vijay Viswanath 2017-08-18 5:19 ` Vijay Viswanath 2017-08-24 10:05 ` Adrian Hunter 2017-08-24 10:05 ` Adrian Hunter 2017-08-28 12:34 ` Vijay Viswanath 2017-08-28 12:34 ` Vijay Viswanath 2017-08-18 5:19 ` [PATCH 4/5] mmc: sdhci-msm: Add ops to do sdhc register write Vijay Viswanath 2017-08-18 5:19 ` Vijay Viswanath 2017-08-24 10:11 ` Adrian Hunter 2017-08-24 10:11 ` Adrian Hunter 2017-08-28 12:35 ` Vijay Viswanath 2017-08-28 12:35 ` Vijay Viswanath 2017-08-18 5:19 ` [PATCH 5/5] defconfig: msm: Enable CONFIG_MMC_SDHCI_IO_ACCESSORS Vijay Viswanath 2017-08-18 5:19 ` Vijay Viswanath 2017-08-22 9:38 ` Ulf Hansson 2017-08-22 9:38 ` Ulf Hansson 2017-08-22 9:38 ` Ulf Hansson 2017-08-28 12:35 ` Vijay Viswanath 2017-08-28 12:35 ` Vijay Viswanath 2017-08-28 12:35 ` Vijay Viswanath 2017-08-22 9:40 ` [PATCH 0/5] mmc: sdhci-msm: Corrections to implementation of power irq Ulf Hansson 2017-08-22 9:40 ` Ulf Hansson 2017-08-22 9:40 ` Ulf Hansson
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1503033582-48703-3-git-send-email-vviswana@codeaurora.org \ --to=vviswana@codeaurora.org \ --cc=adrian.hunter@intel.com \ --cc=asutoshd@codeaurora.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-arm-msm@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mmc@vger.kernel.org \ --cc=riteshh@codeaurora.org \ --cc=stummala@codeaurora.org \ --cc=subhashj@codeaurora.org \ --cc=ulf.hansson@linaro.org \ --cc=will.deacon@arm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.