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

queue-4.9/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch [new file with mode: 0644]
queue-4.9/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch [new file with mode: 0644]

diff --git a/queue-4.9/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch b/queue-4.9/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch
new file mode 100644 (file)
index 0000000..9e79248
--- /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
+@@ -895,6 +895,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))
+@@ -953,13 +957,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
+@@ -35,6 +35,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-4.9/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch b/queue-4.9/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch
new file mode 100644 (file)
index 0000000..93977de
--- /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
+@@ -342,24 +342,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 2f004b361fd6ca7fcfc02af950965db308457dcf..3b4b46660154df5774bbc68861066952cd95c066 100644 (file)
@@ -1,2 +1,5 @@
 tracing-silence-gcc-9-array-bounds-warning.patch
 gcc-9-silence-address-of-packed-member-warning.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
diff --git a/queue-4.9/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch b/queue-4.9/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch
new file mode 100644 (file)
index 0000000..c5ee0c7
--- /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
+@@ -1621,6 +1621,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)
+@@ -1634,6 +1653,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)