From: Greg Kroah-Hartman Date: Sun, 23 Jun 2019 11:57:42 +0000 (+0200) Subject: 5.1-stable patches X-Git-Tag: v5.1.15~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6754ff8d88d789cc9b288e65f2e705d372184727;p=thirdparty%2Fkernel%2Fstable-queue.git 5.1-stable patches added patches: mmc-core-add-sdio_retune_hold_now-and-sdio_retune_release.patch mmc-core-api-to-temporarily-disable-retuning-for-sdio-crc-errors.patch mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch mmc-mediatek-fix-sdio-irq-detection-issue.patch mmc-mediatek-fix-sdio-irq-interrupt-handle-flow.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 scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch usb-xhci-don-t-try-to-recover-an-endpoint-if-port-is-in-error-state.patch xhci-detect-usb-3.2-capable-host-controllers-correctly.patch --- diff --git a/queue-5.1/mmc-core-add-sdio_retune_hold_now-and-sdio_retune_release.patch b/queue-5.1/mmc-core-add-sdio_retune_hold_now-and-sdio_retune_release.patch new file mode 100644 index 00000000000..d5bab5f60a0 --- /dev/null +++ b/queue-5.1/mmc-core-add-sdio_retune_hold_now-and-sdio_retune_release.patch @@ -0,0 +1,89 @@ +From b4c9f938d542d5f88c501744d2d12fad4fd2915f Mon Sep 17 00:00:00 2001 +From: Douglas Anderson +Date: Mon, 17 Jun 2019 10:56:52 -0700 +Subject: mmc: core: Add sdio_retune_hold_now() and sdio_retune_release() + +From: Douglas Anderson + +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 +Acked-by: Adrian Hunter +Acked-by: Kalle Valo +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-5.1/mmc-core-api-to-temporarily-disable-retuning-for-sdio-crc-errors.patch b/queue-5.1/mmc-core-api-to-temporarily-disable-retuning-for-sdio-crc-errors.patch new file mode 100644 index 00000000000..646f1496988 --- /dev/null +++ b/queue-5.1/mmc-core-api-to-temporarily-disable-retuning-for-sdio-crc-errors.patch @@ -0,0 +1,133 @@ +From 0a55f4ab9678413a01e740c86e9367ba0c612b36 Mon Sep 17 00:00:00 2001 +From: Douglas Anderson +Date: Mon, 17 Jun 2019 10:56:50 -0700 +Subject: mmc: core: API to temporarily disable retuning for SDIO CRC errors + +From: Douglas Anderson + +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 +Acked-by: Adrian Hunter +Acked-by: Kalle Valo +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-5.1/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch b/queue-5.1/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch new file mode 100644 index 00000000000..7a83d32664c --- /dev/null +++ b/queue-5.1/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch @@ -0,0 +1,77 @@ +From 83293386bc95cf5e9f0c0175794455835bd1cb4a Mon Sep 17 00:00:00 2001 +From: Ulf Hansson +Date: Tue, 18 Jun 2019 14:05:17 +0200 +Subject: mmc: core: Prevent processing SDIO IRQs when the card is suspended + +From: Ulf Hansson + +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 +Tested-by: Douglas Anderson +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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. diff --git a/queue-5.1/mmc-mediatek-fix-sdio-irq-detection-issue.patch b/queue-5.1/mmc-mediatek-fix-sdio-irq-detection-issue.patch new file mode 100644 index 00000000000..54912ed69f6 --- /dev/null +++ b/queue-5.1/mmc-mediatek-fix-sdio-irq-detection-issue.patch @@ -0,0 +1,35 @@ +From 20314ce30af197963b0c239f0952db6aaef73f99 Mon Sep 17 00:00:00 2001 +From: jjian zhou +Date: Mon, 17 Jun 2019 19:04:08 +0800 +Subject: mmc: mediatek: fix SDIO IRQ detection issue + +From: jjian zhou + +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 +Signed-off-by: Chaotian Jing +Signed-off-by: Yong Mao +Fixes: 5215b2e952f3 ("mmc: mediatek: Add MMC_CAP_SDIO_IRQ support") +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + diff --git a/queue-5.1/mmc-mediatek-fix-sdio-irq-interrupt-handle-flow.patch b/queue-5.1/mmc-mediatek-fix-sdio-irq-interrupt-handle-flow.patch new file mode 100644 index 00000000000..c057cb9e2a3 --- /dev/null +++ b/queue-5.1/mmc-mediatek-fix-sdio-irq-interrupt-handle-flow.patch @@ -0,0 +1,109 @@ +From 8a5df8ac628f4febea1e6cd3044bff2d536dd096 Mon Sep 17 00:00:00 2001 +From: jjian zhou +Date: Mon, 17 Jun 2019 19:04:07 +0800 +Subject: mmc: mediatek: fix SDIO IRQ interrupt handle flow + +From: jjian zhou + +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 +Signed-off-by: Chaotian Jing +Signed-off-by: Yong Mao +Fixes: 5215b2e952f3 ("mmc: mediatek: Add MMC_CAP_SDIO_IRQ support") +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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 = { diff --git a/queue-5.1/mmc-sdhci-sdhci-pci-o2micro-correctly-set-bus-width-when-tuning.patch b/queue-5.1/mmc-sdhci-sdhci-pci-o2micro-correctly-set-bus-width-when-tuning.patch new file mode 100644 index 00000000000..811f4283fc9 --- /dev/null +++ b/queue-5.1/mmc-sdhci-sdhci-pci-o2micro-correctly-set-bus-width-when-tuning.patch @@ -0,0 +1,49 @@ +From 0f7b79a44e7d7dd3ef1f59758c1a341f217ff5e5 Mon Sep 17 00:00:00 2001 +From: Raul E Rangel +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 + +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 +Fixes: 0086fc217d5d7 ("mmc: sdhci: Add support for O2 hardware tuning") +Acked-by: Adrian Hunter +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-5.1/mmc-sdhi-disallow-hs400-for-m3-w-es1.2-rz-g2m-and-v3h.patch b/queue-5.1/mmc-sdhi-disallow-hs400-for-m3-w-es1.2-rz-g2m-and-v3h.patch new file mode 100644 index 00000000000..9d37cce3ed5 --- /dev/null +++ b/queue-5.1/mmc-sdhi-disallow-hs400-for-m3-w-es1.2-rz-g2m-and-v3h.patch @@ -0,0 +1,49 @@ +From 97bf85b6ec9e6597ce81c79b26a28f7918fc4eaf Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +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 + +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 +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Fabrizio Castro +Reviewed-by: Niklas Söderlund +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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. */ }, + }; + diff --git a/queue-5.1/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch b/queue-5.1/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch new file mode 100644 index 00000000000..6af543f36d4 --- /dev/null +++ b/queue-5.1/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch @@ -0,0 +1,69 @@ +From 24e2e7a19f7e4b83d0d5189040d997bce3596473 Mon Sep 17 00:00:00 2001 +From: Stanley Chu +Date: Wed, 12 Jun 2019 23:19:05 +0800 +Subject: scsi: ufs: Avoid runtime suspend possibly being blocked forever + +From: Stanley Chu + +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 +Reviewed-by: Avri Altman +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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: diff --git a/queue-5.1/series b/queue-5.1/series index 09c82e5958e..a782a43932c 100644 --- a/queue-5.1/series +++ b/queue-5.1/series @@ -1 +1,12 @@ 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 diff --git a/queue-5.1/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch b/queue-5.1/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch new file mode 100644 index 00000000000..2f357ac1486 --- /dev/null +++ b/queue-5.1/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch @@ -0,0 +1,76 @@ +From c19dffc0a9511a7d7493ec21019aefd97e9a111b Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Mon, 17 Jun 2019 09:49:07 +0800 +Subject: usb: chipidea: udc: workaround for endpoint conflict issue + +From: Peter Chen + +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: #v3.14+ +Cc: Fabio Estevam +Cc: Greg KH +Cc: Sergei Shtylyov +Cc: Jun Li +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-5.1/usb-xhci-don-t-try-to-recover-an-endpoint-if-port-is-in-error-state.patch b/queue-5.1/usb-xhci-don-t-try-to-recover-an-endpoint-if-port-is-in-error-state.patch new file mode 100644 index 00000000000..fa413e14b59 --- /dev/null +++ b/queue-5.1/usb-xhci-don-t-try-to-recover-an-endpoint-if-port-is-in-error-state.patch @@ -0,0 +1,118 @@ +From b8c3b718087bf7c3c8e388eb1f72ac1108a4926e Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +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 + +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 +Tested-by: Rapolu Chiranjeevi +Cc: +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + 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. */ diff --git a/queue-5.1/xhci-detect-usb-3.2-capable-host-controllers-correctly.patch b/queue-5.1/xhci-detect-usb-3.2-capable-host-controllers-correctly.patch new file mode 100644 index 00000000000..8f087e12320 --- /dev/null +++ b/queue-5.1/xhci-detect-usb-3.2-capable-host-controllers-correctly.patch @@ -0,0 +1,67 @@ +From ddd57980a0fde30f7b5d14b888a2cc84d01610e8 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Tue, 18 Jun 2019 17:27:48 +0300 +Subject: xhci: detect USB 3.2 capable host controllers correctly + +From: Mathias Nyman + +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: # v4.18+ +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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