]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jun 2019 11:56:36 +0000 (13:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jun 2019 11:56:36 +0000 (13:56 +0200)
added patches:
mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch
usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch

queue-4.4/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch [new file with mode: 0644]

diff --git a/queue-4.4/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch b/queue-4.4/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch
new file mode 100644 (file)
index 0000000..1475a07
--- /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
+@@ -897,6 +897,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))
+@@ -955,13 +959,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.
index 2f004b361fd6ca7fcfc02af950965db308457dcf..d0950814478737d4811c736e524c25021923531f 100644 (file)
@@ -1,2 +1,4 @@
 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
+usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch
diff --git a/queue-4.4/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch b/queue-4.4/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch
new file mode 100644 (file)
index 0000000..2643f6a
--- /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
+@@ -1614,6 +1614,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)
+@@ -1627,6 +1646,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)