From 3da0f455999b78b147aa3c470561b3f1d31d4ecc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Jul 2024 14:34:36 +0200 Subject: [PATCH] 5.4-stable patches added patches: mmc-sdhci-do-not-invert-write-protect-twice.patch mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch --- ...ci-do-not-invert-write-protect-twice.patch | 90 +++++++++++++++++++ ...lock-spinlock-around-mmc_gpio_get_ro.patch | 53 +++++++++++ ...vert-pcibios_-return-codes-to-errnos.patch | 74 +++++++++++++++ queue-5.4/series | 3 + 4 files changed, 220 insertions(+) create mode 100644 queue-5.4/mmc-sdhci-do-not-invert-write-protect-twice.patch create mode 100644 queue-5.4/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch create mode 100644 queue-5.4/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch diff --git a/queue-5.4/mmc-sdhci-do-not-invert-write-protect-twice.patch b/queue-5.4/mmc-sdhci-do-not-invert-write-protect-twice.patch new file mode 100644 index 00000000000..0532f19f65f --- /dev/null +++ b/queue-5.4/mmc-sdhci-do-not-invert-write-protect-twice.patch @@ -0,0 +1,90 @@ +From fbd64f902b93fe9658b855b9892ae59ef6ea22b9 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Fri, 14 Jun 2024 11:00:49 +0300 +Subject: mmc: sdhci: Do not invert write-protect twice + +From: Adrian Hunter + +commit fbd64f902b93fe9658b855b9892ae59ef6ea22b9 upstream. + +mmc_of_parse() reads device property "wp-inverted" and sets +MMC_CAP2_RO_ACTIVE_HIGH if it is true. MMC_CAP2_RO_ACTIVE_HIGH is used +to invert a write-protect (AKA read-only) GPIO value. + +sdhci_get_property() also reads "wp-inverted" and sets +SDHCI_QUIRK_INVERTED_WRITE_PROTECT which is used to invert the +write-protect value as well but also acts upon a value read out from the +SDHCI_PRESENT_STATE register. + +Many drivers call both mmc_of_parse() and sdhci_get_property(), +so that both MMC_CAP2_RO_ACTIVE_HIGH and +SDHCI_QUIRK_INVERTED_WRITE_PROTECT will be set if the controller has +device property "wp-inverted". + +Amend the logic in sdhci_check_ro() to allow for that possibility, +so that the write-protect value is not inverted twice. + +Also do not invert the value if it is a negative error value. Note that +callers treat an error the same as not-write-protected, so the result is +functionally the same in that case. + +Also do not invert the value if sdhci host operation ->get_ro() is used. +None of the users of that callback set SDHCI_QUIRK_INVERTED_WRITE_PROTECT +directly or indirectly, but two do call mmc_gpio_get_ro(), so leave it to +them to deal with that if they ever set SDHCI_QUIRK_INVERTED_WRITE_PROTECT +in the future. + +Fixes: 6d5cd068ee59 ("mmc: sdhci: use WP GPIO in sdhci_check_ro()") +Signed-off-by: Adrian Hunter +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240614080051.4005-2-adrian.hunter@intel.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2141,26 +2141,34 @@ static int sdhci_get_cd(struct mmc_host + + static int sdhci_check_ro(struct sdhci_host *host) + { ++ bool allow_invert = false; + unsigned long flags; + int is_readonly; + + spin_lock_irqsave(&host->lock, flags); + +- if (host->flags & SDHCI_DEVICE_DEAD) ++ if (host->flags & SDHCI_DEVICE_DEAD) { + is_readonly = 0; +- else if (host->ops->get_ro) ++ } else if (host->ops->get_ro) { + is_readonly = host->ops->get_ro(host); +- else if (mmc_can_gpio_ro(host->mmc)) ++ } else if (mmc_can_gpio_ro(host->mmc)) { + is_readonly = mmc_gpio_get_ro(host->mmc); +- else ++ /* Do not invert twice */ ++ allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); ++ } else { + is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) + & SDHCI_WRITE_PROTECT); ++ allow_invert = true; ++ } + + spin_unlock_irqrestore(&host->lock, flags); + +- /* This quirk needs to be replaced by a callback-function later */ +- return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? +- !is_readonly : is_readonly; ++ if (is_readonly >= 0 && ++ allow_invert && ++ (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) ++ is_readonly = !is_readonly; ++ ++ return is_readonly; + } + + #define SAMPLE_COUNT 5 diff --git a/queue-5.4/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch b/queue-5.4/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch new file mode 100644 index 00000000000..caaa74b4c1d --- /dev/null +++ b/queue-5.4/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch @@ -0,0 +1,53 @@ +From ab069ce125965a5e282f7b53b86aee76ab32975c Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Fri, 14 Jun 2024 11:00:50 +0300 +Subject: mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro() + +From: Adrian Hunter + +commit ab069ce125965a5e282f7b53b86aee76ab32975c upstream. + +sdhci_check_ro() can call mmc_gpio_get_ro() while holding the sdhci +host->lock spinlock. That would be a problem if the GPIO access done by +mmc_gpio_get_ro() needed to sleep. + +However, host->lock is not needed anyway. The mmc core ensures that host +operations do not race with each other, and asynchronous callbacks like the +interrupt handler, software timeouts, completion work etc, cannot affect +sdhci_check_ro(). + +So remove the locking. + +Fixes: 6d5cd068ee59 ("mmc: sdhci: use WP GPIO in sdhci_check_ro()") +Signed-off-by: Adrian Hunter +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240614080051.4005-3-adrian.hunter@intel.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2142,11 +2142,8 @@ static int sdhci_get_cd(struct mmc_host + static int sdhci_check_ro(struct sdhci_host *host) + { + bool allow_invert = false; +- unsigned long flags; + int is_readonly; + +- spin_lock_irqsave(&host->lock, flags); +- + if (host->flags & SDHCI_DEVICE_DEAD) { + is_readonly = 0; + } else if (host->ops->get_ro) { +@@ -2161,8 +2158,6 @@ static int sdhci_check_ro(struct sdhci_h + allow_invert = true; + } + +- spin_unlock_irqrestore(&host->lock, flags); +- + if (is_readonly >= 0 && + allow_invert && + (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) diff --git a/queue-5.4/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch b/queue-5.4/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch new file mode 100644 index 00000000000..22bb0ec9f1e --- /dev/null +++ b/queue-5.4/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch @@ -0,0 +1,74 @@ +From ebc4fc34eae8ddfbef49f2bdaced1bf4167ef80d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Mon, 27 May 2024 16:24:41 +0300 +Subject: mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +commit ebc4fc34eae8ddfbef49f2bdaced1bf4167ef80d upstream. + +jmicron_pmos() and sdhci_pci_probe() use pci_{read,write}_config_byte() +that return PCIBIOS_* codes. The return code is then returned as is by +jmicron_probe() and sdhci_pci_probe(). Similarly, the return code is +also returned as is from jmicron_resume(). Both probe and resume +functions should return normal errnos. + +Convert PCIBIOS_* returns code using pcibios_err_to_errno() into normal +errno before returning them the fix these issues. + +Fixes: 7582041ff3d4 ("mmc: sdhci-pci: fix simple_return.cocci warnings") +Fixes: 45211e215984 ("sdhci: toggle JMicron PMOS setting") +Cc: stable@vger.kernel.org +Signed-off-by: Ilpo Järvinen +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20240527132443.14038-1-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-pci-core.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -1376,7 +1376,7 @@ static int jmicron_pmos(struct sdhci_pci + + ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); + if (ret) +- return ret; ++ goto fail; + + /* + * Turn PMOS on [bit 0], set over current detection to 2.4 V +@@ -1387,7 +1387,10 @@ static int jmicron_pmos(struct sdhci_pci + else + scratch &= ~0x47; + +- return pci_write_config_byte(chip->pdev, 0xAE, scratch); ++ ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); ++ ++fail: ++ return pcibios_err_to_errno(ret); + } + + static int jmicron_probe(struct sdhci_pci_chip *chip) +@@ -2303,7 +2306,7 @@ static int sdhci_pci_probe(struct pci_de + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + + slots = PCI_SLOT_INFO_SLOTS(slots) + 1; + dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); +@@ -2312,7 +2315,7 @@ static int sdhci_pci_probe(struct pci_de + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + + first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + diff --git a/queue-5.4/series b/queue-5.4/series index 22e3487c706..740893160a0 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -203,3 +203,6 @@ soc-ti-wkup_m3_ipc-send-null-dummy-message-instead-o.patch nvme-fixup-comment-for-nvme-rdma-provider-type.patch gpio-davinci-validate-the-obtained-number-of-irqs.patch x86-stop-playing-stack-games-in-profile_pc.patch +mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch +mmc-sdhci-do-not-invert-write-protect-twice.patch +mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch -- 2.47.3