All of lore.kernel.org
 help / color / mirror / Atom feed
From: Doug Anderson <dianders@chromium.org>
To: Chris Ball <cjb@laptop.org>
Cc: Olof Johansson <olof@lixom.net>,
	Jaehoon Chung <jh80.chung@samsung.com>,
	Seungwon Jeon <tgih.jun@samsung.com>,
	James Hogan <james.hogan@imgtec.com>,
	Grant Grundler <grundler@chromium.org>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Abhilash Kesavan <a.kesavan@samsung.com>,
	Tomasz Figa <tomasz.figa@gmail.com>,
	Doug Anderson <dianders@chromium.org>,
	Kukjin Kim <kgene.kim@samsung.com>,
	linux-mmc@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v4 2/4] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT
Date: Tue,  6 Aug 2013 14:37:49 -0700	[thread overview]
Message-ID: <1375825071-20922-3-git-send-email-dianders@chromium.org> (raw)
In-Reply-To: <1375825071-20922-1-git-send-email-dianders@chromium.org>

If the WAKEUP_INT is asserted at wakeup and not cleared, we'll end up
looping around forever.  This has been seen to happen on exynos5420
silicon despite the fact that we haven't enabled any wakeup events due
to a silicon errata.  It is safe to do on all exynos variants.

Signed-off-by: Doug Anderson <dianders@chromium.org>
---
Changes in v4:
- Take Seungwon's suggestion and don't add any dw_mmc-pltfm code.

Changes in v3:
- Add freeze/thaw and poweroff/restore noirq entries.

Changes in v2:
- Use suspend_noirq as per James Hogan.

 drivers/mmc/host/dw_mmc-exynos.c | 51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 866edef..0c1f192 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -30,6 +30,7 @@
 #define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
 					SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
 					SDMMC_CLKSEL_CCLK_DIVIDER(z))
+#define SDMMC_CLKSEL_WAKEUP_INT		BIT(11)
 
 #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
 #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
@@ -100,6 +101,30 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
 	return 0;
 }
 
+/**
+ * dw_mci_exynos_resume_noirq - Exynos-specific resume code
+ *
+ * On exynos5420 there is a silicon errata that will sometimes leave the
+ * WAKEUP_INT bit in the CLKSEL register asserted.  This bit is 1 to indicate
+ * that it fired and we can clear it by writing a 1 back.  Clear it to prevent
+ * interrupts from going off constantly.
+ *
+ * We run this code on all exynos variants because it doesn't hurt and the bug
+ * may be more widespread than just exynos5420.
+ */
+
+static int dw_mci_exynos_resume_noirq(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+	u32 clksel;
+
+	clksel = mci_readl(host, CLKSEL);
+	if (clksel & SDMMC_CLKSEL_WAKEUP_INT)
+		mci_writel(host, CLKSEL, clksel);
+
+	return 0;
+}
+
 static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	/*
@@ -187,17 +212,39 @@ static int dw_mci_exynos_probe(struct platform_device *pdev)
 	return dw_mci_pltfm_register(pdev, drv_data);
 }
 
+static struct dev_pm_ops dw_mci_exynos_pmops;
+
 static struct platform_driver dw_mci_exynos_pltfm_driver = {
 	.probe		= dw_mci_exynos_probe,
 	.remove		= __exit_p(dw_mci_pltfm_remove),
 	.driver		= {
 		.name		= "dwmmc_exynos",
 		.of_match_table	= dw_mci_exynos_match,
-		.pm		= &dw_mci_pltfm_pmops,
+		.pm		= &dw_mci_exynos_pmops,
 	},
 };
 
-module_platform_driver(dw_mci_exynos_pltfm_driver);
+static int __init dw_mci_exynos_init(void)
+{
+	/* Add a "noirq" resume to platform pmops */
+	memcpy(&dw_mci_exynos_pmops, &dw_mci_pltfm_pmops,
+	       sizeof(dw_mci_exynos_pmops));
+	WARN_ON(dw_mci_exynos_pmops.resume_noirq ||
+		dw_mci_exynos_pmops.thaw_noirq ||
+		dw_mci_exynos_pmops.restore_noirq);
+	dw_mci_exynos_pmops.resume_noirq = dw_mci_exynos_resume_noirq;
+	dw_mci_exynos_pmops.thaw_noirq = dw_mci_exynos_resume_noirq;
+	dw_mci_exynos_pmops.restore_noirq = dw_mci_exynos_resume_noirq;
+
+	return platform_driver_register(&dw_mci_exynos_pltfm_driver);
+}
+module_init(dw_mci_exynos_init);
+
+static void __exit dw_mci_exynos_exit(void)
+{
+	platform_driver_unregister(&dw_mci_exynos_pltfm_driver);
+}
+module_exit(dw_mci_exynos_exit);
 
 MODULE_DESCRIPTION("Samsung Specific DW-MSHC Driver Extension");
 MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com");
