From 1db5f20f5d68259f6d6bf5e7f5017232dda15b2d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 23 Jun 2019 13:56:52 +0200 Subject: [PATCH] 4.9-stable patches 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 --- ...sdio-irqs-when-the-card-is-suspended.patch | 77 +++++++++++++++++++ ...spend-possibly-being-blocked-forever.patch | 69 +++++++++++++++++ queue-4.9/series | 3 + ...rkaround-for-endpoint-conflict-issue.patch | 76 ++++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 queue-4.9/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch create mode 100644 queue-4.9/scsi-ufs-avoid-runtime-suspend-possibly-being-blocked-forever.patch create mode 100644 queue-4.9/usb-chipidea-udc-workaround-for-endpoint-conflict-issue.patch 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 index 00000000000..9e792484caf --- /dev/null +++ b/queue-4.9/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 +@@ -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 index 00000000000..93977dea72e --- /dev/null +++ b/queue-4.9/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 +@@ -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: diff --git a/queue-4.9/series b/queue-4.9/series index 2f004b361fd..3b4b4666015 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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 index 00000000000..c5ee0c7a5eb --- /dev/null +++ b/queue-4.9/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 +@@ -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) -- 2.47.3