diff options
8 files changed, 55 insertions, 188 deletions
diff --git a/target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch b/target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch new file mode 100644 index 0000000000..50ed2be3d7 --- /dev/null +++ b/target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch @@ -0,0 +1,36 @@ +From: Felix Fietkau <nbd@nbd.name> +Date: Thu, 22 Feb 2018 11:11:57 +0100 +Subject: [PATCH] mtd: spi-nor: allow NOR driver to write fewer bytes than + requested + +The write size can be constrained by the maximum message/transfer size +of the SPI controller. Only check for ret = 0 to avoid an infinite loop. + +Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -1371,7 +1371,7 @@ static int spi_nor_write(struct mtd_info + + write_enable(nor); + ret = nor->write(nor, addr, page_remain, buf + i); +- if (ret < 0) ++ if (ret <= 0) + goto write_err; + written = ret; + +@@ -1380,13 +1380,6 @@ static int spi_nor_write(struct mtd_info + goto write_err; + *retlen += written; + i += written; +- if (written != page_remain) { +- dev_err(nor->dev, +- "While writing %zu bytes written %zd bytes\n", +- page_remain, written); +- ret = -EIO; +- goto write_err; +- } + } + + write_err: diff --git a/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch index 89d38ec303..dc71e9d542 100644 --- a/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch +++ b/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch @@ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -2715,6 +2715,7 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -2708,6 +2708,7 @@ int spi_nor_scan(struct spi_nor *nor, co if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || JEDEC_MFR(info) == SNOR_MFR_INTEL || diff --git a/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch b/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch index b7877297ae..fc5cf62324 100644 --- a/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch +++ b/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch @@ -17,7 +17,7 @@ Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -2717,6 +2717,7 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -2710,6 +2710,7 @@ int spi_nor_scan(struct spi_nor *nor, co JEDEC_MFR(info) == SNOR_MFR_INTEL || JEDEC_MFR(info) == SNOR_MFR_MACRONIX || JEDEC_MFR(info) == SNOR_MFR_SST || @@ -25,7 +25,7 @@ Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> info->flags & SPI_NOR_HAS_LOCK) { write_enable(nor); write_sr(nor, 0); -@@ -2735,7 +2736,8 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -2728,7 +2729,8 @@ int spi_nor_scan(struct spi_nor *nor, co /* NOR protection support for STmicro/Micron chips and similar */ if (JEDEC_MFR(info) == SNOR_MFR_MICRON || diff --git a/target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch b/target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch index 10db289cc9..88775041ce 100644 --- a/target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch +++ b/target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch @@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> depends on ARCH_AT91 || (ARM && COMPILE_TEST) --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -2562,10 +2562,12 @@ static int spi_nor_select_erase(struct s +@@ -2555,10 +2555,12 @@ static int spi_nor_select_erase(struct s #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS /* prefer "small sector" erase if possible */ diff --git a/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch b/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch index bc5418bab2..5f939e3e40 100644 --- a/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch +++ b/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch @@ -38,7 +38,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org> obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o --- /dev/null +++ b/drivers/spi/spi-mt7621.c -@@ -0,0 +1,483 @@ +@@ -0,0 +1,491 @@ +/* + * spi-mt7621.c -- MediaTek MT7621 SPI controller driver + * @@ -243,10 +243,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org> + if (t->speed_hz < speed) + speed = t->speed_hz; + -+ if (WARN_ON(len + t->len > 36)) { -+ status = -EIO; -+ goto msg_done; -+ } ++ /* ++ * m25p80 might attempt to write more data than we can handle. ++ * truncate the message to what we can fit into the registers ++ */ ++ if (len + t->len > 36) ++ t->len = 36 - len; + + for (i = 0; i < t->len; i++, len++) + data[len / 4] |= buf[i] << (8 * (len & 3)); @@ -426,6 +428,11 @@ Signed-off-by: John Crispin <blogic@openwrt.org> +}; +MODULE_DEVICE_TABLE(of, mt7621_spi_match); + ++static size_t mt7621_max_transfer_size(struct spi_device *spi) ++{ ++ return 32; ++} ++ +static int mt7621_spi_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; @@ -472,6 +479,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org> + master->bits_per_word_mask = SPI_BPW_MASK(8); + master->dev.of_node = pdev->dev.of_node; + master->num_chipselect = 2; ++ master->max_transfer_size = mt7621_max_transfer_size; + + dev_set_drvdata(&pdev->dev, master); + diff --git a/target/linux/ramips/patches-4.14/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch b/target/linux/ramips/patches-4.14/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch index 6ee0845ffe..b8819e53e1 100644 --- a/target/linux/ramips/patches-4.14/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch +++ b/target/linux/ramips/patches-4.14/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch @@ -165,7 +165,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> for (i = 0; i < len; ) { ssize_t written; loff_t addr = to + i; -@@ -1392,6 +1463,7 @@ static int spi_nor_write(struct mtd_info +@@ -1385,6 +1456,7 @@ static int spi_nor_write(struct mtd_info } write_err: @@ -173,7 +173,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); return ret; } -@@ -2808,8 +2880,10 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -2801,8 +2873,10 @@ int spi_nor_scan(struct spi_nor *nor, co } else if (mtd->size > 0x1000000) { /* enable 4-byte addressing if the device exceeds 16MiB */ nor->addr_width = 4; diff --git a/target/linux/ramips/patches-4.14/0054-mtd-add-chunked-read-io-to-m25p80.patch b/target/linux/ramips/patches-4.14/0054-mtd-add-chunked-read-io-to-m25p80.patch deleted file mode 100644 index b20f081afe..0000000000 --- a/target/linux/ramips/patches-4.14/0054-mtd-add-chunked-read-io-to-m25p80.patch +++ /dev/null @@ -1,124 +0,0 @@ ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -1468,6 +1468,67 @@ write_err: - return ret; - } - -+static int spi_nor_chunked_write(struct mtd_info *mtd, loff_t _to, size_t _len, -+ size_t *_retlen, const u_char *_buf) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ u32 addr_width = nor->addr_width + !!(nor->flags & SNOR_F_4B_EXT_ADDR); -+ int chunk_size; -+ int retlen = 0; -+ int ret; -+ -+ chunk_size = nor->chunk_size; -+ if (!chunk_size) -+ chunk_size = _len; -+ -+ if (addr_width > 3) -+ chunk_size -= addr_width - 3; -+ -+ while (retlen < _len) { -+ size_t len = min_t(int, chunk_size, _len - retlen); -+ const u_char *buf = _buf + retlen; -+ loff_t to = _to + retlen; -+ -+ if (nor->flags & SNOR_F_SST) -+ ret = sst_write(mtd, to, len, &retlen, buf); -+ else -+ ret = spi_nor_write(mtd, to, len, &retlen, buf); -+ if (ret) -+ return ret; -+ } -+ -+ *_retlen += retlen; -+ return 0; -+} -+ -+static int spi_nor_chunked_read(struct mtd_info *mtd, loff_t _from, size_t _len, -+ size_t *_retlen, u_char *_buf) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ int chunk_size; -+ int ret; -+ -+ chunk_size = nor->chunk_size; -+ if (!chunk_size) -+ chunk_size = _len; -+ -+ *_retlen = 0; -+ while (*_retlen < _len) { -+ size_t len = min_t(int, chunk_size, _len - *_retlen); -+ u_char *buf = _buf + *_retlen; -+ loff_t from = _from + *_retlen; -+ int retlen = 0; -+ -+ ret = spi_nor_read(mtd, from, len, &retlen, buf); -+ if (ret) -+ return ret; -+ -+ *_retlen += retlen; -+ } -+ -+ return 0; -+} -+ - /** - * macronix_quad_enable() - set QE bit in Status Register. - * @nor: pointer to a 'struct spi_nor' -@@ -2826,10 +2887,12 @@ int spi_nor_scan(struct spi_nor *nor, co - } - - /* sst nor chips use AAI word program */ -- if (info->flags & SST_WRITE) -+ if (info->flags & SST_WRITE) { - mtd->_write = sst_write; -- else -+ nor->flags |= SNOR_F_SST; -+ } else { - mtd->_write = spi_nor_write; -+ } - - if (info->flags & USE_FSR) - nor->flags |= SNOR_F_USE_FSR; -@@ -2848,11 +2911,20 @@ int spi_nor_scan(struct spi_nor *nor, co - mtd->writebufsize = nor->page_size; - - if (np) { -+ u32 val; -+ - /* If we were instantiated by DT, use it */ - if (of_property_read_bool(np, "m25p,fast-read")) - params.hwcaps.mask |= SNOR_HWCAPS_READ_FAST; - else - params.hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST; -+ -+ if (!of_property_read_u32(np, "m25p,chunked-io", &val)) { -+ dev_info(dev, "using chunked io (size=%d)\n", val); -+ mtd->_read = spi_nor_chunked_read; -+ mtd->_write = spi_nor_chunked_write; -+ nor->chunk_size = val; -+ } - } else { - /* If we weren't instantiated by DT, default to fast-read */ - params.hwcaps.mask |= SNOR_HWCAPS_READ_FAST; ---- a/include/linux/mtd/spi-nor.h -+++ b/include/linux/mtd/spi-nor.h -@@ -231,6 +231,7 @@ enum spi_nor_option_flags { - SNOR_F_READY_XSR_RDY = BIT(4), - SNOR_F_USE_CLSR = BIT(5), - SNOR_F_4B_EXT_ADDR = BIT(6), -+ SNOR_F_SST = BIT(7), - }; - - /** -@@ -272,6 +273,7 @@ struct spi_nor { - struct mutex lock; - struct device *dev; - u32 page_size; -+ size_t chunk_size; - u8 addr_width; - u8 erase_opcode; - u8 read_opcode; diff --git a/target/linux/ramips/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx66l51235l.patch b/target/linux/ramips/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx66l51235l.patch index 7b13e68d8f..ea8d83d98e 100644 --- a/target/linux/ramips/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx66l51235l.patch +++ b/target/linux/ramips/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx66l51235l.patch @@ -9,56 +9,3 @@ { "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { "mx66l1g45g", INFO(0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, -@@ -1947,7 +1947,11 @@ static int spi_nor_read_sfdp(struct spi_ - nor->read_dummy = 8; - - while (len) { -- ret = nor->read(nor, addr, len, (u8 *)buf); -+ size_t _len = len; -+ -+ if (nor->chunk_size) -+ _len = min(len, nor->chunk_size); -+ ret = nor->read(nor, addr, _len, (u8 *)buf); - if (!ret || ret > len) { - ret = -EIO; - goto read_err; -@@ -2791,6 +2795,7 @@ int spi_nor_scan(struct spi_nor *nor, co - struct device *dev = nor->dev; - struct mtd_info *mtd = &nor->mtd; - struct device_node *np = spi_nor_get_flash_node(nor); -+ u32 val; - int ret; - int i; - -@@ -2803,6 +2808,9 @@ int spi_nor_scan(struct spi_nor *nor, co - nor->read_proto = SNOR_PROTO_1_1_1; - nor->write_proto = SNOR_PROTO_1_1_1; - -+ if (np && !of_property_read_u32(np, "m25p,chunked-io", &val)) -+ nor->chunk_size = val; -+ - if (name) - info = spi_nor_match_id(name); - /* Try to auto-detect if chip name wasn't specified or not found */ -@@ -2916,19 +2924,16 @@ int spi_nor_scan(struct spi_nor *nor, co - mtd->writebufsize = nor->page_size; - - if (np) { -- u32 val; -- - /* If we were instantiated by DT, use it */ - if (of_property_read_bool(np, "m25p,fast-read")) - params.hwcaps.mask |= SNOR_HWCAPS_READ_FAST; - else - params.hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST; - -- if (!of_property_read_u32(np, "m25p,chunked-io", &val)) { -- dev_info(dev, "using chunked io (size=%d)\n", val); -+ if (nor->chunk_size) { -+ dev_info(dev, "using chunked io (size=%d)\n", nor->chunk_size); - mtd->_read = spi_nor_chunked_read; - mtd->_write = spi_nor_chunked_write; -- nor->chunk_size = val; - } - } else { - /* If we weren't instantiated by DT, default to fast-read */ |