-- 
1.8.3


WARNING: multiple messages have this Message-ID (diff)
From: dianders@chromium.org (Doug Anderson)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 2/4] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT
Date: Tue,  6 Aug 2013 14:37:49 -0700	[thread overview]
Message-ID: <1375825071-20922-3-git-send-email-dianders@chromium.org> (raw)
In-Reply-To: <1375825071-20922-1-git-send-email-dianders@chromium.org>

If the WAKEUP_INT is asserted at wakeup and not cleared, we'll end up
looping around forever.  This has been seen to happen on exynos5420
silicon despite the fact that we haven't enabled any wakeup events due
to a silicon errata.  It is safe to do on all exynos variants.

Signed-off-by: Doug Anderson <dianders@chromium.org>
---
Changes in v4:
- Take Seungwon's suggestion and don't add any dw_mmc-pltfm code.

Changes in v3:
- Add freeze/thaw and poweroff/restore noirq entries.

Changes in v2:
- Use suspend_noirq as per James Hogan.

 drivers/mmc/host/dw_mmc-exynos.c | 51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 866edef..0c1f192 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -30,6 +30,7 @@
 #define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
 					SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
 					SDMMC_CLKSEL_CCLK_DIVIDER(z))
+#define SDMMC_CLKSEL_WAKEUP_INT		BIT(11)
 
 #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
 #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
@@ -100,6 +101,30 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
 	return 0;
 }
 
+/**
+ * dw_mci_exynos_resume_noirq - Exynos-specific resume code
+ *
+ * On exynos5420 there is a silicon errata that will sometimes leave the
+ * WAKEUP_INT bit in the CLKSEL register asserted.  This bit is 1 to indicate
+ * that it fired and we can clear it by writing a 1 back.  Clear it to prevent
+ * interrupts from going off constantly.
+ *
+ * We run this code on all exynos variants because it doesn't hurt and the bug
+ * may be more widespread than just exynos5420.
+ */
+
+static int dw_mci_exynos_resume_noirq(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+	u32 clksel;
+
+	clksel = mci_readl(host, CLKSEL);
+	if (clksel & SDMMC_CLKSEL_WAKEUP_INT)
+		mci_writel(host, CLKSEL, clksel);
+
+	return 0;
+}
+
 static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	/*
@@ -187,17 +212,39 @@ static int dw_mci_exynos_probe(struct platform_device *pdev)
 	return dw_mci_pltfm_register(pdev, drv_data);
 }
 
+static struct dev_pm_ops dw_mci_exynos_pmops;
+
 static struct platform_driver dw_mci_exynos_pltfm_driver = {
 	.probe		= dw_mci_exynos_probe,
 	.remove		= __exit_p(dw_mci_pltfm_remove),
 	.driver		= {
 		.name		= "dwmmc_exynos",
 		.of_match_table	= dw_mci_exynos_match,
-		.pm		= &dw_mci_pltfm_pmops,
+		.pm		= &dw_mci_exynos_pmops,
 	},
 };
 
-module_platform_driver(dw_mci_exynos_pltfm_driver);
+static int __init dw_mci_exynos_init(void)
+{
+	/* Add a "noirq" resume to platform pmops */
+	memcpy(&dw_mci_exynos_pmops, &dw_mci_pltfm_pmops,
+	       sizeof(dw_mci_exynos_pmops));
+	WARN_ON(dw_mci_exynos_pmops.resume_noirq ||
+		dw_mci_exynos_pmops.thaw_noirq ||
+		dw_mci_exynos_pmops.restore_noirq);
+	dw_mci_exynos_pmops.resume_noirq = dw_mci_exynos_resume_noirq;
+	dw_mci_exynos_pmops.thaw_noirq = dw_mci_exynos_resume_noirq;
+	dw_mci_exynos_pmops.restore_noirq = dw_mci_exynos_resume_noirq;
+
+	return platform_driver_register(&dw_mci_exynos_pltfm_driver);
+}
+module_init(dw_mci_exynos_init);
+
+static void __exit dw_mci_exynos_exit(void)
+{
+	platform_driver_unregister(&dw_mci_exynos_pltfm_driver);
+}
+module_exit(dw_mci_exynos_exit);
 
 MODULE_DESCRIPTION("Samsung Specific DW-MSHC Driver Extension");
 MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com");
