mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2025-05-22 22:27:56 +00:00
Manually rebuild pending patches: - 103-kbuild-export-SUBARCH.patch - 141-jffs2-add-RENAME_EXCHANGE-support.patch - 200-ARM-9404-1-arm32-fix-boot-hang-with-HAVE_LD_DEAD_COD.patch - 203-kallsyms_uncompressed.patch - 270-platform-mikrotik-build-bits.patch - 308-mips32r2_tune.patch - 330-MIPS-kexec-Accept-command-line-parameters-from-users.patch - 402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch - 451-block-partitions-populate-fwnode.patch - 476-mtd-spi-nor-add-eon-en25q128.patch - 477-mtd-spi-nor-add-eon-en25qx128a.patch - 479-mtd-spi-nor-add-xtx-xt25f128b.patch - 481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch - 482-mtd-spi-nor-add-gd25q512.patch - 484-mtd-spi-nor-add-esmt-f25l16pa.patch - 485-mtd-spi-nor-add-xmc-xm25qh128c.patch - 488-mtd-spi-nor-add-xmc-xm25qh64c.patch - 490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch - 497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch - 498-mtd-spi-nor-locking-support-for-MX25L6405D.patch - 510-block-add-uImage.FIT-subimage-block-driver.patch - 530-jffs2_make_lzma_available.patch - 630-packet_socket_type.patch - 666-Add-support-for-MAP-E-FMRs-mesh-mode.patch - 681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch - 700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch - 702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch - 706-net-phy-populate-host_interfaces-when-attaching-PHY.patch - 711-03-net-dsa-qca8k-add-support-for-port_change_master.patch - 734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch - 736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch - 737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch - 739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch - 801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch - 809-01-nvmem-core-generalize-mac-base-cells-handling.patch - 811-pci_disable_usb_common_quirks.patch - 834-ledtrig-libata.patch - 892-leds-Add-LED1202-I2C-driver.patch - 920-mangle_bootargs.patch Co-authored-by: Aditya Nugraha <vortexilation@gmail.com> Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com> [ improve commit title + minor fixes ] Link: https://github.com/openwrt/openwrt/pull/16547 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
246 lines
8.2 KiB
Diff
246 lines
8.2 KiB
Diff
From acacdac272927ae1d96e0bca51eb82899671eaea Mon Sep 17 00:00:00 2001
|
|
From: John Thomson <git@johnthomson.fastmail.com.au>
|
|
Date: Fri, 25 Dec 2020 18:50:08 +1000
|
|
Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Do not prevent writing to mtd partitions where a partition boundary sits
|
|
on a minor erasesize boundary.
|
|
This addresses a FIXME that has been present since the start of the
|
|
linux git history:
|
|
/* Doesn't start on a boundary of major erase size */
|
|
/* FIXME: Let it be writable if it is on a boundary of
|
|
* _minor_ erase size though */
|
|
|
|
Allow a uniform erase region spi-nor device to be configured
|
|
to use the non-uniform erase regions code path for an erase with:
|
|
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
|
|
|
|
On supporting hardware (SECT_4K: majority of current SPI-NOR device)
|
|
provide the facility for an erase to use the least number
|
|
of SPI-NOR operations, as well as access to 4K erase without
|
|
requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
|
|
|
|
Introduce erasesize_minor to the mtd struct,
|
|
the smallest erasesize supported by the device
|
|
|
|
On existing devices, this is useful where write support is wanted
|
|
for data on a 4K partition, such as some u-boot-env partitions,
|
|
or RouterBoot soft_config, while still netting the performance
|
|
benefits of using 64K sectors
|
|
|
|
Performance:
|
|
time mtd erase firmware
|
|
OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length
|
|
|
|
Without this patch
|
|
MTD_SPI_NOR_USE_4K_SECTORS=y |n
|
|
real 2m 11.66s |0m 50.86s
|
|
user 0m 0.00s |0m 0.00s
|
|
sys 1m 56.20s |0m 50.80s
|
|
|
|
With this patch
|
|
MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y
|
|
real 0m 51.68s |0m 50.85s |2m 12.89s
|
|
user 0m 0.00s |0m 0.00s |0m 0.01s
|
|
sys 0m 46.94s |0m 50.38s |2m 12.46s
|
|
|
|
Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
|
|
Signed-off-by: Thibaut VARÈNE <hacks+kernel@slashdirt.org>
|
|
|
|
---
|
|
|
|
checkpatch does not like the printk(KERN_WARNING
|
|
these should be changed separately beforehand?
|
|
|
|
Changes v1 -> v2:
|
|
Added mtdcore sysfs for erasesize_minor
|
|
Removed finding minor erasesize for variable erase regions device,
|
|
as untested and no responses regarding it.
|
|
Moved IF_ENABLED for SPINOR variable erase to guard setting
|
|
erasesize_minor in spi-nor/core.c
|
|
Removed setting erasesize to minor where partition boundaries require
|
|
minor erase to be writable
|
|
Simplified minor boundary check by relying on minor being a factor of
|
|
major
|
|
|
|
Changes RFC -> v1:
|
|
Fix uninitialized variable smatch warning
|
|
Reported-by: kernel test robot <lkp@intel.com>
|
|
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
|
|
---
|
|
drivers/mtd/mtdcore.c | 10 ++++++++++
|
|
drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++----------
|
|
drivers/mtd/spi-nor/Kconfig | 10 ++++++++++
|
|
drivers/mtd/spi-nor/core.c | 11 +++++++++--
|
|
include/linux/mtd/mtd.h | 2 ++
|
|
5 files changed, 56 insertions(+), 12 deletions(-)
|
|
|
|
--- a/drivers/mtd/mtdcore.c
|
|
+++ b/drivers/mtd/mtdcore.c
|
|
@@ -199,6 +199,15 @@ static ssize_t mtd_erasesize_show(struct
|
|
}
|
|
MTD_DEVICE_ATTR_RO(erasesize);
|
|
|
|
+static ssize_t mtd_erasesize_minor_show(struct device *dev,
|
|
+ struct device_attribute *attr, char *buf)
|
|
+{
|
|
+ struct mtd_info *mtd = dev_get_drvdata(dev);
|
|
+
|
|
+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor);
|
|
+}
|
|
+MTD_DEVICE_ATTR_RO(erasesize_minor);
|
|
+
|
|
static ssize_t mtd_writesize_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
@@ -344,6 +353,7 @@ static struct attribute *mtd_attrs[] = {
|
|
&dev_attr_flags.attr,
|
|
&dev_attr_size.attr,
|
|
&dev_attr_erasesize.attr,
|
|
+ &dev_attr_erasesize_minor.attr,
|
|
&dev_attr_writesize.attr,
|
|
&dev_attr_subpagesize.attr,
|
|
&dev_attr_oobsize.attr,
|
|
--- a/drivers/mtd/mtdpart.c
|
|
+++ b/drivers/mtd/mtdpart.c
|
|
@@ -47,6 +47,7 @@ static struct mtd_info *allocate_partiti
|
|
struct mtd_info *master = mtd_get_master(parent);
|
|
int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
|
|
master->writesize : master->erasesize;
|
|
+ int wr_alignment_minor = 0;
|
|
u64 parent_size = mtd_is_partition(parent) ?
|
|
parent->part.size : parent->size;
|
|
struct mtd_info *child;
|
|
@@ -171,6 +172,7 @@ static struct mtd_info *allocate_partiti
|
|
} else {
|
|
/* Single erase size */
|
|
child->erasesize = master->erasesize;
|
|
+ child->erasesize_minor = master->erasesize_minor;
|
|
}
|
|
|
|
/*
|
|
@@ -178,26 +180,39 @@ static struct mtd_info *allocate_partiti
|
|
* exposes several regions with different erasesize. Adjust
|
|
* wr_alignment accordingly.
|
|
*/
|
|
- if (!(child->flags & MTD_NO_ERASE))
|
|
+ if (!(child->flags & MTD_NO_ERASE)) {
|
|
wr_alignment = child->erasesize;
|
|
+ wr_alignment_minor = child->erasesize_minor;
|
|
+ }
|
|
|
|
tmp = mtd_get_master_ofs(child, 0);
|
|
remainder = do_div(tmp, wr_alignment);
|
|
if ((child->flags & MTD_WRITEABLE) && remainder) {
|
|
- /* Doesn't start on a boundary of major erase size */
|
|
- /* FIXME: Let it be writable if it is on a boundary of
|
|
- * _minor_ erase size though */
|
|
- child->flags &= ~MTD_WRITEABLE;
|
|
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
|
|
- part->name);
|
|
+ if (wr_alignment_minor) {
|
|
+ /* rely on minor being a factor of major erasesize */
|
|
+ tmp = remainder;
|
|
+ remainder = do_div(tmp, wr_alignment_minor);
|
|
+ }
|
|
+ if (remainder) {
|
|
+ child->flags &= ~MTD_WRITEABLE;
|
|
+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
|
|
+ part->name);
|
|
+ }
|
|
}
|
|
|
|
tmp = mtd_get_master_ofs(child, 0) + child->part.size;
|
|
remainder = do_div(tmp, wr_alignment);
|
|
if ((child->flags & MTD_WRITEABLE) && remainder) {
|
|
- child->flags &= ~MTD_WRITEABLE;
|
|
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
|
|
- part->name);
|
|
+ if (wr_alignment_minor) {
|
|
+ tmp = remainder;
|
|
+ remainder = do_div(tmp, wr_alignment_minor);
|
|
+ }
|
|
+
|
|
+ if (remainder) {
|
|
+ child->flags &= ~MTD_WRITEABLE;
|
|
+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
|
|
+ part->name);
|
|
+ }
|
|
}
|
|
|
|
child->size = child->part.size;
|
|
--- a/drivers/mtd/spi-nor/Kconfig
|
|
+++ b/drivers/mtd/spi-nor/Kconfig
|
|
@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR
|
|
|
|
if MTD_SPI_NOR
|
|
|
|
+config MTD_SPI_NOR_USE_VARIABLE_ERASE
|
|
+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes"
|
|
+ depends on !MTD_SPI_NOR_USE_4K_SECTORS
|
|
+ default n
|
|
+ help
|
|
+ Allow mixed use of all hardware supported erasesizes,
|
|
+ by forcing spi_nor to use the multiple eraseregions code path.
|
|
+ For example: A 68K erase will use one 64K erase, and one 4K erase
|
|
+ on supporting hardware.
|
|
+
|
|
config MTD_SPI_NOR_USE_4K_SECTORS
|
|
bool "Use small 4096 B erase sectors"
|
|
default y
|
|
--- a/drivers/mtd/spi-nor/core.c
|
|
+++ b/drivers/mtd/spi-nor/core.c
|
|
@@ -1158,6 +1158,8 @@ static u8 spi_nor_convert_3to4_erase(u8
|
|
|
|
static bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
|
|
{
|
|
+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE))
|
|
+ return false;
|
|
return !!nor->params->erase_map.uniform_region.erase_mask;
|
|
}
|
|
|
|
@@ -2516,6 +2518,7 @@ static int spi_nor_select_erase(struct s
|
|
{
|
|
struct spi_nor_erase_map *map = &nor->params->erase_map;
|
|
const struct spi_nor_erase_type *erase = NULL;
|
|
+ const struct spi_nor_erase_type *erase_minor = NULL;
|
|
struct mtd_info *mtd = &nor->mtd;
|
|
int i;
|
|
|
|
@@ -2542,8 +2545,9 @@ static int spi_nor_select_erase(struct s
|
|
*/
|
|
for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
|
|
if (map->erase_type[i].size) {
|
|
- erase = &map->erase_type[i];
|
|
- break;
|
|
+ if (!erase)
|
|
+ erase = &map->erase_type[i];
|
|
+ erase_minor = &map->erase_type[i];
|
|
}
|
|
}
|
|
|
|
@@ -2551,6 +2555,9 @@ static int spi_nor_select_erase(struct s
|
|
return -EINVAL;
|
|
|
|
mtd->erasesize = erase->size;
|
|
+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) &&
|
|
+ erase_minor && erase_minor->size < erase->size)
|
|
+ mtd->erasesize_minor = erase_minor->size;
|
|
return 0;
|
|
}
|
|
|
|
--- a/include/linux/mtd/mtd.h
|
|
+++ b/include/linux/mtd/mtd.h
|
|
@@ -245,6 +245,8 @@ struct mtd_info {
|
|
* information below if they desire
|
|
*/
|
|
uint32_t erasesize;
|
|
+ /* "Minor" (smallest) erase size supported by the whole device */
|
|
+ uint32_t erasesize_minor;
|
|
/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
|
|
* though individual bits can be cleared), in case of NAND flash it is
|
|
* one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
|