diff --git a/main/linux-postmarketos-stericsson/APKBUILD b/main/linux-postmarketos-stericsson/APKBUILD index 932d05ee2..42f9599ab 100644 --- a/main/linux-postmarketos-stericsson/APKBUILD +++ b/main/linux-postmarketos-stericsson/APKBUILD @@ -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 " diff --git a/main/linux-postmarketos-stericsson/config-postmarketos-stericsson.armv7 b/main/linux-postmarketos-stericsson/config-postmarketos-stericsson.armv7 index c5c74b97e..89279022f 100644 --- a/main/linux-postmarketos-stericsson/config-postmarketos-stericsson.armv7 +++ b/main/linux-postmarketos-stericsson/config-postmarketos-stericsson.armv7 @@ -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 diff --git a/main/linux-postmarketos-stericsson/emmc.patch b/main/linux-postmarketos-stericsson/emmc.patch new file mode 100644 index 000000000..aac37b4e2 --- /dev/null +++ b/main/linux-postmarketos-stericsson/emmc.patch @@ -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 +Cc: Stephan Gerhold +Reported-by: newbyte@disroot.org +Signed-off-by: Linus Walleij +--- +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