--- /dev/null
+From b4c9f938d542d5f88c501744d2d12fad4fd2915f Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Mon, 17 Jun 2019 10:56:52 -0700
+Subject: mmc: core: Add sdio_retune_hold_now() and sdio_retune_release()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit b4c9f938d542d5f88c501744d2d12fad4fd2915f upstream.
+
+We want SDIO drivers to be able to temporarily stop retuning when the
+driver knows that the SDIO card is not in a state where retuning will
+work (maybe because the card is asleep). We'll move the relevant
+functions to a place where drivers can call them.
+
+Cc: stable@vger.kernel.org #v4.18+
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Acked-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/sdio_io.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ include/linux/mmc/sdio_func.h | 3 +++
+ 2 files changed, 43 insertions(+)
+
+--- a/drivers/mmc/core/sdio_io.c
++++ b/drivers/mmc/core/sdio_io.c
+@@ -19,6 +19,7 @@
+ #include "sdio_ops.h"
+ #include "core.h"
+ #include "card.h"
++#include "host.h"
+
+ /**
+ * sdio_claim_host - exclusively claim a bus for a certain SDIO function
+@@ -775,3 +776,42 @@ void sdio_retune_crc_enable(struct sdio_
+ func->card->host->retune_crc_disable = false;
+ }
+ EXPORT_SYMBOL_GPL(sdio_retune_crc_enable);
++
++/**
++ * sdio_retune_hold_now - start deferring retuning requests till release
++ * @func: SDIO function attached to host
++ *
++ * This function can be called if it's currently a bad time to do
++ * a retune of the SDIO card. Retune requests made during this time
++ * will be held and we'll actually do the retune sometime after the
++ * release.
++ *
++ * This function could be useful if an SDIO card is in a power state
++ * where it can respond to a small subset of commands that doesn't
++ * include the retuning command. Care should be taken when using
++ * this function since (presumably) the retuning request we might be
++ * deferring was made for a good reason.
++ *
++ * This function should be called while the host is claimed.
++ */
++void sdio_retune_hold_now(struct sdio_func *func)
++{
++ mmc_retune_hold_now(func->card->host);
++}
++EXPORT_SYMBOL_GPL(sdio_retune_hold_now);
++
++/**
++ * sdio_retune_release - signal that it's OK to retune now
++ * @func: SDIO function attached to host
++ *
++ * This is the complement to sdio_retune_hold_now(). Calling this
++ * function won't make a retune happen right away but will allow
++ * them to be scheduled normally.
++ *
++ * This function should be called while the host is claimed.
++ */
++void sdio_retune_release(struct sdio_func *func)
++{
++ mmc_retune_release(func->card->host);
++}
++EXPORT_SYMBOL_GPL(sdio_retune_release);
+--- a/include/linux/mmc/sdio_func.h
++++ b/include/linux/mmc/sdio_func.h
+@@ -162,4 +162,7 @@ extern int sdio_set_host_pm_flags(struct
+ extern void sdio_retune_crc_disable(struct sdio_func *func);
+ extern void sdio_retune_crc_enable(struct sdio_func *func);
+
++extern void sdio_retune_hold_now(struct sdio_func *func);
++extern void sdio_retune_release(struct sdio_func *func);
++
+ #endif /* LINUX_MMC_SDIO_FUNC_H */
--- /dev/null
+From 0a55f4ab9678413a01e740c86e9367ba0c612b36 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Mon, 17 Jun 2019 10:56:50 -0700
+Subject: mmc: core: API to temporarily disable retuning for SDIO CRC errors
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit 0a55f4ab9678413a01e740c86e9367ba0c612b36 upstream.
+
+Normally when the MMC core sees an "-EILSEQ" error returned by a host
+controller then it will trigger a retuning of the card. This is
+generally a good idea.
+
+However, if a command is expected to sometimes cause transfer errors
+then these transfer errors shouldn't cause a re-tuning. This
+re-tuning will be a needless waste of time. One example case where a
+transfer is expected to cause errors is when transitioning between
+idle (sometimes referred to as "sleep" in Broadcom code) and active
+state on certain Broadcom WiFi SDIO cards. Specifically if the card
+was already transitioning between states when the command was sent it
+could cause an error on the SDIO bus.
+
+Let's add an API that the SDIO function drivers can call that will
+temporarily disable the auto-tuning functionality. Then we can add a
+call to this in the Broadcom WiFi driver and any other driver that
+might have similar needs.
+
+NOTE: this makes the assumption that the card is already tuned well
+enough that it's OK to disable the auto-retuning during one of these
+error-prone situations. Presumably the driver code performing the
+error-prone transfer knows how to recover / retry from errors. ...and
+after we can get back to a state where transfers are no longer
+error-prone then we can enable the auto-retuning again. If we truly
+find ourselves in a case where the card needs to be retuned sometimes
+to handle one of these error-prone transfers then we can always try a
+few transfers first without auto-retuning and then re-try with
+auto-retuning if the first few fail.
+
+Without this change on rk3288-veyron-minnie I periodically see this in
+the logs of a machine just sitting there idle:
+ dwmmc_rockchip ff0d0000.dwmmc: Successfully tuned phase to XYZ
+
+Cc: stable@vger.kernel.org #v4.18+
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Acked-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/core.c | 5 +++--
+ drivers/mmc/core/sdio_io.c | 37 +++++++++++++++++++++++++++++++++++++
+ include/linux/mmc/host.h | 1 +
+ include/linux/mmc/sdio_func.h | 3 +++
+ 4 files changed, 44 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -144,8 +144,9 @@ void mmc_request_done(struct mmc_host *h
+ int err = cmd->error;
+
+ /* Flag re-tuning needed on CRC errors */
+- if ((cmd->opcode != MMC_SEND_TUNING_BLOCK &&
+- cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
++ if (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
++ cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
++ !host->retune_crc_disable &&
+ (err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) ||
+ (mrq->data && mrq->data->error == -EILSEQ) ||
+ (mrq->stop && mrq->stop->error == -EILSEQ)))
+--- a/drivers/mmc/core/sdio_io.c
++++ b/drivers/mmc/core/sdio_io.c
+@@ -738,3 +738,40 @@ int sdio_set_host_pm_flags(struct sdio_f
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
++
++/**
++ * sdio_retune_crc_disable - temporarily disable retuning on CRC errors
++ * @func: SDIO function attached to host
++ *
++ * If the SDIO card is known to be in a state where it might produce
++ * CRC errors on the bus in response to commands (like if we know it is
++ * transitioning between power states), an SDIO function driver can
++ * call this function to temporarily disable the SD/MMC core behavior of
++ * triggering an automatic retuning.
++ *
++ * This function should be called while the host is claimed and the host
++ * should remain claimed until sdio_retune_crc_enable() is called.
++ * Specifically, the expected sequence of calls is:
++ * - sdio_claim_host()
++ * - sdio_retune_crc_disable()
++ * - some number of calls like sdio_writeb() and sdio_readb()
++ * - sdio_retune_crc_enable()
++ * - sdio_release_host()
++ */
++void sdio_retune_crc_disable(struct sdio_func *func)
++{
++ func->card->host->retune_crc_disable = true;
++}
++EXPORT_SYMBOL_GPL(sdio_retune_crc_disable);
++
++/**
++ * sdio_retune_crc_enable - re-enable retuning on CRC errors
++ * @func: SDIO function attached to host
++ *
++ * This is the compement to sdio_retune_crc_disable().
++ */
++void sdio_retune_crc_enable(struct sdio_func *func)
++{
++ func->card->host->retune_crc_disable = false;
++}
++EXPORT_SYMBOL_GPL(sdio_retune_crc_enable);
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -398,6 +398,7 @@ struct mmc_host {
+ unsigned int retune_now:1; /* do re-tuning at next req */
+ unsigned int retune_paused:1; /* re-tuning is temporarily disabled */
+ unsigned int use_blk_mq:1; /* use blk-mq */
++ unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */
+
+ int rescan_disable; /* disable card detection */
+ int rescan_entered; /* used with nonremovable devices */
+--- a/include/linux/mmc/sdio_func.h
++++ b/include/linux/mmc/sdio_func.h
+@@ -159,4 +159,7 @@ extern void sdio_f0_writeb(struct sdio_f
+ extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);
+ extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
+
++extern void sdio_retune_crc_disable(struct sdio_func *func);
++extern void sdio_retune_crc_enable(struct sdio_func *func);
++
+ #endif /* LINUX_MMC_SDIO_FUNC_H */
--- /dev/null
+From 83293386bc95cf5e9f0c0175794455835bd1cb4a Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Tue, 18 Jun 2019 14:05:17 +0200
+Subject: mmc: core: Prevent processing SDIO IRQs when the card is suspended
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+commit 83293386bc95cf5e9f0c0175794455835bd1cb4a upstream.
+
+Processing of SDIO IRQs must obviously be prevented while the card is
+system suspended, otherwise we may end up trying to communicate with an
+uninitialized SDIO card.
+
+Reports throughout the years shows that this is not only a theoretical
+problem, but a real issue. So, let's finally fix this problem, by keeping
+track of the state for the card and bail out before processing the SDIO
+IRQ, in case the card is suspended.
+
+Cc: stable@vger.kernel.org
+Reported-by: Douglas Anderson <dianders@chromium.org>
+Tested-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/sdio.c | 13 ++++++++++++-
+ drivers/mmc/core/sdio_irq.c | 4 ++++
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/core/sdio.c
++++ b/drivers/mmc/core/sdio.c
+@@ -941,6 +941,10 @@ static int mmc_sdio_pre_suspend(struct m
+ */
+ static int mmc_sdio_suspend(struct mmc_host *host)
+ {
++ /* Prevent processing of SDIO IRQs in suspended state. */
++ mmc_card_set_suspended(host->card);
++ cancel_delayed_work_sync(&host->sdio_irq_work);
++
+ mmc_claim_host(host);
+
+ if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host))
+@@ -989,13 +993,20 @@ static int mmc_sdio_resume(struct mmc_ho
+ err = sdio_enable_4bit_bus(host->card);
+ }
+
+- if (!err && host->sdio_irqs) {
++ if (err)
++ goto out;
++
++ /* Allow SDIO IRQs to be processed again. */
++ mmc_card_clr_suspended(host->card);
++
++ if (host->sdio_irqs) {
+ if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD))
+ wake_up_process(host->sdio_irq_thread);
+ else if (host->caps & MMC_CAP_SDIO_IRQ)
+ host->ops->enable_sdio_irq(host, 1);
+ }
+
++out:
+ mmc_release_host(host);
+
+ host->pm_flags &= ~MMC_PM_KEEP_POWER;
+--- a/drivers/mmc/core/sdio_irq.c
++++ b/drivers/mmc/core/sdio_irq.c
+@@ -38,6 +38,10 @@ static int process_sdio_pending_irqs(str
+ unsigned char pending;
+ struct sdio_func *func;
+
++ /* Don't process SDIO IRQs if the card is suspended. */
++ if (mmc_card_suspended(card))
++ return 0;
++
+ /*
+ * Optimization, if there is only 1 function interrupt registered
+ * and we know an IRQ was signaled then call irq handler directly.
--- /dev/null
+From 20314ce30af197963b0c239f0952db6aaef73f99 Mon Sep 17 00:00:00 2001
+From: jjian zhou <jjian.zhou@mediatek.com>
+Date: Mon, 17 Jun 2019 19:04:08 +0800
+Subject: mmc: mediatek: fix SDIO IRQ detection issue
+
+From: jjian zhou <jjian.zhou@mediatek.com>
+
+commit 20314ce30af197963b0c239f0952db6aaef73f99 upstream.
+
+If cmd19 timeout or response crcerr occurs during execute_tuning(),
+it need invoke msdc_reset_hw(). Otherwise SDIO IRQ can't be detected.
+
+Signed-off-by: jjian zhou <jjian.zhou@mediatek.com>
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Signed-off-by: Yong Mao <yong.mao@mediatek.com>
+Fixes: 5215b2e952f3 ("mmc: mediatek: Add MMC_CAP_SDIO_IRQ support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/mtk-sd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1003,6 +1003,8 @@ static void msdc_request_done(struct msd
+ msdc_track_cmd_data(host, mrq->cmd, mrq->data);
+ if (mrq->data)
+ msdc_unprepare_data(host, mrq);
++ if (host->error)
++ msdc_reset_hw(host);
+ mmc_request_done(host->mmc, mrq);
+ }
+
--- /dev/null
+From 8a5df8ac628f4febea1e6cd3044bff2d536dd096 Mon Sep 17 00:00:00 2001
+From: jjian zhou <jjian.zhou@mediatek.com>
+Date: Mon, 17 Jun 2019 19:04:07 +0800
+Subject: mmc: mediatek: fix SDIO IRQ interrupt handle flow
+
+From: jjian zhou <jjian.zhou@mediatek.com>
+
+commit 8a5df8ac628f4febea1e6cd3044bff2d536dd096 upstream.
+
+SDIO IRQ is triggered by low level. It need disable SDIO IRQ
+detected function. Otherwise the interrupt register can't be cleared.
+It will process the interrupt more.
+
+Signed-off-by: Jjian Zhou <jjian.zhou@mediatek.com>
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Signed-off-by: Yong Mao <yong.mao@mediatek.com>
+Fixes: 5215b2e952f3 ("mmc: mediatek: Add MMC_CAP_SDIO_IRQ support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/mtk-sd.c | 37 ++++++++++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 17 deletions(-)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1355,24 +1355,25 @@ static void msdc_request_timeout(struct
+ }
+ }
+
+-static void __msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
++static void __msdc_enable_sdio_irq(struct msdc_host *host, int enb)
+ {
+- unsigned long flags;
+- struct msdc_host *host = mmc_priv(mmc);
+-
+- spin_lock_irqsave(&host->lock, flags);
+- if (enb)
++ if (enb) {
+ sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+- else
++ sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
++ } else {
+ sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+- spin_unlock_irqrestore(&host->lock, flags);
++ sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
++ }
+ }
+
+ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
+ {
++ unsigned long flags;
+ struct msdc_host *host = mmc_priv(mmc);
+
+- __msdc_enable_sdio_irq(mmc, enb);
++ spin_lock_irqsave(&host->lock, flags);
++ __msdc_enable_sdio_irq(host, enb);
++ spin_unlock_irqrestore(&host->lock, flags);
+
+ if (enb)
+ pm_runtime_get_noresume(host->dev);
+@@ -1394,6 +1395,8 @@ static irqreturn_t msdc_irq(int irq, voi
+ spin_lock_irqsave(&host->lock, flags);
+ events = readl(host->base + MSDC_INT);
+ event_mask = readl(host->base + MSDC_INTEN);
++ if ((events & event_mask) & MSDC_INT_SDIOIRQ)
++ __msdc_enable_sdio_irq(host, 0);
+ /* clear interrupts */
+ writel(events & event_mask, host->base + MSDC_INT);
+
+@@ -1402,10 +1405,8 @@ static irqreturn_t msdc_irq(int irq, voi
+ data = host->data;
+ spin_unlock_irqrestore(&host->lock, flags);
+
+- if ((events & event_mask) & MSDC_INT_SDIOIRQ) {
+- __msdc_enable_sdio_irq(host->mmc, 0);
++ if ((events & event_mask) & MSDC_INT_SDIOIRQ)
+ sdio_signal_irq(host->mmc);
+- }
+
+ if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ)))
+ break;
+@@ -1528,10 +1529,7 @@ static void msdc_init_hw(struct msdc_hos
+ sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
+
+ /* Config SDIO device detect interrupt function */
+- if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+- sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+- else
+- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
++ sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+
+ /* Configure to default data timeout */
+ sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
+@@ -2052,7 +2050,12 @@ static void msdc_hw_reset(struct mmc_hos
+
+ static void msdc_ack_sdio_irq(struct mmc_host *mmc)
+ {
+- __msdc_enable_sdio_irq(mmc, 1);
++ unsigned long flags;
++ struct msdc_host *host = mmc_priv(mmc);
++
++ spin_lock_irqsave(&host->lock, flags);
++ __msdc_enable_sdio_irq(host, 1);
++ spin_unlock_irqrestore(&host->lock, flags);
+ }
+
+ static const struct mmc_host_ops mt_msdc_ops = {
--- /dev/null
+From 0f7b79a44e7d7dd3ef1f59758c1a341f217ff5e5 Mon Sep 17 00:00:00 2001
+From: Raul E Rangel <rrangel@chromium.org>
+Date: Mon, 17 Jun 2019 14:10:12 -0600
+Subject: mmc: sdhci: sdhci-pci-o2micro: Correctly set bus width when tuning
+
+From: Raul E Rangel <rrangel@chromium.org>
+
+commit 0f7b79a44e7d7dd3ef1f59758c1a341f217ff5e5 upstream.
+
+The O2Micro controller only supports tuning at 4-bits. So the host driver
+needs to change the bus width while tuning and then set it back when done.
+
+There was a bug in the original implementation in that mmc->ios.bus_width
+also wasn't updated. Thus setting the incorrect blocksize in
+sdhci_send_tuning which results in a tuning failure.
+
+Signed-off-by: Raul E Rangel <rrangel@chromium.org>
+Fixes: 0086fc217d5d7 ("mmc: sdhci: Add support for O2 hardware tuning")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-pci-o2micro.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sdhci-pci-o2micro.c
++++ b/drivers/mmc/host/sdhci-pci-o2micro.c
+@@ -124,6 +124,7 @@ static int sdhci_o2_execute_tuning(struc
+ */
+ if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) {
+ current_bus_width = mmc->ios.bus_width;
++ mmc->ios.bus_width = MMC_BUS_WIDTH_4;
+ sdhci_set_bus_width(host, MMC_BUS_WIDTH_4);
+ }
+
+@@ -135,8 +136,10 @@ static int sdhci_o2_execute_tuning(struc
+
+ sdhci_end_tuning(host);
+
+- if (current_bus_width == MMC_BUS_WIDTH_8)
++ if (current_bus_width == MMC_BUS_WIDTH_8) {
++ mmc->ios.bus_width = MMC_BUS_WIDTH_8;
+ sdhci_set_bus_width(host, current_bus_width);
++ }
+
+ host->flags &= ~SDHCI_HS400_TUNING;
+ return 0;
--- /dev/null
+From 97bf85b6ec9e6597ce81c79b26a28f7918fc4eaf Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Date: Thu, 6 Jun 2019 13:35:35 +0200
+Subject: mmc: sdhi: disallow HS400 for M3-W ES1.2, RZ/G2M, and V3H
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+commit 97bf85b6ec9e6597ce81c79b26a28f7918fc4eaf upstream.
+
+Our HW engineers informed us that HS400 is not working on these SoC
+revisions.
+
+Fixes: 0f4e2054c971 ("mmc: renesas_sdhi: disable HS400 on H3 ES1.x and M3-W ES1.[012]")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -620,11 +620,16 @@ static const struct renesas_sdhi_quirks
+ .hs400_4taps = true,
+ };
+
++static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
++ .hs400_disabled = true,
++};
++
+ static const struct soc_device_attribute sdhi_quirks_match[] = {
+ { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_h3_m3w_es1 },
+ { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_h3_es2 },
+- { .soc_id = "r8a7796", .revision = "ES1.0", .data = &sdhi_quirks_h3_m3w_es1 },
+- { .soc_id = "r8a7796", .revision = "ES1.1", .data = &sdhi_quirks_h3_m3w_es1 },
++ { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_h3_m3w_es1 },
++ { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_h3_m3w_es1 },
++ { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },
+ { /* Sentinel. */ },
+ };
+
--- /dev/null
+From 24e2e7a19f7e4b83d0d5189040d997bce3596473 Mon Sep 17 00:00:00 2001
+From: Stanley Chu <stanley.chu@mediatek.com>
+Date: Wed, 12 Jun 2019 23:19:05 +0800
+Subject: scsi: ufs: Avoid runtime suspend possibly being blocked forever
+
+From: Stanley Chu <stanley.chu@mediatek.com>
+
+commit 24e2e7a19f7e4b83d0d5189040d997bce3596473 upstream.
+
+UFS runtime suspend can be triggered after pm_runtime_enable() is invoked
+in ufshcd_pltfrm_init(). However if the first runtime suspend is triggered
+before binding ufs_hba structure to ufs device structure via
+platform_set_drvdata(), then UFS runtime suspend will be no longer
+triggered in the future because its dev->power.runtime_error was set in the
+first triggering and does not have any chance to be cleared.
+
+To be more clear, dev->power.runtime_error is set if hba is NULL in
+ufshcd_runtime_suspend() which returns -EINVAL to rpm_callback() where
+dev->power.runtime_error is set as -EINVAL. In this case, any future
+rpm_suspend() for UFS device fails because rpm_check_suspend_allowed()
+fails due to non-zero
+dev->power.runtime_error.
+
+To resolve this issue, make sure the first UFS runtime suspend get valid
+"hba" in ufshcd_runtime_suspend(): Enable UFS runtime PM only after hba is
+successfully bound to UFS device structure.
+
+Fixes: 62694735ca95 ([SCSI] ufs: Add runtime PM support for UFS host controller driver)
+Cc: stable@vger.kernel.org
+Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/ufs/ufshcd-pltfrm.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
++++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
+@@ -340,24 +340,21 @@ int ufshcd_pltfrm_init(struct platform_d
+ goto dealloc_host;
+ }
+
+- pm_runtime_set_active(&pdev->dev);
+- pm_runtime_enable(&pdev->dev);
+-
+ ufshcd_init_lanes_per_dir(hba);
+
+ err = ufshcd_init(hba, mmio_base, irq);
+ if (err) {
+ dev_err(dev, "Initialization failed\n");
+- goto out_disable_rpm;
++ goto dealloc_host;
+ }
+
+ platform_set_drvdata(pdev, hba);
+
++ pm_runtime_set_active(&pdev->dev);
++ pm_runtime_enable(&pdev->dev);
++
+ return 0;
+
+-out_disable_rpm:
+- pm_runtime_disable(&pdev->dev);
+- pm_runtime_set_suspended(&pdev->dev);
+ dealloc_host:
+ ufshcd_dealloc_host(hba);
+ out:
tracing-silence-gcc-9-array-bounds-warning.patch
+mmc-sdhci-sdhci-pci-o2micro-correctly-set-bus-width-when-tuning.patch
+mmc-sdhi-disallow-hs400-for-m3-w-es1.2-rz-g2m-and-v3h.patch
+mmc-mediatek-fix-sdio-irq-interrupt-handle-flow.patch
+mmc-mediatek-fix-sdio-irq-detection-issue.patch
+mmc-core-api-to-temporarily-disable-retuning-for-sdio-crc-errors.patch
+mmc-core-add-sdio_retune_hold_now-and-sdio_retune_release.patch
+mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch
+scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch
+usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch
+xhci-detect-usb-3.2-capable-host-controllers-correctly.patch
+usb-xhci-don-t-try-to-recover-an-endpoint-if-port-is-in-error-state.patch
--- /dev/null
+From c19dffc0a9511a7d7493ec21019aefd97e9a111b Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Mon, 17 Jun 2019 09:49:07 +0800
+Subject: usb: chipidea: udc: workaround for endpoint conflict issue
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit c19dffc0a9511a7d7493ec21019aefd97e9a111b upstream.
+
+An endpoint conflict occurs when the USB is working in device mode
+during an isochronous communication. When the endpointA IN direction
+is an isochronous IN endpoint, and the host sends an IN token to
+endpointA on another device, then the OUT transaction may be missed
+regardless the OUT endpoint number. Generally, this occurs when the
+device is connected to the host through a hub and other devices are
+connected to the same hub.
+
+The affected OUT endpoint can be either control, bulk, isochronous, or
+an interrupt endpoint. After the OUT endpoint is primed, if an IN token
+to the same endpoint number on another device is received, then the OUT
+endpoint may be unprimed (cannot be detected by software), which causes
+this endpoint to no longer respond to the host OUT token, and thus, no
+corresponding interrupt occurs.
+
+There is no good workaround for this issue, the only thing the software
+could do is numbering isochronous IN from the highest endpoint since we
+have observed most of device number endpoint from the lowest.
+
+Cc: <stable@vger.kernel.org> #v3.14+
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Cc: Jun Li <jun.li@nxp.com>
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/udc.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -1622,6 +1622,25 @@ static int ci_udc_pullup(struct usb_gadg
+ static int ci_udc_start(struct usb_gadget *gadget,
+ struct usb_gadget_driver *driver);
+ static int ci_udc_stop(struct usb_gadget *gadget);
++
++/* Match ISOC IN from the highest endpoint */
++static struct usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
++ struct usb_endpoint_descriptor *desc,
++ struct usb_ss_ep_comp_descriptor *comp_desc)
++{
++ struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
++ struct usb_ep *ep;
++
++ if (usb_endpoint_xfer_isoc(desc) && usb_endpoint_dir_in(desc)) {
++ list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
++ if (ep->caps.dir_in && !ep->claimed)
++ return ep;
++ }
++ }
++
++ return NULL;
++}
++
+ /**
+ * Device operations part of the API to the USB controller hardware,
+ * which don't involve endpoints (or i/o)
+@@ -1635,6 +1654,7 @@ static const struct usb_gadget_ops usb_g
+ .vbus_draw = ci_udc_vbus_draw,
+ .udc_start = ci_udc_start,
+ .udc_stop = ci_udc_stop,
++ .match_ep = ci_udc_match_ep,
+ };
+
+ static int init_eps(struct ci_hdrc *ci)
--- /dev/null
+From b8c3b718087bf7c3c8e388eb1f72ac1108a4926e Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 18 Jun 2019 17:27:47 +0300
+Subject: usb: xhci: Don't try to recover an endpoint if port is in error state.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit b8c3b718087bf7c3c8e388eb1f72ac1108a4926e upstream.
+
+A USB3 device needs to be reset and re-enumarated if the port it
+connects to goes to a error state, with link state inactive.
+
+There is no use in trying to recover failed transactions by resetting
+endpoints at this stage. Tests show that in rare cases, after multiple
+endpoint resets of a roothub port the whole host controller might stop
+completely.
+
+Several retries to recover from transaction error can happen as
+it can take a long time before the hub thread discovers the USB3
+port error and inactive link.
+
+We can't reliably detect the port error from slot or endpoint context
+due to a limitation in xhci, see xhci specs section 4.8.3:
+"There are several cases where the EP State field in the Output
+Endpoint Context may not reflect the current state of an endpoint"
+and
+"Software should maintain an accurate value for EP State, by tracking it
+with an internal variable that is driven by Events and Doorbell accesses"
+
+Same appears to be true for slot state.
+
+set a flag to the corresponding slot if a USB3 roothub port link goes
+inactive to prevent both queueing new URBs and resetting endpoints.
+
+Reported-by: Rapolu Chiranjeevi <chiranjeevi.rapolu@intel.com>
+Tested-by: Rapolu Chiranjeevi <chiranjeevi.rapolu@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c | 15 ++++++++++++++-
+ drivers/usb/host/xhci.c | 5 +++++
+ drivers/usb/host/xhci.h | 9 +++++++++
+ 3 files changed, 28 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1608,8 +1608,13 @@ static void handle_port_status(struct xh
+ usb_hcd_resume_root_hub(hcd);
+ }
+
+- if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE)
++ if (hcd->speed >= HCD_USB3 &&
++ (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) {
++ slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1);
++ if (slot_id && xhci->devs[slot_id])
++ xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR;
+ bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
++ }
+
+ if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
+ xhci_dbg(xhci, "port resume event for port %d\n", port_id);
+@@ -1797,6 +1802,14 @@ static void xhci_cleanup_halted_endpoint
+ {
+ struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
+ struct xhci_command *command;
++
++ /*
++ * Avoid resetting endpoint if link is inactive. Can cause host hang.
++ * Device will be reset soon to recover the link so don't do anything
++ */
++ if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR)
++ return;
++
+ command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+ if (!command)
+ return;
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1442,6 +1442,10 @@ static int xhci_urb_enqueue(struct usb_h
+ xhci_dbg(xhci, "urb submitted during PCI suspend\n");
+ return -ESHUTDOWN;
+ }
++ if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) {
++ xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n");
++ return -ENODEV;
++ }
+
+ if (usb_endpoint_xfer_isoc(&urb->ep->desc))
+ num_tds = urb->number_of_packets;
+@@ -3724,6 +3728,7 @@ static int xhci_discover_or_reset_device
+ }
+ /* If necessary, update the number of active TTs on this root port */
+ xhci_update_tt_active_eps(xhci, virt_dev, old_active_eps);
++ virt_dev->flags = 0;
+ ret = 0;
+
+ command_cleanup:
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1010,6 +1010,15 @@ struct xhci_virt_device {
+ u8 real_port;
+ struct xhci_interval_bw_table *bw_table;
+ struct xhci_tt_bw_info *tt_info;
++ /*
++ * flags for state tracking based on events and issued commands.
++ * Software can not rely on states from output contexts because of
++ * latency between events and xHC updating output context values.
++ * See xhci 1.1 section 4.8.3 for more details
++ */
++ unsigned long flags;
++#define VDEV_PORT_ERROR BIT(0) /* Port error, link inactive */
++
+ /* The current max exit latency for the enabled USB3 link states. */
+ u16 current_mel;
+ /* Used for the debugfs interfaces. */
--- /dev/null
+From ddd57980a0fde30f7b5d14b888a2cc84d01610e8 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 18 Jun 2019 17:27:48 +0300
+Subject: xhci: detect USB 3.2 capable host controllers correctly
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit ddd57980a0fde30f7b5d14b888a2cc84d01610e8 upstream.
+
+USB 3.2 capability in a host can be detected from the
+xHCI Supported Protocol Capability major and minor revision fields.
+
+If major is 0x3 and minor 0x20 then the host is USB 3.2 capable.
+
+For USB 3.2 capable hosts set the root hub lane count to 2.
+
+The Major Revision and Minor Revision fields contain a BCD version number.
+The value of the Major Revision field is JJh and the value of the Minor
+Revision field is MNh for version JJ.M.N, where JJ = major revision number,
+M - minor version number, N = sub-minor version number,
+e.g. version 3.1 is represented with a value of 0310h.
+
+Also fix the extra whitespace printed out when announcing regular
+SuperSpeed hosts.
+
+Cc: <stable@vger.kernel.org> # v4.18+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -5029,16 +5029,26 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ } else {
+ /*
+ * Some 3.1 hosts return sbrn 0x30, use xhci supported protocol
+- * minor revision instead of sbrn
++ * minor revision instead of sbrn. Minor revision is a two digit
++ * BCD containing minor and sub-minor numbers, only show minor.
+ */
+- minor_rev = xhci->usb3_rhub.min_rev;
+- if (minor_rev) {
++ minor_rev = xhci->usb3_rhub.min_rev / 0x10;
++
++ switch (minor_rev) {
++ case 2:
++ hcd->speed = HCD_USB32;
++ hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
++ hcd->self.root_hub->rx_lanes = 2;
++ hcd->self.root_hub->tx_lanes = 2;
++ break;
++ case 1:
+ hcd->speed = HCD_USB31;
+ hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
++ break;
+ }
+- xhci_info(xhci, "Host supports USB 3.%x %s SuperSpeed\n",
++ xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",
+ minor_rev,
+- minor_rev ? "Enhanced" : "");
++ minor_rev ? "Enhanced " : "");
+
+ xhci->usb3_rhub.hcd = hcd;
+ /* xHCI private pointer was set in xhci_pci_probe for the second