aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
authorMark Brown <broonie@kernel.org>2026-05-29 22:36:56 +0100
committerMark Brown <broonie@kernel.org>2026-05-29 22:36:56 +0100
commit7a822a9dd6e98ccec31f0f02bd4db6252ed7f188 (patch)
tree4eeac637b212b37270f2fff28487531e1eef3f74 /Documentation
parentd1304489d366f4f5afa7dd9643344b38bca94976 (diff)
parentdf415c5e1de0f1aeefacb4e6252ff98d38c04437 (diff)
downloadlinux-next-history-7a822a9dd6e98ccec31f0f02bd4db6252ed7f188.tar.gz
Merge branch 'spi-nor/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/driver-api/mtd/spi-nor.rst170
1 files changed, 170 insertions, 0 deletions
diff --git a/Documentation/driver-api/mtd/spi-nor.rst b/Documentation/driver-api/mtd/spi-nor.rst
index 148fa4288760b..747a326fb6c0d 100644
--- a/Documentation/driver-api/mtd/spi-nor.rst
+++ b/Documentation/driver-api/mtd/spi-nor.rst
@@ -203,3 +203,173 @@ section, after the ``---`` marker.
mtd.writesize = 1
mtd.oobsize = 0
regions = 0
+
+5) If your flash supports locking, please go through the following test
+ procedure to make sure it correctly behaves. The below example
+ expects the typical situation where eraseblocks and lock sectors have
+ the same size. In case you enabled MTD_SPI_NOR_USE_4K_SECTORS, you
+ must adapt `bs` accordingly.
+
+ Warning: These tests may hard lock your device! Make sure:
+
+ - The device is not hard locked already (#WP strapped to low and
+ SR_SRWD bit set)
+ - If you have a WPn pin, you may want to set `no-wp` in your DT for
+ the time of the test, to only make use of software protection.
+ Otherwise, clearing the locking state depends on the WPn
+ signal and if it is tied to low, the flash will be permanently
+ locked.
+
+ Test full chip locking and make sure expectations, the MEMISLOCKED
+ ioctl output, the debugfs output and experimental results are all
+ aligned::
+
+ root@1:~# alias show_sectors='grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ root@1:~# flash_lock -u /dev/mtd0
+ root@1:~# flash_lock -i /dev/mtd0
+ Device: /dev/mtd0
+ Start: 0
+ Len: 0x4000000
+ Lock status: unlocked
+ Return code: 0
+ root@1:~# mtd_debug erase /dev/mtd0 0 2097152
+ Erased 2097152 bytes from address 0x00000000 in flash
+ root@1:~# mtd_debug write /dev/mtd0 0 2097152 spi_test
+ Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read
+ Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ root@1:~# sha256sum spi*
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_read
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_test
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-03ffffff | unlocked | 1024
+
+ root@1:~# flash_lock -l /dev/mtd0
+ root@1:~# flash_lock -i /dev/mtd0
+ Device: /dev/mtd0
+ Start: 0
+ Len: 0x4000000
+ Lock status: locked
+ Return code: 1
+ root@1:~# mtd_debug erase /dev/mtd0 0 2097152
+ Erased 2097152 bytes from address 0x00000000 in flash
+ root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read
+ Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ root@1:~# sha256sum spi*
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_read
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_test
+ root@1:~# dd if=/dev/urandom of=./spi_test2 bs=1M count=2
+ 2+0 records in
+ 2+0 records out
+ root@1:~# mtd_debug write /dev/mtd0 0 2097152 spi_test2
+ Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read2
+ Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ root@1:~# sha256sum spi*
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_read
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_read2
+ c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_test
+ bea9334df51c620440f86751cba0799214a016329f1736f9456d40cf40efdc88 spi_test2
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-03ffffff | locked | 1024
+ root@1:~# flash_lock -u /dev/mtd0
+
+ Once we trust the debugfs output we can use it to test various
+ situations. Check top locking/unlocking (end of the device)::
+
+ root@1:~# size=$(cat /sys/class/mtd/mtd0/size)
+ root@1:~# bs=$(cat /sys/class/mtd/mtd0/erasesize)
+ root@1:~# nsectors=$(grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params | sed -e 's/.*unlocked | //')
+ root@1:~# ss=$(($size / $nsectors))
+ root@1:~# bps=$(($ss / $bs))
+
+ root@1:~# flash_lock -u /dev/mtd0
+ root@1:~# flash_lock -l /dev/mtd0 $(($size - (2 * $ss))) $((2 * $bps)) # last two
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-03fdffff | unlocked | 1022
+ 03fe0000-03ffffff | locked | 2
+ root@1:~# flash_lock -u /dev/mtd0 $(($size - (2 * $ss))) $((1 * $bps)) # last one
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-03feffff | unlocked | 1023
+ 03ff0000-03ffffff | locked | 1
+
+ If the flash features 4 block protection bits (BP), we can protect
+ more than 4MB (typically 128 64kiB-blocks or more), with a finer
+ grain than locking the entire device::
+
+ root@1:~# flash_lock -u /dev/mtd0
+ root@1:~# flash_lock -l /dev/mtd0 $(($size - (2**7 * $ss))) $((2**7 * $bps))
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-037fffff | unlocked | 896
+ 03800000-03ffffff | locked | 128
+
+ If the flash features a Top/Bottom (TB) bit, we can protect the
+ beginning of the flash::
+
+ root@1:~# flash_lock -u /dev/mtd0
+ root@1:~# flash_lock -l /dev/mtd0 0 $((2 * $bps)) # first two
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-0001ffff | locked | 2
+ 00020000-03ffffff | unlocked | 1022
+ root@1:~# flash_lock -u /dev/mtd0 $ss $((1 * $bps)) # first one
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-0000ffff | locked | 1
+ 00010000-03ffffff | unlocked | 1023
+
+ If the flash features a Complement (CMP) bit, we can protect with
+ more granularity above half of the capacity. Let's lock all but one
+ block, then unlock one more block::
+
+ root@1:~# all_but_one=$((($size / $bs) - ($ss / $bs)))
+
+ root@1:~# flash_lock -u /dev/mtd0
+ root@1:~# flash_lock -l /dev/mtd0 $ss $all_but_one # all but the first
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-0000ffff | unlocked | 1
+ 00010000-03ffffff | locked | 1023
+ root@1:~# flash_lock -u /dev/mtd0 $ss $(($ss / $bs)) # all but the two first
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-0001ffff | unlocked | 2
+ 00020000-03ffffff | locked | 1022
+ root@1:~# flash_lock -u /dev/mtd0
+ root@1:~# flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-03feffff | locked | 1023
+ 03ff0000-03ffffff | unlocked | 1
+ root@1:~# flash_lock -u /dev/mtd0 $(($size - (2 * $ss))) $(($ss / $bs)) # all but two
+ root@1:~# show_sectors
+ software locked sectors
+ region (in hex) | status | #sectors
+ ------------------+----------+---------
+ 00000000-03fdffff | locked | 1022
+ 03fe0000-03ffffff | unlocked | 2