-- 
1.8.3

  parent reply	other threads:[~2013-08-06 21:44 UTC|newest]

Thread overview: 105+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-09 17:31 [PATCH 0/5] mmc: dw_mmc: fixes for suspend/resume on exynos Doug Anderson
2013-07-09 17:31 ` Doug Anderson
2013-07-09 17:31 ` [PATCH 1/5] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume Doug Anderson
2013-07-09 17:31 ` [PATCH 2/5] mmc: dw_mmc: Add suspend/resume callbacks; disable irq during suspend Doug Anderson
2013-07-09 21:17   ` James Hogan
2013-07-09 21:31     ` Doug Anderson
2013-07-09 17:31 ` [PATCH 3/5] mmc: dw_mmc: Add exynos resume callback to clear WAKEUP_INT Doug Anderson
2013-07-09 17:31   ` Doug Anderson
2013-07-09 17:31   ` Doug Anderson
2013-07-09 19:09   ` Doug Anderson
2013-07-09 19:09     ` Doug Anderson
2013-07-09 19:09     ` Doug Anderson
2013-07-11  0:43     ` Grant Grundler
2013-07-11  0:43       ` Grant Grundler
2013-07-11  0:43       ` Grant Grundler
2013-07-09 17:31 ` [PATCH 4/5] mmc: dw_mmc: Always setup the bus after suspend/resume Doug Anderson
2013-07-09 17:31 ` [PATCH 5/5] mmc: dw_mmc: Set timeout to max upon resume Doug Anderson
2013-07-09 23:19 ` [PATCH v2 0/5] mmc: dw_mmc: fixes for suspend/resume on exynos Doug Anderson
2013-07-09 23:19   ` Doug Anderson
2013-07-09 23:19   ` [PATCH v2 1/5] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume Doug Anderson
2013-07-09 23:19   ` [PATCH v2 2/5] mmc: dw_mmc: Add suspend_noirq/resume_noirq callbacks for dw_mmc-pltfm Doug Anderson
2013-07-10  8:37     ` James Hogan
2013-07-10  8:37       ` James Hogan
2013-07-10 15:08       ` Doug Anderson
2013-07-09 23:19   ` [PATCH v2 3/5] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT Doug Anderson
2013-07-09 23:19     ` Doug Anderson
2013-07-10 14:54     ` Seungwon Jeon
2013-07-10 14:54       ` Seungwon Jeon
2013-07-10 15:05       ` Doug Anderson
2013-07-10 15:05         ` Doug Anderson
2013-07-10 15:05         ` Doug Anderson
2013-07-15 12:09         ` Seungwon Jeon
2013-07-15 12:09           ` Seungwon Jeon
2013-07-31 16:18           ` Doug Anderson
2013-07-31 16:18             ` Doug Anderson
2013-07-31 16:18             ` Doug Anderson
2013-08-06 21:36             ` Doug Anderson
2013-08-06 21:36               ` Doug Anderson
2013-08-06 21:36               ` Doug Anderson
2013-07-09 23:19   ` [PATCH v2 4/5] mmc: dw_mmc: Always setup the bus after suspend/resume Doug Anderson
2013-07-09 23:19   ` [PATCH v2 5/5] mmc: dw_mmc: Set timeout to max upon resume Doug Anderson
2013-07-10 14:54     ` Seungwon Jeon
2013-07-10 15:42   ` [PATCH v3 0/5] mmc: dw_mmc: fixes for suspend/resume on exynos Doug Anderson
2013-07-10 15:42     ` Doug Anderson
2013-07-10 15:42     ` [PATCH v3 1/5] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume Doug Anderson
2013-07-10 15:42     ` [PATCH v3 2/5] mmc: dw_mmc: Add suspend_noirq/resume_noirq callbacks for dw_mmc-pltfm Doug Anderson
2013-07-15 12:09       ` Seungwon Jeon
2013-08-06 21:32         ` Doug Anderson
2013-07-10 15:42     ` [PATCH v3 3/5] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT Doug Anderson
2013-07-10 15:42       ` Doug Anderson
2013-07-16  1:36       ` Jaehoon Chung
2013-07-16  1:36         ` Jaehoon Chung
2013-07-10 15:42     ` [PATCH v3 4/5] mmc: dw_mmc: Always setup the bus after suspend/resume Doug Anderson
2013-07-10 15:42     ` [PATCH v3 5/5] mmc: dw_mmc: Set timeout to max upon resume Doug Anderson
2013-08-06 21:37     ` [PATCH v4 0/4] mmc: dw_mmc: fixes for suspend/resume on exynos Doug Anderson
2013-08-06 21:37       ` Doug Anderson
2013-08-06 21:37       ` [PATCH v4 1/4] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume Doug Anderson
2013-08-06 21:58         ` Tomasz Figa
2013-08-08  5:14         ` Jaehoon Chung
2013-08-09 13:32         ` Seungwon Jeon
2013-08-09 15:22           ` Doug Anderson
2013-08-12  7:14             ` Seungwon Jeon
2013-08-22  0:54               ` Doug Anderson
2013-08-22 16:25                 ` Doug Anderson
2013-08-06 21:37       ` Doug Anderson [this message]
2013-08-06 21:37         ` [PATCH v4 2/4] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT Doug Anderson
2013-08-06 21:58         ` Tomasz Figa
2013-08-06 21:58           ` Tomasz Figa
2013-08-06 22:09           ` Doug Anderson
2013-08-06 22:09             ` Doug Anderson
2013-08-06 22:09             ` Doug Anderson
2013-08-06 22:20             ` Tomasz Figa
2013-08-06 22:20               ` Tomasz Figa
2013-08-06 22:20               ` Tomasz Figa
2013-08-09 13:33         ` Seungwon Jeon
2013-08-09 13:33           ` Seungwon Jeon
2013-08-09 15:05           ` Doug Anderson
2013-08-09 15:05             ` Doug Anderson
2013-08-09 15:05             ` Doug Anderson
2013-08-06 21:37       ` [PATCH v4 3/4] mmc: dw_mmc: Always setup the bus after suspend/resume Doug Anderson
2013-08-06 22:01         ` Tomasz Figa
2013-08-09 13:35         ` Seungwon Jeon
2013-08-09 15:43           ` Doug Anderson
2013-08-12  7:20             ` Seungwon Jeon
2013-08-06 21:37       ` [PATCH v4 4/4] mmc: dw_mmc: Set timeout to max upon resume Doug Anderson
2013-08-06 22:02         ` Tomasz Figa
2013-08-09 16:33       ` [PATCH v5 0/4] mmc: dw_mmc: fixes for suspend/resume on exynos Doug Anderson
2013-08-09 16:33         ` Doug Anderson
2013-08-09 16:33         ` [PATCH v5 1/4] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume Doug Anderson
2013-08-09 16:33         ` [PATCH v5 2/4] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT Doug Anderson
2013-08-09 16:33           ` Doug Anderson
2013-08-09 16:41           ` Fabio Estevam
2013-08-09 16:41             ` Fabio Estevam
2013-08-09 16:48             ` Doug Anderson
2013-08-09 16:48               ` Doug Anderson
2013-08-09 16:48               ` Doug Anderson
2013-08-12  7:21           ` Seungwon Jeon
2013-08-12  7:21             ` Seungwon Jeon
2013-08-09 16:33         ` [PATCH v5 3/4] mmc: dw_mmc: Always setup the bus after suspend/resume Doug Anderson
2013-08-09 16:33         ` [PATCH v5 4/4] mmc: dw_mmc: Set timeout to max upon resume Doug Anderson
2013-08-21 11:48         ` [PATCH v5 0/4] mmc: dw_mmc: fixes for suspend/resume on exynos Seungwon Jeon
2013-08-21 11:48           ` Seungwon Jeon
2013-08-21 15:13           ` Doug Anderson
2013-08-21 15:13             ` Doug Anderson
2013-08-21 15:13             ` Doug Anderson

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=1375825071-20922-3-git-send-email-dianders@chromium.org \
    --to=dianders@chromium.org \
    --cc=a.kesavan@samsung.com \
    --cc=alim.akhtar@samsung.com \
    --cc=cjb@laptop.org \
    --cc=grundler@chromium.org \
    --cc=james.hogan@imgtec.com \
    --cc=jh80.chung@samsung.com \
    --cc=kgene.kim@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=olof@lixom.net \
    --cc=tgih.jun@samsung.com \
    --cc=tomasz.figa@gmail.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: link
Be 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.