Re: [PATCH] mmc: clear all interrupt in suspend before free_irq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 21, 2011 at 2:33 PM, Nicolas Pitre <nico@xxxxxxxxxxx> wrote:
> On Fri, 21 Jan 2011, zhangfei gao wrote:
>
>> >From b7be39e0bbac3950057078ac66900ebc0871f77e Mon Sep 17 00:00:00 2001
>> From: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
>> Date: Fri, 21 Jan 2011 18:02:47 -0500
>> Subject: [PATCH] mmc: clear all interrupt in suspend before free_irq
>>
>>       When debugging wifi host sleep, race condition about
>> SDHCI_INT_CARD_INT happens.
>>       Host free_irq in suspend and request_irq when resume back.
>>       However SDHCI_INT_CARD_INT is not cleared, so interrupt will
>> immediately happen after request_irq.
>>       mmc_signal_sdio_irq will be called and wakeup sdio_irq_thread.
>>       As a result irq_handler in sdio driver is called even before host resume back.
>>
>>       The correct case is mmc_sdio_resume calls mmc_signal_sdio_irq to
>> wakeup sdio_irq_thread
>>
>> Signed-off-by: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
>
> That makes sense, as long as the masking of interrupts doesn't prevent
> a SDIO card interrupt from waking up the host system.
>
Hi, Nicolas

Thanks for suggestion, we found some controller will actively call
sdhci_suspend_host, while CPU still keep in active state, so wakeup
source will not workable at such state, and CPU still rely on
interrupt to wake up.
Interrupt may not be freed in future to support this case.
So directly skip mmc_signal_sdio_irq in suspend state, do you think this is OK.

Subject: [PATCH] mmc: skip mmc_signal_sdio_irq in irq handler when resume back

	When debugging wifi host sleep, race condition about
SDHCI_INT_CARD_INT happens.
	Host free_irq in suspend and request_irq when resume back.
	However SDHCI_INT_CARD_INT is not cleared, so interrupt will
immediately happen after request_irq.
	mmc_signal_sdio_irq will be called and wakeup sdio_irq_thread.
	As a result irq_handler in sdio driver is called even before host resume back.

	So skip mmc_signal_sdio_irq in irq handler when resume back.
	And mmc_sdio_resume calls mmc_signal_sdio_irq to wakeup sdio_irq_thread

Signed-off-by: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
---
 drivers/mmc/host/sdhci.c  |   10 ++++++++--
 include/linux/mmc/sdhci.h |    1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index aacd78c..a813b8b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1684,8 +1684,12 @@ out:
 	/*
 	 * We have to delay this as it calls back into the driver.
 	 */
-	if (cardint)
-		mmc_signal_sdio_irq(host->mmc);
+	if (cardint) {
+		if(host->suspended)
+			sdhci_enable_sdio_irq(host->mmc, 0);
+		else
+			mmc_signal_sdio_irq(host->mmc);
+	}

 	return result;
 }
@@ -1709,6 +1713,7 @@ int sdhci_suspend_host(struct sdhci_host *host,
pm_message_t state)
 		return ret;

 	free_irq(host->irq, host);
+	host->suspended = true;

 	if (host->vmmc)
 		ret = regulator_disable(host->vmmc);
@@ -1742,6 +1747,7 @@ int sdhci_resume_host(struct sdhci_host *host)
 	sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
 	mmiowb();

+	host->suspended = false;
 	ret = mmc_resume_host(host->mmc);
 	sdhci_enable_card_detection(host);

diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 83bd9f7..764666a 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -140,6 +140,7 @@ struct sdhci_host {
 	struct timer_list timer;	/* Timer for timeouts */

 	unsigned int caps;	/* Alternative capabilities */
+	bool suspended;

 	unsigned int            ocr_avail_sdio;	/* OCR bit masks */
 	unsigned int            ocr_avail_sd;
-- 
1.7.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux