ramips: remove chunked-io patch and set spi->max_transfer_size instead
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
46c49d8381
commit
bcf4a5f474
8 changed files with 55 additions and 188 deletions
|
@ -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:
|
|
@ -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 ||
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
+
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue