]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jun 2022 09:24:23 +0000 (11:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jun 2022 09:24:23 +0000 (11:24 +0200)
added patches:
mtd-cfi_cmdset_0002-use-chip_ready-for-write-on-s29gl064n.patch

queue-5.4/mtd-cfi_cmdset_0002-use-chip_ready-for-write-on-s29gl064n.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/mtd-cfi_cmdset_0002-use-chip_ready-for-write-on-s29gl064n.patch b/queue-5.4/mtd-cfi_cmdset_0002-use-chip_ready-for-write-on-s29gl064n.patch
new file mode 100644 (file)
index 0000000..cb7b222
--- /dev/null
@@ -0,0 +1,143 @@
+From 0a8e98305f63deaf0a799d5cf5532cc83af035d1 Mon Sep 17 00:00:00 2001
+From: Tokunori Ikegami <ikegami.t@gmail.com>
+Date: Thu, 24 Mar 2022 02:04:56 +0900
+Subject: mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N
+
+From: Tokunori Ikegami <ikegami.t@gmail.com>
+
+commit 0a8e98305f63deaf0a799d5cf5532cc83af035d1 upstream.
+
+Since commit dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to
+check correct value") buffered writes fail on S29GL064N. This is
+because, on S29GL064N, reads return 0xFF at the end of DQ polling for
+write completion, where as, chip_good() check expects actual data
+written to the last location to be returned post DQ polling completion.
+Fix is to revert to using chip_good() for S29GL064N which only checks
+for DQ lines to settle down to determine write completion.
+
+Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.de/
+Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
+Acked-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220323170458.5608-3-ikegami.t@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/chips/cfi_cmdset_0002.c |   42 +++++++++++++++++++++++++++++-------
+ include/linux/mtd/cfi.h             |    1 
+ 2 files changed, 35 insertions(+), 8 deletions(-)
+
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -59,6 +59,10 @@
+ #define CFI_SR_WBASB          BIT(3)
+ #define CFI_SR_SLSB           BIT(1)
++enum cfi_quirks {
++      CFI_QUIRK_DQ_TRUE_DATA = BIT(0),
++};
++
+ static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+ static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+ #if !FORCE_WORD_WRITE
+@@ -432,6 +436,15 @@ static void fixup_s29ns512p_sectors(stru
+               mtd->name);
+ }
++static void fixup_quirks(struct mtd_info *mtd)
++{
++      struct map_info *map = mtd->priv;
++      struct cfi_private *cfi = map->fldrv_priv;
++
++      if (cfi->mfr == CFI_MFR_AMD && cfi->id == 0x0c01)
++              cfi->quirks |= CFI_QUIRK_DQ_TRUE_DATA;
++}
++
+ /* Used to fix CFI-Tables of chips without Extended Query Tables */
+ static struct cfi_fixup cfi_nopri_fixup_table[] = {
+       { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */
+@@ -470,6 +483,7 @@ static struct cfi_fixup cfi_fixup_table[
+ #if !FORCE_WORD_WRITE
+       { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers },
+ #endif
++      { CFI_MFR_ANY, CFI_ID_ANY, fixup_quirks },
+       { 0, 0, NULL }
+ };
+ static struct cfi_fixup jedec_fixup_table[] = {
+@@ -842,6 +856,18 @@ static int __xipram chip_ready(struct ma
+       return map_word_equal(map, t, *expected);
+ }
++static int __xipram chip_good(struct map_info *map, struct flchip *chip,
++                            unsigned long addr, map_word *expected)
++{
++      struct cfi_private *cfi = map->fldrv_priv;
++      map_word *datum = expected;
++
++      if (cfi->quirks & CFI_QUIRK_DQ_TRUE_DATA)
++              datum = NULL;
++
++      return chip_ready(map, chip, addr, datum);
++}
++
+ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
+ {
+       DECLARE_WAITQUEUE(wait, current);
+@@ -1658,11 +1684,11 @@ static int __xipram do_write_oneword_onc
+               }
+               /*
+-               * We check "time_after" and "!chip_ready" before checking
+-               * "chip_ready" to avoid the failure due to scheduling.
++               * We check "time_after" and "!chip_good" before checking
++               * "chip_good" to avoid the failure due to scheduling.
+                */
+               if (time_after(jiffies, timeo) &&
+-                  !chip_ready(map, chip, adr, &datum)) {
++                  !chip_good(map, chip, adr, &datum)) {
+                       xip_enable(map, chip, adr);
+                       printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
+                       xip_disable(map, chip, adr);
+@@ -1670,7 +1696,7 @@ static int __xipram do_write_oneword_onc
+                       break;
+               }
+-              if (chip_ready(map, chip, adr, &datum)) {
++              if (chip_good(map, chip, adr, &datum)) {
+                       if (cfi_check_err_status(map, chip, adr))
+                               ret = -EIO;
+                       break;
+@@ -1938,18 +1964,18 @@ static int __xipram do_write_buffer_wait
+               }
+               /*
+-               * We check "time_after" and "!chip_ready" before checking
+-               * "chip_ready" to avoid the failure due to scheduling.
++               * We check "time_after" and "!chip_good" before checking
++               * "chip_good" to avoid the failure due to scheduling.
+                */
+               if (time_after(jiffies, timeo) &&
+-                  !chip_ready(map, chip, adr, &datum)) {
++                  !chip_good(map, chip, adr, &datum)) {
+                       pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
+                              __func__, adr);
+                       ret = -EIO;
+                       break;
+               }
+-              if (chip_ready(map, chip, adr, &datum)) {
++              if (chip_good(map, chip, adr, &datum)) {
+                       if (cfi_check_err_status(map, chip, adr))
+                               ret = -EIO;
+                       break;
+--- a/include/linux/mtd/cfi.h
++++ b/include/linux/mtd/cfi.h
+@@ -286,6 +286,7 @@ struct cfi_private {
+       map_word sector_erase_cmd;
+       unsigned long chipshift; /* Because they're of the same type */
+       const char *im_name;     /* inter_module name for cmdset_setup */
++      unsigned long quirks;
+       struct flchip chips[0];  /* per-chip data structure for each chip */
+ };
index 44cefe8ab6a73701f02ce5d4f5afb208b46f79a5..44e0d616c55d298c0a1018f5a82f1d1ae990a95b 100644 (file)
@@ -409,3 +409,4 @@ ixgbe-fix-unexpected-vlan-rx-in-promisc-mode-on-vf.patch
 input-bcm5974-set-missing-urb_no_transfer_dma_map-urb-flag.patch
 powerpc-32-fix-overread-overwrite-of-thread_struct-via-ptrace.patch
 md-raid0-ignore-raid0-layout-if-the-second-zone-has-only-one-device.patch
+mtd-cfi_cmdset_0002-use-chip_ready-for-write-on-s29gl064n.patch