]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jun 2019 11:57:42 +0000 (13:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jun 2019 11:57:42 +0000 (13:57 +0200)
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

12 files changed:
queue-5.1/mmc-core-add-sdio_retune_hold_now-and-sdio_retune_release.patch [new file with mode: 0644]
queue-5.1/mmc-core-api-to-temporarily-disable-retuning-for-sdio-crc-errors.patch [new file with mode: 0644]
queue-5.1/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch [new file with mode: 0644]
queue-5.1/mmc-mediatek-fix-sdio-irq-detection-issue.patch [new file with mode: 0644]
queue-5.1/mmc-mediatek-fix-sdio-irq-interrupt-handle-flow.patch [new file with mode: 0644]
queue-5.1/mmc-sdhci-sdhci-pci-o2micro-correctly-set-bus-width-when-tuning.patch [new file with mode: 0644]
queue-5.1/mmc-sdhi-disallow-hs400-for-m3-w-es1.2-rz-g2m-and-v3h.patch [new file with mode: 0644]
queue-5.1/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch [new file with mode: 0644]
queue-5.1/series
queue-5.1/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch [new file with mode: 0644]
queue-5.1/usb-xhci-don-t-try-to-recover-an-endpoint-if-port-is-in-error-state.patch [new file with mode: 0644]
queue-5.1/xhci-detect-usb-3.2-capable-host-controllers-correctly.patch [new file with mode: 0644]

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 (file)
index 0000000..d5bab5f
--- /dev/null
@@ -0,0 +1,89 @@
+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 */
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 (file)
index 0000000..646f149
--- /dev/null
@@ -0,0 +1,133 @@
+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 */
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 (file)
index 0000000..7a83d32
--- /dev/null
@@ -0,0 +1,77 @@
+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.
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 (file)
index 0000000..54912ed
--- /dev/null
@@ -0,0 +1,35 @@
+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);
+ }
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 (file)
index 0000000..c057cb9
--- /dev/null
@@ -0,0 +1,109 @@
+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 = {
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 (file)
index 0000000..811f428
--- /dev/null
@@ -0,0 +1,49 @@
+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;
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 (file)
index 0000000..9d37cce
--- /dev/null
@@ -0,0 +1,49 @@
+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. */ },
+ };
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 (file)
index 0000000..6af543f
--- /dev/null
@@ -0,0 +1,69 @@
+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:
index 09c82e5958eabf2cf8684309fe7d9ed8502bf7d6..a782a43932c61cf4144fb5382a46d7805434834c 100644 (file)
@@ -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 (file)
index 0000000..2f357ac
--- /dev/null
@@ -0,0 +1,76 @@
+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)
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 (file)
index 0000000..fa413e1
--- /dev/null
@@ -0,0 +1,118 @@
+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. */
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 (file)
index 0000000..8f087e1
--- /dev/null
@@ -0,0 +1,67 @@
+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