* [PATCH AUTOSEL 4.19 115/128] mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD
[not found] <20190922185418.2158-1-sashal@kernel.org>
@ 2019-09-22 18:54 ` Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 116/128] mmc: sdhci: Fix incorrect switch to HS mode Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-09-22 18:54 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ulf Hansson, Matthias Kaehlcke, Douglas Anderson, Sasha Levin,
linux-mmc
From: Ulf Hansson <ulf.hansson@linaro.org>
[ Upstream commit 36d57efb4af534dd6b442ea0b9a04aa6dfa37abe ]
The sdio_irq_pending flag is used to let host drivers indicate that it has
signaled an IRQ. If that is the case and we only have a single SDIO func
that have claimed an SDIO IRQ, our assumption is that we can avoid reading
the SDIO_CCCR_INTx register and just call the SDIO func irq handler
immediately. This makes sense, but the flag is set/cleared in a somewhat
messy order, let's fix that up according to below.
First, the flag is currently set in sdio_run_irqs(), which is executed as a
work that was scheduled from sdio_signal_irq(). To make it more implicit
that the host have signaled an IRQ, let's instead immediately set the flag
in sdio_signal_irq(). This also makes the behavior consistent with host
drivers that uses the legacy, mmc_signal_sdio_irq() API. This have no
functional impact, because we don't expect host drivers to call
sdio_signal_irq() until after the work (sdio_run_irqs()) have been executed
anyways.
Second, currently we never clears the flag when using the sdio_run_irqs()
work, but only when using the sdio_irq_thread(). Let make the behavior
consistent, by moving the flag to be cleared inside the common
process_sdio_pending_irqs() function. Additionally, tweak the behavior of
the flag slightly, by avoiding to clear it unless we processed the SDIO
IRQ. The purpose with this at this point, is to keep the information about
whether there have been an SDIO IRQ signaled by the host, so at system
resume we can decide to process it without reading the SDIO_CCCR_INTx
register.
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mmc/core/sdio_irq.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index b299a24d33f96..d206f2de80d23 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -35,6 +35,7 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
{
struct mmc_card *card = host->card;
int i, ret, count;
+ bool sdio_irq_pending = host->sdio_irq_pending;
unsigned char pending;
struct sdio_func *func;
@@ -42,13 +43,16 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
if (mmc_card_suspended(card))
return 0;
+ /* Clear the flag to indicate that we have processed the IRQ. */
+ host->sdio_irq_pending = false;
+
/*
* Optimization, if there is only 1 function interrupt registered
* and we know an IRQ was signaled then call irq handler directly.
* Otherwise do the full probe.
*/
func = card->sdio_single_irq;
- if (func && host->sdio_irq_pending) {
+ if (func && sdio_irq_pending) {
func->irq_handler(func);
return 1;
}
@@ -100,7 +104,6 @@ void sdio_run_irqs(struct mmc_host *host)
{
mmc_claim_host(host);
if (host->sdio_irqs) {
- host->sdio_irq_pending = true;
process_sdio_pending_irqs(host);
if (host->ops->ack_sdio_irq)
host->ops->ack_sdio_irq(host);
@@ -119,6 +122,7 @@ void sdio_irq_work(struct work_struct *work)
void sdio_signal_irq(struct mmc_host *host)
{
+ host->sdio_irq_pending = true;
queue_delayed_work(system_wq, &host->sdio_irq_work, 0);
}
EXPORT_SYMBOL_GPL(sdio_signal_irq);
@@ -164,7 +168,6 @@ static int sdio_irq_thread(void *_host)
if (ret)
break;
ret = process_sdio_pending_irqs(host);
- host->sdio_irq_pending = false;
mmc_release_host(host);
/*
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 4.19 116/128] mmc: sdhci: Fix incorrect switch to HS mode
[not found] <20190922185418.2158-1-sashal@kernel.org>
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 115/128] mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD Sasha Levin
@ 2019-09-22 18:54 ` Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 117/128] mmc: core: Add helper function to indicate if SDIO IRQs is enabled Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 118/128] mmc: dw_mmc: Re-store SDIO IRQs mask at system resume Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-09-22 18:54 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Al Cooper, Adrian Hunter, Ulf Hansson, Sasha Levin, linux-mmc
From: Al Cooper <alcooperx@gmail.com>
[ Upstream commit c894e33ddc1910e14d6f2a2016f60ab613fd8b37 ]
When switching from any MMC speed mode that requires 1.8v
(HS200, HS400 and HS400ES) to High Speed (HS) mode, the system
ends up configured for SDR12 with a 50MHz clock which is an illegal
mode.
This happens because the SDHCI_CTRL_VDD_180 bit in the
SDHCI_HOST_CONTROL2 register is left set and when this bit is
set, the speed mode is controlled by the SDHCI_CTRL_UHS field
in the SDHCI_HOST_CONTROL2 register. The SDHCI_CTRL_UHS field
will end up being set to 0 (SDR12) by sdhci_set_uhs_signaling()
because there is no UHS mode being set.
The fix is to change sdhci_set_uhs_signaling() to set the
SDHCI_CTRL_UHS field to SDR25 (which is the same as HS) for
any switch to HS mode.
This was found on a new eMMC controller that does strict checking
of the speed mode and the corresponding clock rate. It caused the
switch to HS400 mode to fail because part of the sequence to switch
to HS400 requires a switch from HS200 to HS before going to HS400.
Suggested-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mmc/host/sdhci.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c749d3dc1d36d..eb33b892b484c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1713,7 +1713,9 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
else if (timing == MMC_TIMING_UHS_SDR12)
ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
- else if (timing == MMC_TIMING_UHS_SDR25)
+ else if (timing == MMC_TIMING_SD_HS ||
+ timing == MMC_TIMING_MMC_HS ||
+ timing == MMC_TIMING_UHS_SDR25)
ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
else if (timing == MMC_TIMING_UHS_SDR50)
ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 4.19 117/128] mmc: core: Add helper function to indicate if SDIO IRQs is enabled
[not found] <20190922185418.2158-1-sashal@kernel.org>
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 115/128] mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 116/128] mmc: sdhci: Fix incorrect switch to HS mode Sasha Levin
@ 2019-09-22 18:54 ` Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 118/128] mmc: dw_mmc: Re-store SDIO IRQs mask at system resume Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-09-22 18:54 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ulf Hansson, Matthias Kaehlcke, Douglas Anderson, Sasha Levin,
linux-mmc
From: Ulf Hansson <ulf.hansson@linaro.org>
[ Upstream commit bd880b00697befb73eff7220ee20bdae4fdd487b ]
To avoid each host driver supporting SDIO IRQs, from keeping track
internally about if SDIO IRQs has been claimed, let's introduce a common
helper function, sdio_irq_claimed().
The function returns true if SDIO IRQs are claimed, via using the
information about the number of claimed irqs. This is safe, even without
any locks, as long as the helper function is called only from
runtime/system suspend callbacks of the host driver.
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/mmc/host.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2ff52de1c2b89..840462ed1ec7e 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -488,6 +488,15 @@ void mmc_command_done(struct mmc_host *host, struct mmc_request *mrq);
void mmc_cqe_request_done(struct mmc_host *host, struct mmc_request *mrq);
+/*
+ * May be called from host driver's system/runtime suspend/resume callbacks,
+ * to know if SDIO IRQs has been claimed.
+ */
+static inline bool sdio_irq_claimed(struct mmc_host *host)
+{
+ return host->sdio_irqs > 0;
+}
+
static inline void mmc_signal_sdio_irq(struct mmc_host *host)
{
host->ops->enable_sdio_irq(host, 0);
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 4.19 118/128] mmc: dw_mmc: Re-store SDIO IRQs mask at system resume
[not found] <20190922185418.2158-1-sashal@kernel.org>
` (2 preceding siblings ...)
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 117/128] mmc: core: Add helper function to indicate if SDIO IRQs is enabled Sasha Levin
@ 2019-09-22 18:54 ` Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-09-22 18:54 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ulf Hansson, Matthias Kaehlcke, Douglas Anderson, Sasha Levin,
linux-mmc
From: Ulf Hansson <ulf.hansson@linaro.org>
[ Upstream commit 7c526608d5afb62cbc967225e2ccaacfdd142e9d ]
In cases when SDIO IRQs have been enabled, runtime suspend is prevented by
the driver. However, this still means dw_mci_runtime_suspend|resume() gets
called during system suspend/resume, via pm_runtime_force_suspend|resume().
This means during system suspend/resume, the register context of the dw_mmc
device most likely loses its register context, even in cases when SDIO IRQs
have been enabled.
To re-enable the SDIO IRQs during system resume, the dw_mmc driver
currently relies on the mmc core to re-enable the SDIO IRQs when it resumes
the SDIO card, but this isn't the recommended solution. Instead, it's
better to deal with this locally in the dw_mmc driver, so let's do that.
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mmc/host/dw_mmc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 942da07c9eb87..22c454c7aaca6 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -3486,6 +3486,10 @@ int dw_mci_runtime_resume(struct device *dev)
/* Force setup bus to guarantee available clock output */
dw_mci_setup_bus(host->slot, true);
+ /* Re-enable SDIO interrupts. */
+ if (sdio_irq_claimed(host->slot->mmc))
+ __dw_mci_enable_sdio_irq(host->slot, 1);
+
/* Now that slots are all setup, we can enable card detect */
dw_mci_enable_cd(host);
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-09-22 18:54 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20190922185418.2158-1-sashal@kernel.org>
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 115/128] mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 116/128] mmc: sdhci: Fix incorrect switch to HS mode Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 117/128] mmc: core: Add helper function to indicate if SDIO IRQs is enabled Sasha Levin
2019-09-22 18:54 ` [PATCH AUTOSEL 4.19 118/128] mmc: dw_mmc: Re-store SDIO IRQs mask at system resume Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).