main/linux-postmarketos-stericsson: upgrade to 5.13 (MR 2288)

[ci:skip-build] already built successfully in CI
This commit is contained in:
Newbyte 2021-06-29 14:40:33 +02:00 committed by Clayton Craft
parent 7ba97fda03
commit f9dc4366ee
No known key found for this signature in database
GPG key ID: 7A3461CA187CEA54
3 changed files with 250 additions and 6 deletions

View file

@ -4,9 +4,9 @@
_flavor="postmarketos-stericsson"
_config="config-$_flavor.armv7"
pkgname=linux-$_flavor
pkgver=5.13_rc4
pkgver=5.13
pkgrel=0
_tag="5.13-rc4"
_tag="5.13"
pkgdesc="Mainline kernel fork for ST-Ericsson NovaThor devices"
arch="armv7"
_carch="arm"
@ -19,6 +19,7 @@ source="
$pkgname-$_tag.tar.gz::https://git.kernel.org/torvalds/t/linux-$_tag.tar.gz
config-$_flavor.armv7
bl.patch
emmc.patch
panel.patch
regulators.patch
"
@ -49,9 +50,10 @@ package() {
}
sha512sums="
94ee9e59d4a3edcaf229c5ec29623302b50dd62d4ef8bdd91539cf0009f5a5fd13be629dbe78d004b016fec822c9e755898ea708fa33e1c74c54a650f64e030e linux-postmarketos-stericsson-5.13-rc4.tar.gz
6758b31eeefbb72cf7bb831467dce96acfd33b547d37a45631a74c8e1a58fc7305a9fba77fddc9cbada6d9b0fccacb2255fc4f8562ee25d88ca02cae71a17036 config-postmarketos-stericsson.armv7
6d70f9e4599abde63a5052541e2bd1c483e41be6504f859c26ad398501d82f036191954c1eb06b43b80d3409aeb1bba172d6728901bc72413fe75ea971a541d1 linux-postmarketos-stericsson-5.13.tar.gz
00c384b6c4cc2f7dd586b2c9463e898bf0634510fcc025a7efa3dfd189f75af92b690b022fced5ac40d1dc0e6f083fe037caa5dc5e82476d4e7db9b574818450 config-postmarketos-stericsson.armv7
66ec2d3105540e991bccc8cfb0e4212cb40a31a5a35e8cdc084b8bd7ffa016a86b3b340fd57b077b3c95b5bcb1e80cadaa11e71cd1a54a3e0e595024f3f27346 bl.patch
760afb46cf56a97b9a9a61fabd5c686c7b98bd64864774516099ad57a7c34d146a16d7ce4687b6071c3fd2df307e7f184428924569e0e767f3c80b780720d85b emmc.patch
1d4d549c5a8c8bda8eec814cd8632626f16d273d775f082028d15db7a330e0c01b2999668b0963eaeb06410de0c14d1d4c3344ac92a228da9392dba33562dcac panel.patch
8206d74c52328827502a32644f70fd149a72a78aaf936cd44f474b9153e8caccf73206df76e24004329edebab90e1a4a0e965630f4817aa5dd642d9ee2729295 regulators.patch
"

View file

@ -1,8 +1,8 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 5.13.0-rc4 Kernel Configuration
# Linux/arm 5.13.0 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="armv7-alpine-linux-musleabihf-gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424"
CONFIG_CC_VERSION_TEXT="armv7-alpine-linux-musleabihf-gcc (Alpine 10.3.1_git20210625) 10.3.1 20210625"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=100301
CONFIG_CLANG_VERSION=0
@ -2978,6 +2978,7 @@ CONFIG_HID_MONTEREY=y
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SEMITEK is not set
# CONFIG_HID_SPEEDLINK is not set
# CONFIG_HID_STEAM is not set
# CONFIG_HID_STEELSERIES is not set

View file

@ -0,0 +1,241 @@
Some boot partitions on the Samsung 4GB KLM4G1YE4C "4YMD1R" and "M4G1YC"
cards appear broken when accessed randomly. CMD6 to switch back to the main
partition randomly stalls after CMD18 access to the boot partition 1, and
the card never comes back online. The accesses to the boot partitions work
several times before this happens.
Some problematic eMMC cards are found in the Samsung GT-S7710 mobile phone.
I tried using only single blocks with CMD17 on the boot partitions with the
result that it crashed even faster.
The card may survive on older kernels, but this seems to be because recent
kernel partition parsers are accessing the boot partitions more, and we get
more block traffic to the boot partitions during kernel startup.
After applying this patch, the main partition can be accessed and mounted
without problems.
After a bit of root cause analysis it turns out that these old eMMC cards
cannot do hardware busy detection (monitoring DAT0) properly. This explains
why older kernels work since we only recently added support for this to the
MMCI driver which is used with these cards on these platforms.
Construct a quirk that makes the MMC cord avoid using the ->card_busy()
callback if the card is listed with MMC_QUIRK_BROKEN_HW_BUSY_DETECT and
register the known problematic cards. The core changes are pretty
straight-forward with a helper inline to check of we can use hardware
busy detection.
On the MMCI host we have to counter the fact that if the host was able to
use busy detect, it would be used unsolicited in the command IRQ callback.
Rewrite this so that MMCI will not attempt to use hardware busy detection
in the command IRQ until:
- A card is attached to the host and
- We know that the card can handle this busy detection
I have glanced over the ->card_busy() callbacks on some other hosts and
they seem to mostly read a register reflecting the value of DAT0 for this
which works fine with the quirk in this patch. However if the error appear
on other hosts they might need additional fixes.
Fixes: cb0335b778c7 ("mmc: mmci: add busy_complete callback")
Cc: stable@vger.kernel.org
Cc: phone-devel@vger.kernel.org
Cc: Ludovic Barre <ludovic.barre@st.com>
Cc: Stephan Gerhold <stephan@gerhold.net>
Reported-by: newbyte@disroot.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Rewrite to reflect the actual problem of broken busy detection.
---
drivers/mmc/core/core.c | 8 ++++----
drivers/mmc/core/core.h | 17 +++++++++++++++++
drivers/mmc/core/mmc_ops.c | 4 ++--
drivers/mmc/core/quirks.h | 21 +++++++++++++++++++++
drivers/mmc/host/mmci.c | 22 ++++++++++++++++++++--
include/linux/mmc/card.h | 1 +
6 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index f194940c5974..7142a806f6a6 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -232,7 +232,7 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
* And bypass I/O abort, reset and bus suspend operations.
*/
if (sdio_is_io_busy(mrq->cmd->opcode, mrq->cmd->arg) &&
- host->ops->card_busy) {
+ mmc_hw_busy_detect(host)) {
int tries = 500; /* Wait aprox 500ms at maximum */
while (host->ops->card_busy(host) && --tries)
@@ -1197,7 +1197,7 @@ int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr)
*/
if (!host->ops->start_signal_voltage_switch)
return -EPERM;
- if (!host->ops->card_busy)
+ if (!mmc_hw_busy_detect(host))
pr_warn("%s: cannot verify signal voltage switch\n",
mmc_hostname(host));
@@ -1217,7 +1217,7 @@ int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr)
* after the response of cmd11, but wait 1 ms to be sure
*/
mmc_delay(1);
- if (host->ops->card_busy && !host->ops->card_busy(host)) {
+ if (mmc_hw_busy_detect(host) && !host->ops->card_busy(host)) {
err = -EAGAIN;
goto power_cycle;
}
@@ -1238,7 +1238,7 @@ int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr)
* Failure to switch is indicated by the card holding
* dat[0:3] low
*/
- if (host->ops->card_busy && host->ops->card_busy(host))
+ if (mmc_hw_busy_detect(host) && host->ops->card_busy(host))
err = -EAGAIN;
power_cycle:
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index db3c9c68875d..68091bbba580 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -172,4 +172,21 @@ static inline bool mmc_cache_enabled(struct mmc_host *host)
return false;
}
+/**
+ * mmc_hw_busy_detect() - Can we use hw busy detection?
+ * @host: the host in question
+ */
+static inline bool mmc_hw_busy_detect(struct mmc_host *host)
+{
+ struct mmc_card *card = host->card;
+ bool has_ops;
+ bool able = true;
+
+ has_ops = (host->ops->card_busy != NULL);
+ if (card)
+ able = !(card->quirks & MMC_QUIRK_BROKEN_HW_BUSY_DETECT);
+
+ return (has_ops && able);
+}
+
#endif
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 5756781fef37..5f37e280dc1c 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -431,7 +431,7 @@ static int mmc_busy_status(struct mmc_card *card, bool retry_crc_err,
u32 status = 0;
int err;
- if (host->ops->card_busy) {
+ if (mmc_hw_busy_detect(host)) {
*busy = host->ops->card_busy(host);
return 0;
}
@@ -480,7 +480,7 @@ static int __mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
* capable of polling by using ->card_busy(), then rely on waiting the
* stated timeout to be sufficient.
*/
- if (!send_status && !host->ops->card_busy) {
+ if (!send_status && mmc_hw_busy_detect(host)) {
mmc_delay(timeout_ms);
return 0;
}
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
index d68e6e513a4f..8da6526f0eb0 100644
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -99,6 +99,27 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_TRIM_BROKEN),
+ /*
+ * Some older Samsung eMMCs have broken hardware busy detection.
+ * Enabling this feature in the host controller can make the card
+ * accesses lock up completely.
+ */
+ MMC_FIXUP("4YMD1R", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+ /* Samsung KLMxGxxE4x eMMCs from 2012: 4, 8, 16, 32 and 64 GB */
+ MMC_FIXUP("M4G1YC", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+ MMC_FIXUP("M8G1WA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+ MMC_FIXUP("MAG2WA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+ MMC_FIXUP("MBG4WA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+ MMC_FIXUP("MAG2WA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+ MMC_FIXUP("MCG8WA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BROKEN_HW_BUSY_DETECT),
+
END_FIXUP
};
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 984d35055156..3046917b2b67 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -347,6 +347,24 @@ static int mmci_card_busy(struct mmc_host *mmc)
return busy;
}
+/* Use this if the MMCI variant AND the card supports it */
+static bool mmci_use_busy_detect(struct mmci_host *host)
+{
+ struct mmc_card *card = host->mmc->card;
+
+ if (!host->variant->busy_detect)
+ return false;
+
+ /* We don't allow this until we know that the card can handle it */
+ if (!card)
+ return false;
+
+ if (card->quirks & MMC_QUIRK_BROKEN_HW_BUSY_DETECT)
+ return false;
+
+ return true;
+}
+
static void mmci_reg_delay(struct mmci_host *host)
{
/*
@@ -1381,7 +1399,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
return;
/* Handle busy detection on DAT0 if the variant supports it. */
- if (busy_resp && host->variant->busy_detect)
+ if (busy_resp && mmci_use_busy_detect(host))
if (!host->ops->busy_complete(host, status, err_msk))
return;
@@ -1725,7 +1743,7 @@ static void mmci_set_max_busy_timeout(struct mmc_host *mmc)
struct mmci_host *host = mmc_priv(mmc);
u32 max_busy_timeout = 0;
- if (!host->variant->busy_detect)
+ if (!mmci_use_busy_detect(host))
return;
if (host->variant->busy_timeout && mmc->actual_clock)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index f9ad35dd6012..b9a12e925a5b 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -259,6 +259,7 @@ struct mmc_card {
/* for byte mode */
#define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */
/* (missing CIA registers) */
+#define MMC_QUIRK_BROKEN_HW_BUSY_DETECT (1<<3) /* Disable hardware busy detection on DAT0 */
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
--
2.31.1