Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mtd/for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux

Pull MTD updates from Miquel Raynal:
"MTD:

- prioritize ofpart in physmap-core probing

- conversions to scoped for each OF child loops

Bindings:

- The bulk of the changes consists of binding fixes/updates to
restrict the use of undefined properties, which was mostly
ineffective in the current form because of the nesting of partition
nodes and the lack of compatible strings

- YAML conversions and the addition of a dma-coherent property in the
cdns,hp-nfc driver

SPI NAND:

- support for octal DTR modes (8D-8D-8D)

- support for Foresee F35SQB002G chips

And small misc fixes"

* tag 'mtd/for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (65 commits)
mtd: spi-nor: hisi-sfc: fix refcounting bug in hisi_spi_nor_register_all()
mtd: spinand: fix NULL pointer dereference in spinand_support_vendor_ops()
mtd: rawnand: pl353: Add message about ECC mode
mtd: rawnand: pl353: Fix software ECC support
mtd: spinand: winbond: Remove unneeded semicolon
dt-bindings: mtd: cdns,hp-nfc: Add dma-coherent property
mtd: spinand: Disable continuous read during probe
mtd: spinand: add Foresee F35SQB002G flash support
mtd: spinand: winbond: W35N octal DTR support
mtd: spinand: Add octal DTR support
mtd: spinand: Warn if using SSDR-only vendor commands in a non SSDR mode
mtd: spinand: Give the bus interface to the configuration helper
mtd: spinand: Propagate the bus interface across core helpers
mtd: spinand: Add support for setting a bus interface
mtd: spinand: Gather all the bus interface steps in one single function
mtd: spinand: winbond: Configure the IO mode after the dummy cycles
mtd: spinand: winbond: Rename IO_MODE register macro
mtd: spinand: winbond: Fix style
mtd: spinand: winbond: Register W35N vendor specific operation
mtd: spinand: winbond: Register W25N vendor specific operation
...

+1292 -608
+6 -14
Documentation/devicetree/bindings/mmc/mmc-card.yaml
··· 32 32 33 33 patternProperties: 34 34 "^partitions(-boot[12]|-gp[14])?$": 35 - $ref: /schemas/mtd/partitions/partitions.yaml 35 + type: object 36 + additionalProperties: true 36 37 37 - patternProperties: 38 - "^partition@[0-9a-f]+$": 39 - $ref: /schemas/mtd/partitions/partition.yaml 40 - 41 - properties: 42 - reg: 43 - description: Must be multiple of 512 as it's converted 44 - internally from bytes to SECTOR_SIZE (512 bytes) 45 - 46 - required: 47 - - reg 48 - 49 - unevaluatedProperties: false 38 + properties: 39 + compatible: 40 + contains: 41 + const: fixed-partitions 50 42 51 43 required: 52 44 - compatible
-1
Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
··· 66 66 items: 67 67 - const: brcm,nand-iproc 68 68 - const: brcm,brcmnand-v6.1 69 - - const: brcm,brcmnand 70 69 - description: BCM63168 SoC-specific NAND controller 71 70 items: 72 71 - const: brcm,nand-bcm63168
+2
Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml
··· 40 40 dmas: 41 41 maxItems: 1 42 42 43 + dma-coherent: true 44 + 43 45 iommus: 44 46 maxItems: 1 45 47
-18
Documentation/devicetree/bindings/mtd/microchip,mchp23k256.txt
··· 1 - * MTD SPI driver for Microchip 23K256 (and similar) serial SRAM 2 - 3 - Required properties: 4 - - #address-cells, #size-cells : Must be present if the device has sub-nodes 5 - representing partitions. 6 - - compatible : Must be one of "microchip,mchp23k256" or "microchip,mchp23lcv1024" 7 - - reg : Chip-Select number 8 - - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at 9 - 10 - Example: 11 - 12 - spi-sram@0 { 13 - #address-cells = <1>; 14 - #size-cells = <1>; 15 - compatible = "microchip,mchp23k256"; 16 - reg = <0>; 17 - spi-max-frequency = <20000000>; 18 - };
+49
Documentation/devicetree/bindings/mtd/microchip,mchp23k256.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mtd/microchip,mchp23k256.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Microchip 23K256 SPI SRAM 8 + 9 + maintainers: 10 + - Richard Weinberger <richard@nod.at> 11 + 12 + description: 13 + The Microchip 23K256 is a 256 Kbit (32 Kbyte) serial SRAM with an 14 + SPI interface,supporting clock frequencies up to 20 MHz. It features 15 + a 32-byte page size for writes and supports byte, page, and 16 + sequential access modes. 17 + 18 + allOf: 19 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 20 + 21 + properties: 22 + compatible: 23 + enum: 24 + - microchip,mchp23k256 25 + - microchip,mchp23lcv1024 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + required: 31 + - reg 32 + - compatible 33 + - spi-max-frequency 34 + 35 + unevaluatedProperties: false 36 + 37 + examples: 38 + - | 39 + spi { 40 + #address-cells = <1>; 41 + #size-cells = <0>; 42 + 43 + sram@0 { 44 + compatible = "microchip,mchp23k256"; 45 + reg = <0>; 46 + spi-max-frequency = <20000000>; 47 + }; 48 + }; 49 + ...
+3 -7
Documentation/devicetree/bindings/mtd/mtd.yaml
··· 30 30 deprecated: true 31 31 32 32 partitions: 33 - $ref: /schemas/mtd/partitions/partitions.yaml 33 + type: object 34 34 35 35 required: 36 36 - compatible 37 37 38 38 patternProperties: 39 - "@[0-9a-f]+$": 40 - $ref: partitions/partition.yaml 41 - deprecated: true 42 - 43 - "^partition@[0-9a-f]+": 44 - $ref: partitions/partition.yaml 39 + "(^partition)?@[0-9a-f]+$": 40 + $ref: /schemas/mtd/partitions/partition.yaml#/$defs/partition-node 45 41 deprecated: true 46 42 47 43 "^otp(-[0-9]+)?$":
+78
Documentation/devicetree/bindings/mtd/mxic,multi-itfc-v009-nand-controller.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/mtd/mxic,multi-itfc-v009-nand-controller.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Macronix Raw NAND Controller 9 + 10 + maintainers: 11 + - Mason Yang <masonccyang@mxic.com.tw> 12 + 13 + description: 14 + The Macronix Multi-Interface Raw NAND Controller is a versatile flash 15 + memory controller for embedding in SoCs, capable of interfacing with 16 + various NAND devices. It requires dedicated clock inputs for core, data 17 + transmit, and delayed transmit paths along with register space and an 18 + interrupt line for operation. 19 + 20 + allOf: 21 + - $ref: nand-controller.yaml# 22 + 23 + properties: 24 + compatible: 25 + const: mxic,multi-itfc-v009-nand-controller 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + interrupts: 31 + maxItems: 1 32 + 33 + "#address-cells": 34 + const: 1 35 + 36 + "#size-cells": 37 + const: 0 38 + 39 + clocks: 40 + minItems: 3 41 + maxItems: 3 42 + 43 + clock-names: 44 + items: 45 + - const: ps 46 + - const: send 47 + - const: send_dly 48 + 49 + required: 50 + - compatible 51 + - reg 52 + - interrupts 53 + - "#address-cells" 54 + - "#size-cells" 55 + - clocks 56 + - clock-names 57 + 58 + unevaluatedProperties: false 59 + 60 + examples: 61 + - | 62 + #include <dt-bindings/interrupt-controller/arm-gic.h> 63 + nand-controller@43c30000 { 64 + compatible = "mxic,multi-itfc-v009-nand-controller"; 65 + reg = <0x43c30000 0x10000>; 66 + #address-cells = <1>; 67 + #size-cells = <0>; 68 + interrupts = <GIC_SPI 0x1d IRQ_TYPE_EDGE_RISING>; 69 + clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 15>; 70 + clock-names = "ps", "send", "send_dly"; 71 + 72 + nand@0 { 73 + reg = <0>; 74 + nand-ecc-mode = "soft"; 75 + nand-ecc-algo = "bch"; 76 + }; 77 + }; 78 + ...
-36
Documentation/devicetree/bindings/mtd/mxic-nand.txt
··· 1 - Macronix Raw NAND Controller Device Tree Bindings 2 - ------------------------------------------------- 3 - 4 - Required properties: 5 - - compatible: should be "mxic,multi-itfc-v009-nand-controller" 6 - - reg: should contain 1 entry for the registers 7 - - #address-cells: should be set to 1 8 - - #size-cells: should be set to 0 9 - - interrupts: interrupt line connected to this raw NAND controller 10 - - clock-names: should contain "ps", "send" and "send_dly" 11 - - clocks: should contain 3 phandles for the "ps", "send" and 12 - "send_dly" clocks 13 - 14 - Children nodes: 15 - - children nodes represent the available NAND chips. 16 - 17 - See Documentation/devicetree/bindings/mtd/nand-controller.yaml 18 - for more details on generic bindings. 19 - 20 - Example: 21 - 22 - nand: nand-controller@43c30000 { 23 - compatible = "mxic,multi-itfc-v009-nand-controller"; 24 - reg = <0x43c30000 0x10000>; 25 - #address-cells = <1>; 26 - #size-cells = <0>; 27 - interrupts = <GIC_SPI 0x1d IRQ_TYPE_EDGE_RISING>; 28 - clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 15>; 29 - clock-names = "send", "send_dly", "ps"; 30 - 31 - nand@0 { 32 - reg = <0>; 33 - nand-ecc-mode = "soft"; 34 - nand-ecc-algo = "bch"; 35 - }; 36 - };
-2
Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml
··· 9 9 maintainers: 10 10 - Linus Walleij <linusw@kernel.org> 11 11 12 - select: false 13 - 14 12 description: | 15 13 The ARM Firmware Suite is a flash partitioning system found on the 16 14 ARM reference designs: Integrator AP, Integrator CP, Versatile AB,
-53
Documentation/devicetree/bindings/mtd/partitions/binman.yaml
··· 1 - # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 - %YAML 1.2 3 - --- 4 - $id: http://devicetree.org/schemas/mtd/partitions/binman.yaml# 5 - $schema: http://devicetree.org/meta-schemas/core.yaml# 6 - 7 - title: Binman entries 8 - 9 - description: | 10 - This corresponds to a binman 'entry'. It is a single partition which holds 11 - data of a defined type. 12 - 13 - Binman uses the type to indicate what data file / type to place in the 14 - partition. There are quite a number of binman-specific entry types, such as 15 - section, fill and files, to be added later. 16 - 17 - maintainers: 18 - - Simon Glass <sjg@chromium.org> 19 - 20 - allOf: 21 - - $ref: /schemas/mtd/partitions/partition.yaml# 22 - 23 - properties: 24 - compatible: 25 - enum: 26 - - u-boot # u-boot.bin from U-Boot project 27 - - tfa-bl31 # bl31.bin or bl31.elf from TF-A project 28 - 29 - required: 30 - - compatible 31 - 32 - unevaluatedProperties: false 33 - 34 - examples: 35 - - | 36 - partitions { 37 - compatible = "fixed-partitions"; 38 - #address-cells = <1>; 39 - #size-cells = <1>; 40 - 41 - partition@100000 { 42 - compatible = "u-boot"; 43 - reg = <0x100000 0xf00000>; 44 - align-size = <0x1000>; 45 - align-end = <0x10000>; 46 - }; 47 - 48 - partition@200000 { 49 - compatible = "tfa-bl31"; 50 - reg = <0x200000 0x100000>; 51 - align = <0x4000>; 52 - }; 53 - };
+1 -7
Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
··· 17 17 maintainers: 18 18 - Rafał Miłecki <rafal@milecki.pl> 19 19 20 - select: false 21 - 22 20 properties: 23 21 compatible: 24 22 const: brcm,bcm4908-partitions ··· 29 31 30 32 patternProperties: 31 33 "^partition@[0-9a-f]+$": 32 - $ref: partition.yaml# 33 - properties: 34 - compatible: 35 - const: brcm,bcm4908-firmware 36 - unevaluatedProperties: false 34 + $ref: partition.yaml#/$defs/partition-node 37 35 38 36 required: 39 37 - "#address-cells"
-2
Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml
··· 35 35 maintainers: 36 36 - Rafał Miłecki <rafal@milecki.pl> 37 37 38 - select: false 39 - 40 38 properties: 41 39 compatible: 42 40 const: brcm,bcm947xx-cfe-partitions
-45
Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-imagetag.txt
··· 1 - Broadcom BCM963XX ImageTag Partition Container 2 - ============================================== 3 - 4 - Some Broadcom BCM63XX SoC based devices contain additional, non discoverable 5 - partitions or non standard bootloader partition sizes. For these a mixed layout 6 - needs to be used with an explicit firmware partition. 7 - 8 - The BCM963XX ImageTag is a simple firmware header describing the offsets and 9 - sizes of the rootfs and kernel parts contained in the firmware. 10 - 11 - Required properties: 12 - - compatible : must be "brcm,bcm963xx-imagetag" 13 - 14 - Example: 15 - 16 - flash@1e000000 { 17 - compatible = "cfi-flash"; 18 - reg = <0x1e000000 0x2000000>; 19 - bank-width = <2>; 20 - 21 - partitions { 22 - compatible = "fixed-partitions"; 23 - #address-cells = <1>; 24 - #size-cells = <1>; 25 - 26 - cfe@0 { 27 - reg = <0x0 0x10000>; 28 - read-only; 29 - }; 30 - 31 - firmware@10000 { 32 - reg = <0x10000 0x7d0000>; 33 - compatible = "brcm,bcm963xx-imagetag"; 34 - }; 35 - 36 - caldata@7e0000 { 37 - reg = <0x7e0000 0x10000>; 38 - read-only; 39 - }; 40 - 41 - nvram@7f0000 { 42 - reg = <0x7f0000 0x10000>; 43 - }; 44 - }; 45 - };
-42
Documentation/devicetree/bindings/mtd/partitions/brcm,trx.txt
··· 1 - Broadcom TRX Container Partition 2 - ================================ 3 - 4 - TRX is Broadcom's official firmware format for the BCM947xx boards. It's used by 5 - most of the vendors building devices based on Broadcom's BCM47xx SoCs and is 6 - supported by the CFE bootloader. 7 - 8 - Design of the TRX format is very minimalistic. Its header contains 9 - identification fields, CRC32 checksum and the locations of embedded partitions. 10 - Its purpose is to store a few partitions in a format that can be distributed as 11 - a standalone file and written in a flash memory. 12 - 13 - Container can hold up to 4 partitions. The first partition has to contain a 14 - device executable binary (e.g. a kernel) as it's what the CFE bootloader starts 15 - executing. Other partitions can be used for operating system purposes. This is 16 - useful for systems that keep kernel and rootfs separated. 17 - 18 - TRX doesn't enforce any strict partition boundaries or size limits. All 19 - partitions have to be less than the 4GiB max size limit. 20 - 21 - There are two existing/known TRX variants: 22 - 1) v1 which contains 3 partitions 23 - 2) v2 which contains 4 partitions 24 - 25 - There aren't separated compatible bindings for them as version can be trivialy 26 - detected by a software parsing TRX header. 27 - 28 - Required properties: 29 - - compatible : (required) must be "brcm,trx" 30 - 31 - Optional properties: 32 - 33 - - brcm,trx-magic: TRX magic, if it is different from the default magic 34 - 0x30524448 as a u32. 35 - 36 - Example: 37 - 38 - flash@0 { 39 - partitions { 40 - compatible = "brcm,trx"; 41 - }; 42 - };
+65
Documentation/devicetree/bindings/mtd/partitions/brcm,trx.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mtd/partitions/brcm,trx.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Broadcom TRX Container Partition 8 + 9 + maintainers: 10 + - Hauke Mehrtens <hauke@hauke-m.de> 11 + - Rafał Miłecki <rafal@milecki.pl> 12 + 13 + description: > 14 + TRX is Broadcom's official firmware format for the BCM947xx boards. It's used by 15 + most of the vendors building devices based on Broadcom's BCM47xx SoCs and is 16 + supported by the CFE bootloader. 17 + 18 + Design of the TRX format is very minimalistic. Its header contains 19 + identification fields, CRC32 checksum and the locations of embedded partitions. 20 + Its purpose is to store a few partitions in a format that can be distributed as 21 + a standalone file and written in a flash memory. 22 + 23 + Container can hold up to 4 partitions. The first partition has to contain a 24 + device executable binary (e.g. a kernel) as it's what the CFE bootloader starts 25 + executing. Other partitions can be used for operating system purposes. This is 26 + useful for systems that keep kernel and rootfs separated. 27 + 28 + TRX doesn't enforce any strict partition boundaries or size limits. All 29 + partitions have to be less than the 4GiB max size limit. 30 + 31 + There are two existing/known TRX variants: 32 + 1) v1 which contains 3 partitions 33 + 2) v2 which contains 4 partitions 34 + 35 + There aren't separated compatible bindings for them as version can be trivially 36 + detected by a software parsing TRX header. 37 + 38 + properties: 39 + compatible: 40 + oneOf: 41 + - items: 42 + - const: linksys,ns-firmware 43 + - const: brcm,trx 44 + - const: brcm,trx 45 + 46 + brcm,trx-magic: 47 + description: TRX magic, if it is different from the default magic. 48 + $ref: /schemas/types.yaml#/definitions/uint32 49 + default: 0x30524448 50 + 51 + required: 52 + - compatible 53 + 54 + allOf: 55 + - $ref: partition.yaml# 56 + 57 + unevaluatedProperties: false 58 + 59 + examples: 60 + - | 61 + flash { 62 + partitions { 63 + compatible = "brcm,trx"; 64 + }; 65 + };
+10 -33
Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
··· 25 25 - const: sercomm,sc-partitions 26 26 - const: fixed-partitions 27 27 28 - "#address-cells": true 28 + "#address-cells": 29 + enum: [ 1, 2 ] 29 30 30 - "#size-cells": true 31 - 32 - compression: 33 - $ref: /schemas/types.yaml#/definitions/string 34 - description: | 35 - Compression algorithm used to store the data in this partition, chosen 36 - from a list of well-known algorithms. 37 - 38 - The contents are compressed using this algorithm. 39 - 40 - enum: 41 - - none 42 - - bzip2 43 - - gzip 44 - - lzop 45 - - lz4 46 - - lzma 47 - - xz 48 - - zstd 31 + "#size-cells": 32 + enum: [ 1, 2 ] 49 33 50 34 patternProperties: 51 35 "@[0-9a-f]+$": 52 - $ref: partition.yaml# 53 - 54 - properties: 55 - sercomm,scpart-id: 56 - description: Partition id in Sercomm partition map. Mtd parser 57 - uses this id to find a record in the partition map containing 58 - offset and size of the current partition. The values from 59 - partition map overrides partition offset and size defined in 60 - reg property of the dts. Frequently these values are the same, 61 - but may differ if device has bad eraseblocks on a flash. 62 - $ref: /schemas/types.yaml#/definitions/uint32 36 + $ref: partition.yaml#/$defs/partition-node 63 37 64 38 required: 65 39 - "#address-cells" 66 40 - "#size-cells" 67 41 68 - additionalProperties: true 42 + # fixed-partitions can be nested 43 + allOf: 44 + - $ref: partition.yaml# 45 + 46 + unevaluatedProperties: false 69 47 70 48 examples: 71 49 - | ··· 119 141 compatible = "fixed-partitions"; 120 142 label = "calibration"; 121 143 reg = <0xf00000 0x100000>; 122 - ranges = <0 0xf00000 0x100000>; 123 144 #address-cells = <1>; 124 145 #size-cells = <1>; 125 146
+1 -9
Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml
··· 18 18 maintainers: 19 19 - Rafał Miłecki <rafal@milecki.pl> 20 20 21 - select: false 22 - 23 21 properties: 24 22 compatible: 25 23 const: linksys,ns-partitions ··· 30 32 31 33 patternProperties: 32 34 "^partition@[0-9a-f]+$": 33 - $ref: partition.yaml# 34 - properties: 35 - compatible: 36 - items: 37 - - const: linksys,ns-firmware 38 - - const: brcm,trx 39 - unevaluatedProperties: false 35 + $ref: partition.yaml#/$defs/partition-node 40 36 41 37 required: 42 38 - "#address-cells"
+43 -1
Documentation/devicetree/bindings/mtd/partitions/partition.yaml
··· 108 108 with the padding bytes, so may grow. If ‘align-end’ is not provided, 109 109 no alignment is performed. 110 110 111 + compression: 112 + $ref: /schemas/types.yaml#/definitions/string 113 + description: | 114 + Compression algorithm used to store the data in this partition, chosen 115 + from a list of well-known algorithms. 116 + 117 + The contents are compressed using this algorithm. 118 + 119 + enum: 120 + - none 121 + - bzip2 122 + - gzip 123 + - lzop 124 + - lz4 125 + - lzma 126 + - xz 127 + - zstd 128 + 129 + sercomm,scpart-id: 130 + description: Partition id in Sercomm partition map. Mtd parser 131 + uses this id to find a record in the partition map containing 132 + offset and size of the current partition. The values from 133 + partition map overrides partition offset and size defined in 134 + reg property of the dts. Frequently these values are the same, 135 + but may differ if device has bad eraseblocks on a flash. 136 + $ref: /schemas/types.yaml#/definitions/uint32 137 + 138 + nvmem-layout: 139 + $ref: /schemas/nvmem/layouts/nvmem-layout.yaml 140 + 111 141 if: 112 142 not: 113 143 required: [ reg ] 114 144 then: 115 145 properties: 116 146 $nodename: 117 - pattern: '^partition-.*$' 147 + pattern: '^partitions?(-.+)?$' 118 148 119 149 # This is a generic file other binding inherit from and extend 120 150 additionalProperties: true 151 + 152 + $defs: 153 + partition-node: 154 + type: object 155 + if: 156 + not: 157 + required: [ compatible ] 158 + then: 159 + $ref: '#' 160 + unevaluatedProperties: false 161 + else: 162 + $ref: '#' 121 163 122 164 examples: 123 165 - |
-42
Documentation/devicetree/bindings/mtd/partitions/partitions.yaml
··· 1 - # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 - %YAML 1.2 3 - --- 4 - $id: http://devicetree.org/schemas/mtd/partitions/partitions.yaml# 5 - $schema: http://devicetree.org/meta-schemas/core.yaml# 6 - 7 - title: Partitions 8 - 9 - description: | 10 - This binding is generic and describes the content of the partitions container 11 - node. All partition parsers must be referenced here. 12 - 13 - maintainers: 14 - - Miquel Raynal <miquel.raynal@bootlin.com> 15 - 16 - oneOf: 17 - - $ref: arm,arm-firmware-suite.yaml 18 - - $ref: brcm,bcm4908-partitions.yaml 19 - - $ref: brcm,bcm947xx-cfe-partitions.yaml 20 - - $ref: fixed-partitions.yaml 21 - - $ref: linksys,ns-partitions.yaml 22 - - $ref: qcom,smem-part.yaml 23 - - $ref: redboot-fis.yaml 24 - - $ref: tplink,safeloader-partitions.yaml 25 - 26 - properties: 27 - compatible: true 28 - 29 - '#address-cells': 30 - enum: [1, 2] 31 - 32 - '#size-cells': 33 - enum: [1, 2] 34 - 35 - patternProperties: 36 - "^partition(-.+|@[0-9a-f]+)$": 37 - $ref: partition.yaml 38 - 39 - required: 40 - - compatible 41 - 42 - unevaluatedProperties: false
-4
Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml
··· 28 28 device. On a flash memory with 32KB eraseblocks, 0 means the first 29 29 eraseblock at 0x00000000, 1 means the second eraseblock at 0x00008000 and so on. 30 30 31 - '#address-cells': false 32 - 33 - '#size-cells': false 34 - 35 31 required: 36 32 - compatible 37 33 - fis-index-block
-44
Documentation/devicetree/bindings/mtd/partitions/seama.yaml
··· 1 - # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - %YAML 1.2 3 - --- 4 - $id: http://devicetree.org/schemas/mtd/partitions/seama.yaml# 5 - $schema: http://devicetree.org/meta-schemas/core.yaml# 6 - 7 - title: Seattle Image Partitions 8 - 9 - description: The SEAttle iMAge (SEAMA) partition is a type of partition 10 - used for NAND flash devices. This type of flash image is found in some 11 - D-Link routers such as DIR-645, DIR-842, DIR-859, DIR-860L, DIR-885L, 12 - DIR890L and DCH-M225, as well as in WD and NEC routers on the ath79 13 - (MIPS), Broadcom BCM53xx, and RAMIPS platforms. This partition type 14 - does not have children defined in the device tree, they need to be 15 - detected by software. 16 - 17 - allOf: 18 - - $ref: partition.yaml# 19 - 20 - maintainers: 21 - - Linus Walleij <linusw@kernel.org> 22 - 23 - properties: 24 - compatible: 25 - const: seama 26 - 27 - required: 28 - - compatible 29 - 30 - unevaluatedProperties: false 31 - 32 - examples: 33 - - | 34 - partitions { 35 - compatible = "fixed-partitions"; 36 - #address-cells = <1>; 37 - #size-cells = <1>; 38 - 39 - partition@0 { 40 - compatible = "seama"; 41 - reg = <0x0 0x800000>; 42 - label = "firmware"; 43 - }; 44 - };
+61
Documentation/devicetree/bindings/mtd/partitions/simple-partition.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mtd/partitions/simple-partition.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Simple partition types 8 + 9 + description: 10 + Simple partition types which only define a "compatible" value and no custom 11 + properties. 12 + 13 + maintainers: 14 + - Rafał Miłecki <rafal@milecki.pl> 15 + - Simon Glass <sjg@chromium.org> 16 + 17 + allOf: 18 + - $ref: partition.yaml# 19 + 20 + properties: 21 + compatible: 22 + oneOf: 23 + - const: brcm,bcm4908-firmware 24 + description: 25 + Broadcom BCM4908 CFE bootloader firmware partition 26 + 27 + - const: brcm,bcm963xx-imagetag 28 + description: 29 + The BCM963XX ImageTag is a simple firmware header describing the 30 + offsets and sizes of the rootfs and kernel parts contained in the 31 + firmware. 32 + 33 + - const: seama 34 + description: 35 + The SEAttle iMAge (SEAMA) partition is a type of partition used for 36 + NAND flash devices. This type of flash image is found in some D-Link 37 + routers such as DIR-645, DIR-842, DIR-859, DIR-860L, DIR-885L, DIR890L 38 + and DCH-M225, as well as in WD and NEC routers on the ath79 (MIPS), 39 + Broadcom BCM53xx, and RAMIPS platforms. This partition type does not 40 + have children defined in the device tree, they need to be detected by 41 + software. 42 + 43 + - const: u-boot 44 + description: > 45 + u-boot.bin from U-Boot project. 46 + 47 + This corresponds to a binman 'entry'. It is a single partition which holds 48 + data of a defined type. 49 + 50 + Binman uses the type to indicate what data file / type to place in the 51 + partition. There are quite a number of binman-specific entry types, such as 52 + section, fill and files, to be added later. 53 + 54 + - const: tfa-bl31 55 + description: > 56 + bl31.bin or bl31.elf from TF-A project 57 + 58 + This corresponds to a binman 'entry'. It is a single partition which holds 59 + data of a defined type. 60 + 61 + unevaluatedProperties: false
+1 -1
Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml
··· 38 38 39 39 patternProperties: 40 40 "^partition-.*$": 41 - $ref: partition.yaml# 41 + $ref: partition.yaml#/$defs/partition-node 42 42 43 43 required: 44 44 - partitions-table-offset
+1 -1
Documentation/devicetree/bindings/mtd/partitions/u-boot.yaml
··· 29 29 30 30 patternProperties: 31 31 "^partition-.*$": 32 - $ref: partition.yaml# 32 + $ref: partition.yaml#/$defs/partition-node 33 33 34 34 unevaluatedProperties: false 35 35
-29
Documentation/devicetree/bindings/mtd/spear_smi.txt
··· 1 - * SPEAr SMI 2 - 3 - Required properties: 4 - - compatible : "st,spear600-smi" 5 - - reg : Address range of the mtd chip 6 - - #address-cells, #size-cells : Must be present if the device has sub-nodes 7 - representing partitions. 8 - - interrupts: Should contain the STMMAC interrupts 9 - - clock-rate : Functional clock rate of SMI in Hz 10 - 11 - Optional properties: 12 - - st,smi-fast-mode : Flash supports read in fast mode 13 - 14 - Example: 15 - 16 - smi: flash@fc000000 { 17 - compatible = "st,spear600-smi"; 18 - #address-cells = <1>; 19 - #size-cells = <1>; 20 - reg = <0xfc000000 0x1000>; 21 - interrupt-parent = <&vic1>; 22 - interrupts = <12>; 23 - clock-rate = <50000000>; /* 50MHz */ 24 - 25 - flash@f8000000 { 26 - st,smi-fast-mode; 27 - ... 28 - }; 29 - };
+72
Documentation/devicetree/bindings/mtd/st,spear600-smi.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mtd/st,spear600-smi.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectronics SPEAr600 Serial Memory Interface (SMI) Controller 8 + 9 + maintainers: 10 + - Richard Weinberger <richard@nod.at> 11 + 12 + description: 13 + The SPEAr600 Serial Memory Interface (SMI) is a dedicated serial flash 14 + controller supporting up to four chip selects for serial NOR flashes 15 + connected in parallel. The controller is memory-mapped and the attached 16 + flash devices appear in the CPU address space.The driver 17 + (drivers/mtd/devices/spear_smi.c) probes the attached flashes 18 + dynamically by sending commands (e.g., RDID) to each bank. 19 + Flash sub nodes describe the memory range and optional per-flash 20 + properties. 21 + 22 + allOf: 23 + - $ref: mtd.yaml# 24 + 25 + properties: 26 + compatible: 27 + const: st,spear600-smi 28 + 29 + reg: 30 + maxItems: 1 31 + 32 + interrupts: 33 + maxItems: 1 34 + 35 + "#address-cells": 36 + const: 1 37 + 38 + "#size-cells": 39 + const: 1 40 + 41 + clock-rate: 42 + $ref: /schemas/types.yaml#/definitions/uint32 43 + description: Functional clock rate of the SMI controller in Hz. 44 + 45 + st,smi-fast-mode: 46 + type: boolean 47 + description: Indicates that the attached flash supports fast read mode. 48 + 49 + required: 50 + - compatible 51 + - reg 52 + - clock-rate 53 + 54 + unevaluatedProperties: false 55 + 56 + examples: 57 + - | 58 + flash@fc000000 { 59 + compatible = "st,spear600-smi"; 60 + #address-cells = <1>; 61 + #size-cells = <1>; 62 + reg = <0xfc000000 0x1000>; 63 + interrupt-parent = <&vic1>; 64 + interrupts = <12>; 65 + clock-rate = <50000000>; /* 50 MHz */ 66 + 67 + flash@f8000000 { 68 + reg = <0xfc000000 0x1000>; 69 + st,smi-fast-mode; 70 + }; 71 + }; 72 + ...
+68
Documentation/devicetree/bindings/mtd/st,spi-fsm.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mtd/st,spi-fsm.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectronics SPI FSM Serial NOR Flash Controller 8 + 9 + maintainers: 10 + - Angus Clark <angus.clark@st.com> 11 + 12 + description: 13 + The STMicroelectronics Fast Sequence Mode (FSM) controller is a dedicated 14 + hardware accelerator integrated in older STiH4xx/STiDxxx set-top box SoCs 15 + (such as STiH407, STiH416, STiD127). It connects directly to a single 16 + external serial flash device used as the primary boot device. The FSM 17 + executes hard-coded or configurable instruction sequences in hardware, 18 + providing low-latency reads suitable for execute-in-place (XIP) boot 19 + and high read bandwidth. 20 + 21 + properties: 22 + compatible: 23 + const: st,spi-fsm 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + reg-names: 29 + const: spi-fsm 30 + 31 + interrupts: 32 + maxItems: 1 33 + 34 + st,syscfg: 35 + $ref: /schemas/types.yaml#/definitions/phandle 36 + description: Phandle to the system configuration registers used for boot-device selection. 37 + 38 + st,boot-device-reg: 39 + $ref: /schemas/types.yaml#/definitions/uint32 40 + description: Offset of the boot-device register within the st,syscfg node. 41 + 42 + st,boot-device-spi: 43 + $ref: /schemas/types.yaml#/definitions/uint32 44 + description: Expected boot-device value when booting from this SPI controller. 45 + 46 + required: 47 + - compatible 48 + - reg 49 + - reg-names 50 + - interrupts 51 + - pinctrl-0 52 + 53 + unevaluatedProperties: false 54 + 55 + examples: 56 + - | 57 + #include <dt-bindings/interrupt-controller/arm-gic.h> 58 + spifsm@fe902000 { 59 + compatible = "st,spi-fsm"; 60 + reg = <0xfe902000 0x1000>; 61 + reg-names = "spi-fsm"; 62 + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; 63 + pinctrl-0 = <&pinctrl_fsm>; 64 + st,syscfg = <&syscfg_rear>; 65 + st,boot-device-reg = <0x958>; 66 + st,boot-device-spi = <0x1a>; 67 + }; 68 + ...
-25
Documentation/devicetree/bindings/mtd/st-fsm.txt
··· 1 - * ST-Microelectronics SPI FSM Serial (NOR) Flash Controller 2 - 3 - Required properties: 4 - - compatible : Should be "st,spi-fsm" 5 - - reg : Contains register's location and length. 6 - - reg-names : Should contain the reg names "spi-fsm" 7 - - interrupts : The interrupt number 8 - - pinctrl-0 : Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt) 9 - 10 - Optional properties: 11 - - st,syscfg : Phandle to boot-device system configuration registers 12 - - st,boot-device-reg : Address of the aforementioned boot-device register(s) 13 - - st,boot-device-spi : Expected boot-device value if booted via this device 14 - 15 - Example: 16 - spifsm: spifsm@fe902000{ 17 - compatible = "st,spi-fsm"; 18 - reg = <0xfe902000 0x1000>; 19 - reg-names = "spi-fsm"; 20 - pinctrl-0 = <&pinctrl_fsm>; 21 - st,syscfg = <&syscfg_rear>; 22 - st,boot-device-reg = <0x958>; 23 - st,boot-device-spi = <0x1a>; 24 - }; 25 -
+3 -1
Documentation/devicetree/bindings/mtd/ti,davinci-nand.yaml
··· 24 24 - description: AEMIF control registers. 25 25 26 26 partitions: 27 - $ref: /schemas/mtd/partitions/partitions.yaml 27 + type: object 28 + required: 29 + - compatible 28 30 29 31 ti,davinci-chipselect: 30 32 description:
+1 -1
Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
··· 36 36 37 37 patternProperties: 38 38 "@[0-9a-f]+$": 39 - $ref: /schemas/mtd/partitions/partition.yaml 39 + $ref: /schemas/mtd/partitions/partition.yaml#/$defs/partition-node 40 40 41 41 allOf: 42 42 - $ref: /schemas/memory-controllers/ti,gpmc-child.yaml
-5
MAINTAINERS
··· 4445 4445 F: fs/bfs/ 4446 4446 F: include/uapi/linux/bfs_fs.h 4447 4447 4448 - BINMAN 4449 - M: Simon Glass <sjg@chromium.org> 4450 - S: Supported 4451 - F: Documentation/devicetree/bindings/mtd/partitions/binman* 4452 - 4453 4448 BITMAP API 4454 4449 M: Yury Norov <yury.norov@gmail.com> 4455 4450 R: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+2 -2
drivers/mtd/chips/jedec_probe.c
··· 1921 1921 */ 1922 1922 do { 1923 1923 uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi); 1924 - mask = (1 << (cfi->device_type * 8)) - 1; 1924 + mask = (1ULL << (cfi->device_type * 8)) - 1; 1925 1925 if (ofs >= map->size) 1926 1926 return 0; 1927 1927 result = map_read(map, base + ofs); ··· 1937 1937 map_word result; 1938 1938 unsigned long mask; 1939 1939 u32 ofs = cfi_build_cmd_addr(1, map, cfi); 1940 - mask = (1 << (cfi->device_type * 8)) -1; 1940 + mask = (1ULL << (cfi->device_type * 8)) - 1; 1941 1941 result = map_read(map, base + ofs); 1942 1942 return result.x[0] & mask; 1943 1943 }
+6 -3
drivers/mtd/devices/mtd_intel_dg.c
··· 770 770 771 771 kref_init(&nvm->refcnt); 772 772 mutex_init(&nvm->lock); 773 + nvm->nregions = nregions; 773 774 774 775 for (n = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) { 775 776 if (!invm->regions[i].name) ··· 778 777 779 778 char *name = kasprintf(GFP_KERNEL, "%s.%s", 780 779 dev_name(&aux_dev->dev), invm->regions[i].name); 781 - if (!name) 782 - continue; 780 + if (!name) { 781 + ret = -ENOMEM; 782 + goto err; 783 + } 784 + 783 785 nvm->regions[n].name = name; 784 786 nvm->regions[n].id = i; 785 787 n++; 786 788 } 787 - nvm->nregions = n; /* in case where kasprintf fail */ 788 789 789 790 ret = devm_pm_runtime_enable(device); 790 791 if (ret < 0) {
+1 -1
drivers/mtd/maps/physmap-core.c
··· 268 268 MODULE_DEVICE_TABLE(of, of_flash_match); 269 269 270 270 static const char * const of_default_part_probes[] = { 271 - "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL 271 + "cmdlinepart", "ofpart", "ofoldpart", "RedBoot", NULL 272 272 }; 273 273 274 274 static const char * const *of_get_part_probes(struct platform_device *dev)
+2 -4
drivers/mtd/nand/raw/atmel/nand-controller.c
··· 2304 2304 2305 2305 nc->sram.pool = of_gen_pool_get(nc->base.dev->of_node, 2306 2306 "atmel,nfc-sram", 0); 2307 - if (!nc->sram.pool) { 2308 - dev_err(nc->base.dev, "Missing SRAM\n"); 2309 - return -ENOMEM; 2310 - } 2307 + if (!nc->sram.pool) 2308 + return dev_err_probe(nc->base.dev, -EPROBE_DEFER, "Missing SRAM\n"); 2311 2309 2312 2310 nc->sram.virt = (void __iomem *)gen_pool_dma_alloc(nc->sram.pool, 2313 2311 ATMEL_NFC_SRAM_SIZE,
+4 -6
drivers/mtd/nand/raw/brcmnand/brcmnand.c
··· 3298 3298 { 3299 3299 struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev); 3300 3300 struct device *dev = &pdev->dev; 3301 - struct device_node *dn = dev->of_node, *child; 3301 + struct device_node *dn = dev->of_node; 3302 3302 struct brcmnand_controller *ctrl; 3303 3303 struct brcmnand_host *host; 3304 3304 struct resource *res; ··· 3486 3486 } 3487 3487 } 3488 3488 3489 - for_each_available_child_of_node(dn, child) { 3489 + for_each_available_child_of_node_scoped(dn, child) { 3490 3490 if (of_device_is_compatible(child, "brcm,nandcs")) { 3491 3491 3492 3492 host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); 3493 3493 if (!host) { 3494 - of_node_put(child); 3495 3494 ret = -ENOMEM; 3496 3495 goto err; 3497 3496 } ··· 3508 3509 3509 3510 ret = brcmnand_init_cs(host, NULL); 3510 3511 if (ret) { 3511 - if (ret == -EPROBE_DEFER) { 3512 - of_node_put(child); 3512 + if (ret == -EPROBE_DEFER) 3513 3513 goto err; 3514 - } 3514 + 3515 3515 devm_kfree(dev, host); 3516 3516 continue; /* Try all chip-selects */ 3517 3517 }
+1 -1
drivers/mtd/nand/raw/cadence-nand-controller.c
··· 1066 1066 } 1067 1067 1068 1068 /* Send SDMA command and wait for finish. */ 1069 - static u32 1069 + static int 1070 1070 cadence_nand_cdma_send_and_wait(struct cdns_nand_ctrl *cdns_ctrl, 1071 1071 u8 thread) 1072 1072 {
+2 -5
drivers/mtd/nand/raw/denali_dt.c
··· 115 115 struct denali_dt *dt; 116 116 const struct denali_dt_data *data; 117 117 struct denali_controller *denali; 118 - struct device_node *np; 119 118 int ret; 120 119 121 120 dt = devm_kzalloc(dev, sizeof(*dt), GFP_KERNEL); ··· 191 192 if (ret) 192 193 goto out_assert_rst; 193 194 194 - for_each_child_of_node(dev->of_node, np) { 195 + for_each_child_of_node_scoped(dev->of_node, np) { 195 196 ret = denali_dt_chip_init(denali, np); 196 - if (ret) { 197 - of_node_put(np); 197 + if (ret) 198 198 goto out_remove_denali; 199 - } 200 199 } 201 200 202 201 platform_set_drvdata(pdev, dt);
+1 -3
drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c
··· 438 438 struct platform_device *pdev) 439 439 { 440 440 struct device *dev = &pdev->dev; 441 - struct device_node *np; 442 441 int i = 0; 443 442 int ret; 444 443 int num_chips = of_get_child_count(dev->of_node); ··· 448 449 return -EINVAL; 449 450 } 450 451 451 - for_each_child_of_node(dev->of_node, np) { 452 + for_each_child_of_node_scoped(dev->of_node, np) { 452 453 ret = ingenic_nand_init_chip(pdev, nfc, np, i); 453 454 if (ret) { 454 455 ingenic_nand_cleanup_chips(nfc); 455 - of_node_put(np); 456 456 return ret; 457 457 } 458 458
+4
drivers/mtd/nand/raw/pl35x-nand-controller.c
··· 970 970 971 971 switch (chip->ecc.engine_type) { 972 972 case NAND_ECC_ENGINE_TYPE_ON_DIE: 973 + dev_dbg(nfc->dev, "Using on-die ECC\n"); 973 974 /* Keep these legacy BBT descriptors for ON_DIE situations */ 974 975 chip->bbt_td = &bbt_main_descr; 975 976 chip->bbt_md = &bbt_mirror_descr; 976 977 fallthrough; 977 978 case NAND_ECC_ENGINE_TYPE_NONE: 978 979 case NAND_ECC_ENGINE_TYPE_SOFT: 980 + dev_dbg(nfc->dev, "Using software ECC (Hamming 1-bit/512B)\n"); 981 + chip->ecc.write_page_raw = nand_monolithic_write_page_raw; 979 982 break; 980 983 case NAND_ECC_ENGINE_TYPE_ON_HOST: 984 + dev_dbg(nfc->dev, "Using hardware ECC\n"); 981 985 ret = pl35x_nand_init_hw_ecc_controller(nfc, chip); 982 986 if (ret) 983 987 return ret;
+3 -5
drivers/mtd/nand/raw/qcom_nandc.c
··· 2206 2206 static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc) 2207 2207 { 2208 2208 struct device *dev = nandc->dev; 2209 - struct device_node *dn = dev->of_node, *child; 2209 + struct device_node *dn = dev->of_node; 2210 2210 struct qcom_nand_host *host; 2211 2211 int ret = -ENODEV; 2212 2212 2213 - for_each_available_child_of_node(dn, child) { 2213 + for_each_available_child_of_node_scoped(dn, child) { 2214 2214 host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); 2215 - if (!host) { 2216 - of_node_put(child); 2215 + if (!host) 2217 2216 return -ENOMEM; 2218 - } 2219 2217 2220 2218 ret = qcom_nand_host_init_and_register(nandc, host, child); 2221 2219 if (ret) {
-6
drivers/mtd/nand/raw/sunxi_nand.c
··· 29 29 #include <linux/iopoll.h> 30 30 #include <linux/reset.h> 31 31 32 - /* non compile-time field get/prep */ 33 - #undef field_get 34 - #define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) 35 - #undef field_prep 36 - #define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) 37 - 38 32 #define NFC_REG_CTL 0x0000 39 33 #define NFC_REG_ST 0x0004 40 34 #define NFC_REG_INT 0x0008
+2 -4
drivers/mtd/nand/raw/vf610_nfc.c
··· 810 810 struct vf610_nfc *nfc; 811 811 struct mtd_info *mtd; 812 812 struct nand_chip *chip; 813 - struct device_node *child; 814 813 int err; 815 814 int irq; 816 815 ··· 839 840 return PTR_ERR(nfc->clk); 840 841 } 841 842 842 - nfc->variant = (enum vf610_nfc_variant)device_get_match_data(&pdev->dev); 843 + nfc->variant = (unsigned long)device_get_match_data(&pdev->dev); 843 844 if (!nfc->variant) 844 845 return -ENODEV; 845 846 846 - for_each_available_child_of_node(nfc->dev->of_node, child) { 847 + for_each_available_child_of_node_scoped(nfc->dev->of_node, child) { 847 848 if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) { 848 849 849 850 if (nand_get_flash_node(chip)) { 850 851 dev_err(nfc->dev, 851 852 "Only one NAND chip supported!\n"); 852 - of_node_put(child); 853 853 return -EINVAL; 854 854 } 855 855
+2 -2
drivers/mtd/nand/spi/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 spinand-objs := core.o otp.o 3 - spinand-objs += alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o 4 - spinand-objs += micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o 3 + spinand-objs += alliancememory.o ato.o dosilicon.o esmt.o fmsh.o foresee.o gigadevice.o 4 + spinand-objs += macronix.o micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o 5 5 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
+346 -52
drivers/mtd/nand/spi/core.c
··· 20 20 #include <linux/spi/spi.h> 21 21 #include <linux/spi/spi-mem.h> 22 22 23 + static struct spi_mem_op 24 + spinand_fill_reset_op(struct spinand_device *spinand) 25 + { 26 + return spinand->op_templates->reset; 27 + } 28 + 29 + static struct spi_mem_op 30 + spinand_fill_readid_op(struct spinand_device *spinand, 31 + u8 naddr, u8 ndummy, void *buf, unsigned int len) 32 + { 33 + struct spi_mem_op op = spinand->op_templates->readid; 34 + 35 + op.addr.nbytes = naddr; 36 + op.dummy.nbytes = ndummy; 37 + op.data.buf.in = buf; 38 + op.data.nbytes = len; 39 + 40 + return op; 41 + } 42 + 43 + struct spi_mem_op 44 + spinand_fill_wr_en_op(struct spinand_device *spinand) 45 + { 46 + return spinand->op_templates->wr_en; 47 + } 48 + 49 + static __maybe_unused struct spi_mem_op 50 + spinand_fill_wr_dis_op(struct spinand_device *spinand) 51 + { 52 + return spinand->op_templates->wr_dis; 53 + } 54 + 55 + struct spi_mem_op 56 + spinand_fill_set_feature_op(struct spinand_device *spinand, u64 reg, const void *valptr) 57 + { 58 + struct spi_mem_op op = spinand->op_templates->set_feature; 59 + 60 + if (op.cmd.dtr && op.cmd.buswidth == 8) 61 + reg |= reg << 8; 62 + 63 + op.addr.val = reg; 64 + op.data.buf.out = valptr; 65 + 66 + return op; 67 + } 68 + 69 + struct spi_mem_op 70 + spinand_fill_get_feature_op(struct spinand_device *spinand, u64 reg, void *valptr) 71 + { 72 + struct spi_mem_op op = spinand->op_templates->get_feature; 73 + 74 + if (op.cmd.dtr && op.cmd.buswidth == 8) 75 + reg |= reg << 8; 76 + 77 + op.addr.val = reg; 78 + op.data.buf.in = valptr; 79 + 80 + return op; 81 + } 82 + 83 + static struct spi_mem_op 84 + spinand_fill_blk_erase_op(struct spinand_device *spinand, u64 addr) 85 + { 86 + struct spi_mem_op op = spinand->op_templates->blk_erase; 87 + 88 + op.addr.val = addr; 89 + 90 + return op; 91 + } 92 + 93 + static struct spi_mem_op 94 + spinand_fill_page_read_op(struct spinand_device *spinand, u64 addr) 95 + { 96 + struct spi_mem_op op = spinand->op_templates->page_read; 97 + 98 + op.addr.val = addr; 99 + 100 + return op; 101 + } 102 + 103 + struct spi_mem_op 104 + spinand_fill_prog_exec_op(struct spinand_device *spinand, u64 addr) 105 + { 106 + struct spi_mem_op op = spinand->op_templates->prog_exec; 107 + 108 + op.addr.val = addr; 109 + 110 + return op; 111 + } 112 + 23 113 int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) 24 114 { 25 - struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(reg, 26 - spinand->scratchbuf); 115 + struct spi_mem_op op = SPINAND_OP(spinand, get_feature, 116 + reg, spinand->scratchbuf); 27 117 int ret; 28 118 29 119 ret = spi_mem_exec_op(spinand->spimem, &op); ··· 126 36 127 37 int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val) 128 38 { 129 - struct spi_mem_op op = SPINAND_SET_FEATURE_1S_1S_1S_OP(reg, 130 - spinand->scratchbuf); 39 + struct spi_mem_op op = SPINAND_OP(spinand, set_feature, 40 + reg, spinand->scratchbuf); 131 41 132 42 *spinand->scratchbuf = val; 133 43 return spi_mem_exec_op(spinand->spimem, &op); ··· 267 177 return 0; 268 178 } 269 179 270 - static int spinand_init_quad_enable(struct spinand_device *spinand) 180 + static int spinand_init_quad_enable(struct spinand_device *spinand, 181 + bool enable) 271 182 { 272 - bool enable = false; 273 - 274 - if (!(spinand->flags & SPINAND_HAS_QE_BIT)) 275 - return 0; 276 - 277 - if (spinand->op_templates.read_cache->data.buswidth == 4 || 278 - spinand->op_templates.write_cache->data.buswidth == 4 || 279 - spinand->op_templates.update_cache->data.buswidth == 4) 280 - enable = true; 281 - 282 183 return spinand_upd_cfg(spinand, CFG_QUAD_ENABLE, 283 184 enable ? CFG_QUAD_ENABLE : 0); 284 185 } ··· 443 362 444 363 int spinand_write_enable_op(struct spinand_device *spinand) 445 364 { 446 - struct spi_mem_op op = SPINAND_WR_EN_DIS_1S_0_0_OP(true); 365 + struct spi_mem_op op = SPINAND_OP(spinand, wr_en); 447 366 448 367 return spi_mem_exec_op(spinand->spimem, &op); 449 368 } ··· 453 372 { 454 373 struct nand_device *nand = spinand_to_nand(spinand); 455 374 unsigned int row = nanddev_pos_to_row(nand, &req->pos); 456 - struct spi_mem_op op = SPINAND_PAGE_READ_1S_1S_0_OP(row); 375 + struct spi_mem_op op = SPINAND_OP(spinand, page_read, row); 457 376 458 377 return spi_mem_exec_op(spinand->spimem, &op); 459 378 } ··· 608 527 { 609 528 struct nand_device *nand = spinand_to_nand(spinand); 610 529 unsigned int row = nanddev_pos_to_row(nand, &req->pos); 611 - struct spi_mem_op op = SPINAND_PROG_EXEC_1S_1S_0_OP(row); 530 + struct spi_mem_op op = SPINAND_OP(spinand, prog_exec, row); 612 531 613 532 return spi_mem_exec_op(spinand->spimem, &op); 614 533 } ··· 618 537 { 619 538 struct nand_device *nand = spinand_to_nand(spinand); 620 539 unsigned int row = nanddev_pos_to_row(nand, pos); 621 - struct spi_mem_op op = SPINAND_BLK_ERASE_1S_1S_0_OP(row); 540 + struct spi_mem_op op = SPINAND_OP(spinand, blk_erase, row); 622 541 623 542 return spi_mem_exec_op(spinand->spimem, &op); 624 543 } ··· 638 557 int spinand_wait(struct spinand_device *spinand, unsigned long initial_delay_us, 639 558 unsigned long poll_delay_us, u8 *s) 640 559 { 641 - struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(REG_STATUS, 642 - spinand->scratchbuf); 560 + struct spi_mem_op op = SPINAND_OP(spinand, get_feature, 561 + REG_STATUS, spinand->scratchbuf); 643 562 u8 status; 644 563 int ret; 645 564 ··· 672 591 static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr, 673 592 u8 ndummy, u8 *buf) 674 593 { 675 - struct spi_mem_op op = SPINAND_READID_1S_1S_1S_OP( 676 - naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN); 594 + struct spi_mem_op op = SPINAND_OP(spinand, readid, 595 + naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN); 677 596 int ret; 678 597 679 598 ret = spi_mem_exec_op(spinand->spimem, &op); ··· 685 604 686 605 static int spinand_reset_op(struct spinand_device *spinand) 687 606 { 688 - struct spi_mem_op op = SPINAND_RESET_1S_0_0_OP; 607 + struct spi_mem_op op = SPINAND_OP(spinand, reset); 689 608 int ret; 690 609 691 610 ret = spi_mem_exec_op(spinand->spimem, &op); ··· 940 859 (engine_type == NAND_ECC_ENGINE_TYPE_ON_DIE || 941 860 engine_type == NAND_ECC_ENGINE_TYPE_NONE)) { 942 861 spinand->cont_read_possible = true; 862 + 863 + /* 864 + * Ensure continuous read is disabled on probe. 865 + * Some devices retain this state across soft reset, 866 + * which leaves the OOB area inaccessible and results 867 + * in false positive returns from spinand_isbad(). 868 + */ 869 + spinand_cont_read_enable(spinand, false); 943 870 } 944 871 } 945 872 ··· 1243 1154 info.offset = plane << fls(nand->memorg.pagesize); 1244 1155 1245 1156 info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); 1246 - info.op_tmpl = *spinand->op_templates.update_cache; 1157 + info.op_tmpl = *spinand->op_templates->update_cache; 1247 1158 desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, 1248 1159 spinand->spimem, &info); 1249 1160 if (IS_ERR(desc)) ··· 1251 1162 1252 1163 spinand->dirmaps[plane].wdesc = desc; 1253 1164 1254 - info.op_tmpl = *spinand->op_templates.read_cache; 1165 + info.op_tmpl = *spinand->op_templates->read_cache; 1255 1166 desc = spinand_create_rdesc(spinand, &info); 1256 1167 if (IS_ERR(desc)) 1257 1168 return PTR_ERR(desc); ··· 1266 1177 } 1267 1178 1268 1179 info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); 1269 - info.op_tmpl = *spinand->op_templates.update_cache; 1180 + info.op_tmpl = *spinand->op_templates->update_cache; 1270 1181 info.op_tmpl.data.ecc = true; 1271 1182 desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, 1272 1183 spinand->spimem, &info); ··· 1275 1186 1276 1187 spinand->dirmaps[plane].wdesc_ecc = desc; 1277 1188 1278 - info.op_tmpl = *spinand->op_templates.read_cache; 1189 + info.op_tmpl = *spinand->op_templates->read_cache; 1279 1190 info.op_tmpl.data.ecc = true; 1280 1191 desc = spinand_create_rdesc(spinand, &info); 1281 1192 if (IS_ERR(desc)) ··· 1316 1227 static const struct spinand_manufacturer *spinand_manufacturers[] = { 1317 1228 &alliancememory_spinand_manufacturer, 1318 1229 &ato_spinand_manufacturer, 1230 + &dosilicon_spinand_manufacturer, 1319 1231 &esmt_8c_spinand_manufacturer, 1320 1232 &esmt_c8_spinand_manufacturer, 1321 1233 &fmsh_spinand_manufacturer, ··· 1397 1307 return ret; 1398 1308 } 1399 1309 1400 - if (spinand->configure_chip) { 1401 - ret = spinand->configure_chip(spinand); 1402 - if (ret) 1403 - return ret; 1404 - } 1405 - 1406 1310 return 0; 1407 1311 } 1408 1312 ··· 1407 1323 return spinand->manufacturer->ops->cleanup(spinand); 1408 1324 } 1409 1325 1326 + static bool spinand_op_is_odtr(const struct spi_mem_op *op) 1327 + { 1328 + return op->cmd.dtr && op->cmd.buswidth == 8; 1329 + } 1330 + 1331 + static void spinand_init_ssdr_templates(struct spinand_device *spinand) 1332 + { 1333 + struct spinand_mem_ops *tmpl = &spinand->ssdr_op_templates; 1334 + 1335 + tmpl->reset = (struct spi_mem_op)SPINAND_RESET_1S_0_0_OP; 1336 + tmpl->readid = (struct spi_mem_op)SPINAND_READID_1S_1S_1S_OP(0, 0, NULL, 0); 1337 + tmpl->wr_en = (struct spi_mem_op)SPINAND_WR_EN_1S_0_0_OP; 1338 + tmpl->wr_dis = (struct spi_mem_op)SPINAND_WR_DIS_1S_0_0_OP; 1339 + tmpl->set_feature = (struct spi_mem_op)SPINAND_SET_FEATURE_1S_1S_1S_OP(0, NULL); 1340 + tmpl->get_feature = (struct spi_mem_op)SPINAND_GET_FEATURE_1S_1S_1S_OP(0, NULL); 1341 + tmpl->blk_erase = (struct spi_mem_op)SPINAND_BLK_ERASE_1S_1S_0_OP(0); 1342 + tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_1S_1S_0_OP(0); 1343 + tmpl->prog_exec = (struct spi_mem_op)SPINAND_PROG_EXEC_1S_1S_0_OP(0); 1344 + spinand->op_templates = &spinand->ssdr_op_templates; 1345 + spinand->bus_iface = SSDR; 1346 + } 1347 + 1348 + static int spinand_support_vendor_ops(struct spinand_device *spinand, 1349 + const struct spinand_info *info, 1350 + enum spinand_bus_interface iface) 1351 + { 1352 + int i; 1353 + 1354 + if (!info->vendor_ops) 1355 + return 0; 1356 + /* 1357 + * The vendor ops array is only used in order to verify this chip and all its memory 1358 + * operations are supported. If we see patterns emerging, we could ideally name these 1359 + * operations and define them at the SPI NAND core level instead. 1360 + * For now, this only serves as a sanity check. 1361 + */ 1362 + for (i = 0; i < info->vendor_ops->nops; i++) { 1363 + const struct spi_mem_op *op = &info->vendor_ops->ops[i]; 1364 + 1365 + if ((iface == SSDR && spinand_op_is_odtr(op)) || 1366 + (iface == ODTR && !spinand_op_is_odtr(op))) 1367 + continue; 1368 + 1369 + if (!spi_mem_supports_op(spinand->spimem, op)) 1370 + return -EOPNOTSUPP; 1371 + } 1372 + 1373 + return 0; 1374 + } 1375 + 1376 + static int spinand_init_odtr_instruction_set(struct spinand_device *spinand) 1377 + { 1378 + struct spinand_mem_ops *tmpl = &spinand->odtr_op_templates; 1379 + 1380 + tmpl->reset = (struct spi_mem_op)SPINAND_RESET_8D_0_0_OP; 1381 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->reset)) 1382 + return -EOPNOTSUPP; 1383 + 1384 + tmpl->readid = (struct spi_mem_op)SPINAND_READID_8D_8D_8D_OP(0, 0, NULL, 0); 1385 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->readid)) 1386 + return -EOPNOTSUPP; 1387 + 1388 + tmpl->wr_en = (struct spi_mem_op)SPINAND_WR_EN_8D_0_0_OP; 1389 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->wr_en)) 1390 + return -EOPNOTSUPP; 1391 + 1392 + tmpl->wr_dis = (struct spi_mem_op)SPINAND_WR_DIS_8D_0_0_OP; 1393 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->wr_dis)) 1394 + return -EOPNOTSUPP; 1395 + 1396 + tmpl->set_feature = (struct spi_mem_op)SPINAND_SET_FEATURE_8D_8D_8D_OP(0, NULL); 1397 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->set_feature)) 1398 + return -EOPNOTSUPP; 1399 + 1400 + tmpl->get_feature = (struct spi_mem_op)SPINAND_GET_FEATURE_8D_8D_8D_OP(0, NULL); 1401 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->get_feature)) 1402 + return -EOPNOTSUPP; 1403 + 1404 + tmpl->blk_erase = (struct spi_mem_op)SPINAND_BLK_ERASE_8D_8D_0_OP(0); 1405 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->blk_erase)) 1406 + return -EOPNOTSUPP; 1407 + 1408 + tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_8D_8D_0_OP(0); 1409 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->page_read)) 1410 + return -EOPNOTSUPP; 1411 + 1412 + tmpl->prog_exec = (struct spi_mem_op)SPINAND_PROG_EXEC_8D_8D_0_OP(0); 1413 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->prog_exec)) 1414 + return -EOPNOTSUPP; 1415 + 1416 + return 0; 1417 + } 1418 + 1410 1419 static const struct spi_mem_op * 1411 - spinand_select_op_variant(struct spinand_device *spinand, 1420 + spinand_select_op_variant(struct spinand_device *spinand, enum spinand_bus_interface iface, 1412 1421 const struct spinand_op_variants *variants) 1413 1422 { 1414 1423 struct nand_device *nand = spinand_to_nand(spinand); ··· 1514 1337 u64 op_duration_ns = 0; 1515 1338 unsigned int nbytes; 1516 1339 int ret; 1340 + 1341 + if ((iface == SSDR && spinand_op_is_odtr(&op)) || 1342 + (iface == ODTR && !spinand_op_is_odtr(&op))) 1343 + continue; 1517 1344 1518 1345 nbytes = nanddev_per_page_oobsize(nand) + 1519 1346 nanddev_page_size(nand); ··· 1570 1389 u8 *id = spinand->id.data; 1571 1390 struct nand_device *nand = spinand_to_nand(spinand); 1572 1391 unsigned int i; 1392 + int ret; 1573 1393 1574 1394 for (i = 0; i < table_size; i++) { 1575 1395 const struct spinand_info *info = &table[i]; ··· 1595 1413 spinand->read_retries = table[i].read_retries; 1596 1414 spinand->set_read_retry = table[i].set_read_retry; 1597 1415 1598 - op = spinand_select_op_variant(spinand, 1416 + /* I/O variants selection with single-spi SDR commands */ 1417 + 1418 + op = spinand_select_op_variant(spinand, SSDR, 1599 1419 info->op_variants.read_cache); 1600 1420 if (!op) 1601 - return -ENOTSUPP; 1421 + return -EOPNOTSUPP; 1602 1422 1603 - spinand->op_templates.read_cache = op; 1423 + spinand->ssdr_op_templates.read_cache = op; 1604 1424 1605 - op = spinand_select_op_variant(spinand, 1425 + op = spinand_select_op_variant(spinand, SSDR, 1606 1426 info->op_variants.write_cache); 1607 1427 if (!op) 1608 - return -ENOTSUPP; 1428 + return -EOPNOTSUPP; 1609 1429 1610 - spinand->op_templates.write_cache = op; 1430 + spinand->ssdr_op_templates.write_cache = op; 1611 1431 1612 - op = spinand_select_op_variant(spinand, 1432 + op = spinand_select_op_variant(spinand, SSDR, 1613 1433 info->op_variants.update_cache); 1614 - spinand->op_templates.update_cache = op; 1434 + if (!op) 1435 + return -EOPNOTSUPP; 1436 + 1437 + spinand->ssdr_op_templates.update_cache = op; 1438 + 1439 + ret = spinand_support_vendor_ops(spinand, info, SSDR); 1440 + if (ret) 1441 + return ret; 1442 + 1443 + /* I/O variants selection with octo-spi DDR commands (optional) */ 1444 + 1445 + ret = spinand_init_odtr_instruction_set(spinand); 1446 + if (ret) 1447 + return 0; 1448 + 1449 + ret = spinand_support_vendor_ops(spinand, info, ODTR); 1450 + if (ret) 1451 + return 0; 1452 + 1453 + op = spinand_select_op_variant(spinand, ODTR, 1454 + info->op_variants.read_cache); 1455 + spinand->odtr_op_templates.read_cache = op; 1456 + 1457 + op = spinand_select_op_variant(spinand, ODTR, 1458 + info->op_variants.write_cache); 1459 + spinand->odtr_op_templates.write_cache = op; 1460 + 1461 + op = spinand_select_op_variant(spinand, ODTR, 1462 + info->op_variants.update_cache); 1463 + spinand->odtr_op_templates.update_cache = op; 1615 1464 1616 1465 return 0; 1617 1466 } 1618 1467 1619 - return -ENOTSUPP; 1468 + return -EOPNOTSUPP; 1620 1469 } 1621 1470 1622 1471 static int spinand_detect(struct spinand_device *spinand) ··· 1683 1470 return 0; 1684 1471 } 1685 1472 1473 + static int spinand_configure_chip(struct spinand_device *spinand) 1474 + { 1475 + bool odtr = false, quad_enable = false; 1476 + int ret; 1477 + 1478 + if (spinand->odtr_op_templates.read_cache && 1479 + spinand->odtr_op_templates.write_cache && 1480 + spinand->odtr_op_templates.update_cache) 1481 + odtr = true; 1482 + 1483 + if (odtr) { 1484 + if (!spinand->configure_chip) 1485 + goto try_ssdr; 1486 + 1487 + /* ODTR bus interface configuration happens here */ 1488 + ret = spinand->configure_chip(spinand, ODTR); 1489 + if (ret) { 1490 + spinand->odtr_op_templates.read_cache = NULL; 1491 + spinand->odtr_op_templates.write_cache = NULL; 1492 + spinand->odtr_op_templates.update_cache = NULL; 1493 + goto try_ssdr; 1494 + } 1495 + 1496 + spinand->op_templates = &spinand->odtr_op_templates; 1497 + spinand->bus_iface = ODTR; 1498 + 1499 + return 0; 1500 + } 1501 + 1502 + try_ssdr: 1503 + if (spinand->flags & SPINAND_HAS_QE_BIT) { 1504 + if (spinand->ssdr_op_templates.read_cache->data.buswidth == 4 || 1505 + spinand->ssdr_op_templates.write_cache->data.buswidth == 4 || 1506 + spinand->ssdr_op_templates.update_cache->data.buswidth == 4) 1507 + quad_enable = true; 1508 + } 1509 + 1510 + ret = spinand_init_quad_enable(spinand, quad_enable); 1511 + if (ret) 1512 + return ret; 1513 + 1514 + if (spinand->configure_chip) { 1515 + ret = spinand->configure_chip(spinand, SSDR); 1516 + if (ret) 1517 + return ret; 1518 + } 1519 + 1520 + return ret; 1521 + } 1522 + 1686 1523 static int spinand_init_flash(struct spinand_device *spinand) 1687 1524 { 1688 1525 struct device *dev = &spinand->spimem->spi->dev; ··· 1740 1477 int ret, i; 1741 1478 1742 1479 ret = spinand_read_cfg(spinand); 1743 - if (ret) 1744 - return ret; 1745 - 1746 - ret = spinand_init_quad_enable(spinand); 1747 1480 if (ret) 1748 1481 return ret; 1749 1482 ··· 1755 1496 return ret; 1756 1497 } 1757 1498 1499 + ret = spinand_configure_chip(spinand); 1500 + if (ret) 1501 + goto manuf_cleanup; 1502 + 1758 1503 /* After power up, all blocks are locked, so unlock them here. */ 1759 1504 for (i = 0; i < nand->memorg.ntargets; i++) { 1760 1505 ret = spinand_select_target(spinand, i); 1761 1506 if (ret) 1762 - break; 1507 + goto manuf_cleanup; 1763 1508 1764 1509 ret = spinand_lock_block(spinand, BL_ALL_UNLOCKED); 1765 1510 if (ret) 1766 - break; 1511 + goto manuf_cleanup; 1767 1512 } 1768 1513 1769 - if (ret) 1770 - spinand_manufacturer_cleanup(spinand); 1514 + return 0; 1515 + 1516 + manuf_cleanup: 1517 + spinand_manufacturer_cleanup(spinand); 1771 1518 1772 1519 return ret; 1773 1520 } ··· 1794 1529 spinand_ecc_enable(spinand, false); 1795 1530 } 1796 1531 1532 + static int spinand_mtd_suspend(struct mtd_info *mtd) 1533 + { 1534 + struct spinand_device *spinand = mtd_to_spinand(mtd); 1535 + int ret; 1536 + 1537 + /* 1538 + * Return to SSDR interface in the suspend path to make sure the 1539 + * reset operation is correctly processed upon resume. 1540 + * 1541 + * Note: Once back in SSDR mode, every operation but the page helpers 1542 + * (dirmap based I/O accessors) will work. Page accesses would require 1543 + * destroying and recreating the dirmaps twice to work, which would be 1544 + * impacting for no reason, as this is just a transitional state. 1545 + */ 1546 + if (spinand->bus_iface == ODTR) { 1547 + ret = spinand->configure_chip(spinand, SSDR); 1548 + if (ret) 1549 + return ret; 1550 + 1551 + spinand->op_templates = &spinand->ssdr_op_templates; 1552 + spinand->bus_iface = SSDR; 1553 + } 1554 + 1555 + return 0; 1556 + } 1557 + 1797 1558 static int spinand_init(struct spinand_device *spinand) 1798 1559 { 1799 1560 struct device *dev = &spinand->spimem->spi->dev; ··· 1834 1543 spinand->scratchbuf = kzalloc(SPINAND_MAX_ID_LEN, GFP_KERNEL); 1835 1544 if (!spinand->scratchbuf) 1836 1545 return -ENOMEM; 1546 + 1547 + spinand_init_ssdr_templates(spinand); 1837 1548 1838 1549 ret = spinand_detect(spinand); 1839 1550 if (ret) ··· 1889 1596 mtd->_block_isreserved = spinand_mtd_block_isreserved; 1890 1597 mtd->_erase = spinand_mtd_erase; 1891 1598 mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks; 1599 + mtd->_suspend = spinand_mtd_suspend; 1892 1600 mtd->_resume = spinand_mtd_resume; 1893 1601 1894 1602 if (spinand_user_otp_size(spinand) || spinand_fact_otp_size(spinand)) {
+91
drivers/mtd/nand/spi/dosilicon.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Author: Ahmed Naseef <naseefkm@gmail.com> 4 + */ 5 + 6 + #include <linux/device.h> 7 + #include <linux/kernel.h> 8 + #include <linux/mtd/spinand.h> 9 + 10 + #define SPINAND_MFR_DOSILICON 0xE5 11 + 12 + static SPINAND_OP_VARIANTS(read_cache_variants, 13 + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0), 14 + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0), 15 + SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0), 16 + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0)); 17 + 18 + static SPINAND_OP_VARIANTS(write_cache_variants, 19 + SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0), 20 + SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0)); 21 + 22 + static SPINAND_OP_VARIANTS(update_cache_variants, 23 + SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0), 24 + SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); 25 + 26 + static int ds35xx_ooblayout_ecc(struct mtd_info *mtd, int section, 27 + struct mtd_oob_region *region) 28 + { 29 + if (section > 3) 30 + return -ERANGE; 31 + 32 + region->offset = 8 + (section * 16); 33 + region->length = 8; 34 + 35 + return 0; 36 + } 37 + 38 + static int ds35xx_ooblayout_free(struct mtd_info *mtd, int section, 39 + struct mtd_oob_region *region) 40 + { 41 + if (section > 3) 42 + return -ERANGE; 43 + 44 + if (section == 0) { 45 + /* reserve 2 bytes for the BBM */ 46 + region->offset = 2; 47 + region->length = 6; 48 + } else { 49 + region->offset = section * 16; 50 + region->length = 8; 51 + } 52 + 53 + return 0; 54 + } 55 + 56 + static const struct mtd_ooblayout_ops ds35xx_ooblayout = { 57 + .ecc = ds35xx_ooblayout_ecc, 58 + .free = ds35xx_ooblayout_free, 59 + }; 60 + 61 + static const struct spinand_info dosilicon_spinand_table[] = { 62 + SPINAND_INFO("DS35Q1GA", 63 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71), 64 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 65 + NAND_ECCREQ(4, 512), 66 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 67 + &write_cache_variants, 68 + &update_cache_variants), 69 + SPINAND_HAS_QE_BIT, 70 + SPINAND_ECCINFO(&ds35xx_ooblayout, NULL)), 71 + SPINAND_INFO("DS35M1GA", 72 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21), 73 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 74 + NAND_ECCREQ(4, 512), 75 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 76 + &write_cache_variants, 77 + &update_cache_variants), 78 + SPINAND_HAS_QE_BIT, 79 + SPINAND_ECCINFO(&ds35xx_ooblayout, NULL)), 80 + }; 81 + 82 + static const struct spinand_manufacturer_ops dosilicon_spinand_manuf_ops = { 83 + }; 84 + 85 + const struct spinand_manufacturer dosilicon_spinand_manufacturer = { 86 + .id = SPINAND_MFR_DOSILICON, 87 + .name = "Dosilicon", 88 + .chips = dosilicon_spinand_table, 89 + .nchips = ARRAY_SIZE(dosilicon_spinand_table), 90 + .ops = &dosilicon_spinand_manuf_ops, 91 + };
+2 -2
drivers/mtd/nand/spi/esmt.c
··· 138 138 static int f50l1g41lb_otp_lock(struct spinand_device *spinand, loff_t from, 139 139 size_t len) 140 140 { 141 - struct spi_mem_op write_op = SPINAND_WR_EN_DIS_1S_0_0_OP(true); 142 - struct spi_mem_op exec_op = SPINAND_PROG_EXEC_1S_1S_0_OP(0); 141 + struct spi_mem_op write_op = SPINAND_OP(spinand, wr_en); 142 + struct spi_mem_op exec_op = SPINAND_OP(spinand, prog_exec, 0); 143 143 u8 status; 144 144 int ret; 145 145
+34
drivers/mtd/nand/spi/foresee.c
··· 11 11 12 12 #define SPINAND_MFR_FORESEE 0xCD 13 13 14 + #define F35SQB002G_STATUS_ECC_MASK (7 << 4) 15 + #define F35SQB002G_STATUS_ECC_NO_BITFLIPS (0 << 4) 16 + #define F35SQB002G_STATUS_ECC_1_3_BITFLIPS (1 << 4) 17 + #define F35SQB002G_STATUS_ECC_UNCOR_ERROR (7 << 4) 18 + 14 19 static SPINAND_OP_VARIANTS(read_cache_variants, 15 20 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0), 16 21 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0), ··· 75 70 return -EBADMSG; 76 71 } 77 72 73 + static int f35sqb002g_ecc_get_status(struct spinand_device *spinand, u8 status) 74 + { 75 + switch (status & F35SQB002G_STATUS_ECC_MASK) { 76 + case F35SQB002G_STATUS_ECC_NO_BITFLIPS: 77 + return 0; 78 + 79 + case F35SQB002G_STATUS_ECC_1_3_BITFLIPS: 80 + return 3; 81 + 82 + case F35SQB002G_STATUS_ECC_UNCOR_ERROR: 83 + return -EBADMSG; 84 + 85 + default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */ 86 + return ((status & F35SQB002G_STATUS_ECC_MASK) >> 4) + 2; 87 + } 88 + 89 + return -EINVAL; 90 + } 91 + 78 92 static const struct spinand_info foresee_spinand_table[] = { 79 93 SPINAND_INFO("F35SQA002G", 80 94 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x72, 0x72), ··· 115 91 SPINAND_HAS_QE_BIT, 116 92 SPINAND_ECCINFO(&f35sqa002g_ooblayout, 117 93 f35sqa002g_ecc_get_status)), 94 + SPINAND_INFO("F35SQB002G", 95 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52, 0x52), 96 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 97 + NAND_ECCREQ(8, 512), 98 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 99 + &write_cache_variants, 100 + &update_cache_variants), 101 + SPINAND_HAS_QE_BIT, 102 + SPINAND_ECCINFO(&f35sqa002g_ooblayout, 103 + f35sqb002g_ecc_get_status)), 118 104 }; 119 105 120 106 static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = {
+4 -4
drivers/mtd/nand/spi/gigadevice.c
··· 266 266 u8 status) 267 267 { 268 268 u8 status2; 269 - struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(GD5FXGQXXEXXG_REG_STATUS2, 270 - spinand->scratchbuf); 269 + struct spi_mem_op op = SPINAND_OP(spinand, get_feature, 270 + GD5FXGQXXEXXG_REG_STATUS2, spinand->scratchbuf); 271 271 int ret; 272 272 273 273 switch (status & STATUS_ECC_MASK) { ··· 309 309 u8 status) 310 310 { 311 311 u8 status2; 312 - struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(GD5FXGQXXEXXG_REG_STATUS2, 313 - spinand->scratchbuf); 312 + struct spi_mem_op op = SPINAND_OP(spinand, get_feature, 313 + GD5FXGQXXEXXG_REG_STATUS2, spinand->scratchbuf); 314 314 int ret; 315 315 316 316 switch (status & STATUS_ECC_MASK) {
+42 -7
drivers/mtd/nand/spi/macronix.c
··· 41 41 SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0), 42 42 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); 43 43 44 + #define SPINAND_MACRONIX_READ_ECCSR_1S_0_1S(buf) \ 45 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1), \ 46 + SPI_MEM_OP_NO_ADDR, \ 47 + SPI_MEM_OP_DUMMY(1, 1), \ 48 + SPI_MEM_OP_DATA_IN(1, buf, 1)) 49 + 50 + static SPINAND_OP_VARIANTS(macronix_ops, 51 + SPINAND_MACRONIX_READ_ECCSR_1S_0_1S(NULL)); 52 + 53 + static struct spi_mem_op 54 + spinand_fill_macronix_read_eccsr_op(struct spinand_device *spinand, void *valptr) 55 + { 56 + WARN_ON_ONCE(spinand->bus_iface != SSDR); 57 + 58 + return (struct spi_mem_op)SPINAND_MACRONIX_READ_ECCSR_1S_0_1S(valptr); 59 + } 60 + 44 61 static int mx35lfxge4ab_ooblayout_ecc(struct mtd_info *mtd, int section, 45 62 struct mtd_oob_region *region) 46 63 { ··· 84 67 static int macronix_get_eccsr(struct spinand_device *spinand, u8 *eccsr) 85 68 { 86 69 struct macronix_priv *priv = spinand->priv; 87 - struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1), 88 - SPI_MEM_OP_NO_ADDR, 89 - SPI_MEM_OP_DUMMY(1, 1), 90 - SPI_MEM_OP_DATA_IN(1, eccsr, 1)); 70 + struct spi_mem_op op = SPINAND_OP(spinand, macronix_read_eccsr, eccsr); 71 + int ret; 91 72 92 - int ret = spi_mem_exec_op(spinand->spimem, &op); 73 + ret = spi_mem_exec_op(spinand->spimem, &op); 93 74 if (ret) 94 75 return ret; 95 76 ··· 163 148 static int macronix_set_read_retry(struct spinand_device *spinand, 164 149 unsigned int retry_mode) 165 150 { 166 - struct spi_mem_op op = SPINAND_SET_FEATURE_1S_1S_1S_OP(MACRONIX_FEATURE_ADDR_READ_RETRY, 167 - spinand->scratchbuf); 151 + struct spi_mem_op op = SPINAND_OP(spinand, set_feature, 152 + MACRONIX_FEATURE_ADDR_READ_RETRY, spinand->scratchbuf); 168 153 169 154 *spinand->scratchbuf = retry_mode; 170 155 return spi_mem_exec_op(spinand->spimem, &op); ··· 179 164 &write_cache_variants, 180 165 &update_cache_variants), 181 166 SPINAND_HAS_QE_BIT, 167 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 182 168 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 183 169 macronix_ecc_get_status)), 184 170 SPINAND_INFO("MX35LF2GE4AB", ··· 201 185 &write_cache_variants, 202 186 &update_cache_variants), 203 187 SPINAND_HAS_QE_BIT, 188 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 204 189 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 205 190 macronix_ecc_get_status), 206 191 SPINAND_CONT_READ(macronix_set_cont_read), ··· 215 198 &write_cache_variants, 216 199 &update_cache_variants), 217 200 SPINAND_HAS_QE_BIT, 201 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 218 202 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 219 203 macronix_ecc_get_status), 220 204 SPINAND_CONT_READ(macronix_set_cont_read), ··· 286 268 &write_cache_variants, 287 269 &update_cache_variants), 288 270 SPINAND_HAS_QE_BIT, 271 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 289 272 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 290 273 macronix_ecc_get_status)), 291 274 SPINAND_INFO("MX31UF1GE4BC", ··· 297 278 &write_cache_variants, 298 279 &update_cache_variants), 299 280 SPINAND_HAS_QE_BIT, 281 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 300 282 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 301 283 macronix_ecc_get_status)), 302 284 ··· 311 291 SPINAND_HAS_QE_BIT | 312 292 SPINAND_HAS_PROG_PLANE_SELECT_BIT | 313 293 SPINAND_HAS_READ_PLANE_SELECT_BIT, 294 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 314 295 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 315 296 macronix_ecc_get_status)), 316 297 SPINAND_INFO("MX35UF4G24AD", ··· 323 302 &update_cache_variants), 324 303 SPINAND_HAS_QE_BIT | 325 304 SPINAND_HAS_PROG_PLANE_SELECT_BIT, 305 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 326 306 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 327 307 macronix_ecc_get_status), 328 308 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES, ··· 336 314 &write_cache_variants, 337 315 &update_cache_variants), 338 316 SPINAND_HAS_QE_BIT, 317 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 339 318 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 340 319 macronix_ecc_get_status), 341 320 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES, ··· 349 326 &write_cache_variants, 350 327 &update_cache_variants), 351 328 SPINAND_HAS_QE_BIT, 329 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 352 330 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 353 331 macronix_ecc_get_status), 354 332 SPINAND_CONT_READ(macronix_set_cont_read), ··· 365 341 SPINAND_HAS_QE_BIT | 366 342 SPINAND_HAS_PROG_PLANE_SELECT_BIT | 367 343 SPINAND_HAS_READ_PLANE_SELECT_BIT, 344 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 368 345 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 369 346 macronix_ecc_get_status)), 370 347 SPINAND_INFO("MX35UF2G24AD", ··· 377 352 &update_cache_variants), 378 353 SPINAND_HAS_QE_BIT | 379 354 SPINAND_HAS_PROG_PLANE_SELECT_BIT, 355 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 380 356 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 381 357 macronix_ecc_get_status), 382 358 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES, ··· 390 364 &write_cache_variants, 391 365 &update_cache_variants), 392 366 SPINAND_HAS_QE_BIT, 367 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 393 368 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 394 369 macronix_ecc_get_status), 395 370 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES, ··· 403 376 &write_cache_variants, 404 377 &update_cache_variants), 405 378 SPINAND_HAS_QE_BIT, 379 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 406 380 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 407 381 macronix_ecc_get_status), 408 382 SPINAND_CONT_READ(macronix_set_cont_read), ··· 417 389 &write_cache_variants, 418 390 &update_cache_variants), 419 391 SPINAND_HAS_QE_BIT, 392 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 420 393 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 421 394 macronix_ecc_get_status), 422 395 SPINAND_CONT_READ(macronix_set_cont_read)), ··· 429 400 &write_cache_variants, 430 401 &update_cache_variants), 431 402 SPINAND_HAS_QE_BIT, 403 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 432 404 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 433 405 macronix_ecc_get_status)), 434 406 SPINAND_INFO("MX35UF1G24AD", ··· 440 410 &write_cache_variants, 441 411 &update_cache_variants), 442 412 SPINAND_HAS_QE_BIT, 413 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 443 414 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 444 415 macronix_ecc_get_status), 445 416 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES, ··· 453 422 &write_cache_variants, 454 423 &update_cache_variants), 455 424 SPINAND_HAS_QE_BIT, 425 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 456 426 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 457 427 macronix_ecc_get_status), 458 428 SPINAND_CONT_READ(macronix_set_cont_read), ··· 467 435 &write_cache_variants, 468 436 &update_cache_variants), 469 437 SPINAND_HAS_QE_BIT, 438 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 470 439 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 471 440 macronix_ecc_get_status), 472 441 SPINAND_CONT_READ(macronix_set_cont_read)), ··· 479 446 &write_cache_variants, 480 447 &update_cache_variants), 481 448 SPINAND_HAS_QE_BIT, 449 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 482 450 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 483 451 macronix_ecc_get_status)), 484 452 SPINAND_INFO("MX3UF2GE4BC", ··· 490 456 &write_cache_variants, 491 457 &update_cache_variants), 492 458 SPINAND_HAS_QE_BIT, 459 + SPINAND_INFO_VENDOR_OPS(&macronix_ops), 493 460 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 494 461 macronix_ecc_get_status)), 495 462 };
+4 -4
drivers/mtd/nand/spi/micron.c
··· 137 137 static int micron_select_target(struct spinand_device *spinand, 138 138 unsigned int target) 139 139 { 140 - struct spi_mem_op op = SPINAND_SET_FEATURE_1S_1S_1S_OP(MICRON_DIE_SELECT_REG, 141 - spinand->scratchbuf); 140 + struct spi_mem_op op = SPINAND_OP(spinand, set_feature, 141 + MICRON_DIE_SELECT_REG, spinand->scratchbuf); 142 142 143 143 if (target > 1) 144 144 return -EINVAL; ··· 251 251 static int mt29f2g01abagd_otp_lock(struct spinand_device *spinand, loff_t from, 252 252 size_t len) 253 253 { 254 - struct spi_mem_op write_op = SPINAND_WR_EN_DIS_1S_0_0_OP(true); 255 - struct spi_mem_op exec_op = SPINAND_PROG_EXEC_1S_1S_0_OP(0); 254 + struct spi_mem_op write_op = SPINAND_OP(spinand, wr_en); 255 + struct spi_mem_op exec_op = SPINAND_OP(spinand, prog_exec, 0); 256 256 u8 status; 257 257 int ret; 258 258
+2 -1
drivers/mtd/nand/spi/toshiba.c
··· 73 73 { 74 74 struct nand_device *nand = spinand_to_nand(spinand); 75 75 u8 mbf = 0; 76 - struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(0x30, spinand->scratchbuf); 76 + struct spi_mem_op op = SPINAND_OP(spinand, get_feature, 77 + 0x30, spinand->scratchbuf); 77 78 78 79 switch (status & STATUS_ECC_MASK) { 79 80 case STATUS_ECC_NO_BITFLIPS:
+95 -34
drivers/mtd/nand/spi/winbond.c
··· 22 22 #define W25N0XJW_SR4 0xD0 23 23 #define W25N0XJW_SR4_HS BIT(2) 24 24 25 - #define W35N01JW_VCR_IO_MODE 0x00 25 + #define W35N01JW_VCR_IO_MODE_REG 0x00 26 26 #define W35N01JW_VCR_IO_MODE_SINGLE_SDR 0xFF 27 27 #define W35N01JW_VCR_IO_MODE_OCTAL_SDR 0xDF 28 28 #define W35N01JW_VCR_IO_MODE_OCTAL_DDR_DS 0xE7 ··· 36 36 */ 37 37 38 38 static SPINAND_OP_VARIANTS(read_cache_octal_variants, 39 + SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(0, 24, NULL, 0, 120 * HZ_PER_MHZ), 40 + SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(0, 16, NULL, 0, 86 * HZ_PER_MHZ), 39 41 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP(0, 3, NULL, 0, 120 * HZ_PER_MHZ), 40 42 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP(0, 2, NULL, 0, 105 * HZ_PER_MHZ), 41 43 SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP(0, 20, NULL, 0, 0), ··· 50 48 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0)); 51 49 52 50 static SPINAND_OP_VARIANTS(write_cache_octal_variants, 51 + SPINAND_PROG_LOAD_8D_8D_8D_OP(true, 0, NULL, 0), 53 52 SPINAND_PROG_LOAD_1S_8S_8S_OP(true, 0, NULL, 0), 54 53 SPINAND_PROG_LOAD_1S_1S_8S_OP(0, NULL, 0), 55 54 SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0)); 56 55 57 56 static SPINAND_OP_VARIANTS(update_cache_octal_variants, 57 + SPINAND_PROG_LOAD_8D_8D_8D_OP(false, 0, NULL, 0), 58 58 SPINAND_PROG_LOAD_1S_8S_8S_OP(false, 0, NULL, 0), 59 59 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); 60 60 ··· 91 87 SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0), 92 88 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); 93 89 90 + #define SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(reg, buf) \ 91 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x81, 1), \ 92 + SPI_MEM_OP_ADDR(3, reg, 1), \ 93 + SPI_MEM_OP_NO_DUMMY, \ 94 + SPI_MEM_OP_DATA_OUT(1, buf, 1)) 95 + 96 + #define SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(reg, buf) \ 97 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x81, 8), \ 98 + SPI_MEM_DTR_OP_ADDR(4, reg, 8), \ 99 + SPI_MEM_OP_NO_DUMMY, \ 100 + SPI_MEM_DTR_OP_DATA_OUT(2, buf, 8)) 101 + 102 + static SPINAND_OP_VARIANTS(winbond_w35_ops, 103 + SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(0, NULL), 104 + SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(0, NULL)); 105 + 106 + static struct spi_mem_op 107 + spinand_fill_winbond_write_vcr_op(struct spinand_device *spinand, u8 reg, void *valptr) 108 + { 109 + return (spinand->bus_iface == SSDR) ? 110 + (struct spi_mem_op)SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(reg, valptr) : 111 + (struct spi_mem_op)SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(reg, valptr); 112 + } 113 + 114 + #define SPINAND_WINBOND_SELECT_TARGET_1S_0_1S(buf) \ 115 + SPI_MEM_OP(SPI_MEM_OP_CMD(0xc2, 1), \ 116 + SPI_MEM_OP_NO_ADDR, \ 117 + SPI_MEM_OP_NO_DUMMY, \ 118 + SPI_MEM_OP_DATA_OUT(1, buf, 1)) 119 + 120 + static SPINAND_OP_VARIANTS(winbond_w25_ops, 121 + SPINAND_WINBOND_SELECT_TARGET_1S_0_1S(NULL)); 122 + 123 + static struct spi_mem_op 124 + spinand_fill_winbond_select_target_op(struct spinand_device *spinand, void *valptr) 125 + { 126 + WARN_ON_ONCE(spinand->bus_iface != SSDR); 127 + 128 + return (struct spi_mem_op)SPINAND_WINBOND_SELECT_TARGET_1S_0_1S(valptr); 129 + } 130 + 94 131 static int w25m02gv_ooblayout_ecc(struct mtd_info *mtd, int section, 95 132 struct mtd_oob_region *region) 96 133 { ··· 164 119 static int w25m02gv_select_target(struct spinand_device *spinand, 165 120 unsigned int target) 166 121 { 167 - struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0xc2, 1), 168 - SPI_MEM_OP_NO_ADDR, 169 - SPI_MEM_OP_NO_DUMMY, 170 - SPI_MEM_OP_DATA_OUT(1, 171 - spinand->scratchbuf, 172 - 1)); 122 + struct spi_mem_op op = SPINAND_OP(spinand, winbond_select_target, 123 + spinand->scratchbuf); 173 124 174 125 *spinand->scratchbuf = target; 175 126 return spi_mem_exec_op(spinand->spimem, &op); ··· 292 251 { 293 252 struct nand_device *nand = spinand_to_nand(spinand); 294 253 u8 mbf = 0; 295 - struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(0x30, spinand->scratchbuf); 254 + struct spi_mem_op op = SPINAND_OP(spinand, get_feature, 255 + 0x30, spinand->scratchbuf); 296 256 297 257 switch (status & STATUS_ECC_MASK) { 298 258 case STATUS_ECC_NO_BITFLIPS: ··· 326 284 return -EINVAL; 327 285 } 328 286 329 - static int w25n0xjw_hs_cfg(struct spinand_device *spinand) 287 + static int w25n0xjw_hs_cfg(struct spinand_device *spinand, 288 + enum spinand_bus_interface iface) 330 289 { 331 290 const struct spi_mem_op *op; 332 291 bool hs; 333 292 u8 sr4; 334 293 int ret; 335 294 336 - op = spinand->op_templates.read_cache; 295 + if (iface != SSDR) 296 + return -EOPNOTSUPP; 297 + 298 + op = spinand->op_templates->read_cache; 337 299 if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) 338 300 hs = false; 339 301 else if (op->cmd.buswidth == 1 && op->addr.buswidth == 1 && ··· 366 320 367 321 static int w35n0xjw_write_vcr(struct spinand_device *spinand, u8 reg, u8 val) 368 322 { 369 - struct spi_mem_op op = 370 - SPI_MEM_OP(SPI_MEM_OP_CMD(0x81, 1), 371 - SPI_MEM_OP_ADDR(3, reg, 1), 372 - SPI_MEM_OP_NO_DUMMY, 373 - SPI_MEM_OP_DATA_OUT(1, spinand->scratchbuf, 1)); 323 + struct spi_mem_op op = SPINAND_OP(spinand, winbond_write_vcr, 324 + reg, spinand->scratchbuf); 374 325 int ret; 375 326 376 327 *spinand->scratchbuf = val; ··· 390 347 return 0; 391 348 } 392 349 393 - static int w35n0xjw_vcr_cfg(struct spinand_device *spinand) 350 + static int w35n0xjw_vcr_cfg(struct spinand_device *spinand, 351 + enum spinand_bus_interface iface) 394 352 { 395 - const struct spi_mem_op *op; 353 + const struct spi_mem_op *ref_op; 396 354 unsigned int dummy_cycles; 397 355 bool dtr, single; 398 356 u8 io_mode; 399 357 int ret; 400 358 401 - op = spinand->op_templates.read_cache; 359 + switch (iface) { 360 + case SSDR: 361 + ref_op = spinand->ssdr_op_templates.read_cache; 362 + break; 363 + case ODTR: 364 + ref_op = spinand->odtr_op_templates.read_cache; 365 + break; 366 + default: 367 + return -EOPNOTSUPP; 368 + } 402 369 403 - single = (op->cmd.buswidth == 1 && op->addr.buswidth == 1 && op->data.buswidth == 1); 404 - dtr = (op->cmd.dtr || op->addr.dtr || op->data.dtr); 405 - if (single && !dtr) 406 - io_mode = W35N01JW_VCR_IO_MODE_SINGLE_SDR; 407 - else if (!single && !dtr) 408 - io_mode = W35N01JW_VCR_IO_MODE_OCTAL_SDR; 409 - else if (!single && dtr) 410 - io_mode = W35N01JW_VCR_IO_MODE_OCTAL_DDR; 411 - else 412 - return -EINVAL; 413 - 414 - ret = w35n0xjw_write_vcr(spinand, W35N01JW_VCR_IO_MODE, io_mode); 415 - if (ret) 416 - return ret; 417 - 418 - dummy_cycles = ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1); 370 + dummy_cycles = ((ref_op->dummy.nbytes * 8) / ref_op->dummy.buswidth) / 371 + (ref_op->dummy.dtr ? 2 : 1); 419 372 switch (dummy_cycles) { 420 373 case 8: 421 374 case 12: ··· 423 384 default: 424 385 return -EINVAL; 425 386 } 387 + 426 388 ret = w35n0xjw_write_vcr(spinand, W35N01JW_VCR_DUMMY_CLOCK_REG, dummy_cycles); 389 + if (ret) 390 + return ret; 391 + 392 + single = (ref_op->cmd.buswidth == 1 && 393 + ref_op->addr.buswidth == 1 && 394 + ref_op->data.buswidth == 1); 395 + dtr = (ref_op->cmd.dtr && ref_op->addr.dtr && ref_op->data.dtr); 396 + if (single && !dtr) 397 + io_mode = W35N01JW_VCR_IO_MODE_SINGLE_SDR; 398 + else if (!single && !dtr) 399 + io_mode = W35N01JW_VCR_IO_MODE_OCTAL_SDR; 400 + else if (!single && dtr) 401 + io_mode = W35N01JW_VCR_IO_MODE_OCTAL_DDR; 402 + else 403 + return -EINVAL; 404 + 405 + ret = w35n0xjw_write_vcr(spinand, W35N01JW_VCR_IO_MODE_REG, io_mode); 427 406 if (ret) 428 407 return ret; 429 408 ··· 505 448 &write_cache_octal_variants, 506 449 &update_cache_octal_variants), 507 450 0, 451 + SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops), 508 452 SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL), 509 453 SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)), 510 454 SPINAND_INFO("W35N02JW", /* 1.8V */ ··· 516 458 &write_cache_octal_variants, 517 459 &update_cache_octal_variants), 518 460 0, 461 + SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops), 519 462 SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL), 520 463 SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)), 521 464 SPINAND_INFO("W35N04JW", /* 1.8V */ ··· 527 468 &write_cache_octal_variants, 528 469 &update_cache_octal_variants), 529 470 0, 471 + SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops), 530 472 SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL), 531 473 SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)), 532 474 /* 2G-bit densities */ ··· 539 479 &write_cache_variants, 540 480 &update_cache_variants), 541 481 0, 482 + SPINAND_INFO_VENDOR_OPS(&winbond_w25_ops), 542 483 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), 543 484 SPINAND_SELECT_TARGET(w25m02gv_select_target)), 544 485 SPINAND_INFO("W25N02JW", /* high-speed 1.8V */
-6
drivers/mtd/parsers/ofpart_bcm4908.h
··· 4 4 5 5 #ifdef CONFIG_MTD_OF_PARTS_BCM4908 6 6 int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts); 7 - #else 8 - static inline int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, 9 - int nr_parts) 10 - { 11 - return -EOPNOTSUPP; 12 - } 13 7 #endif 14 8 15 9 #endif
+22 -2
drivers/mtd/parsers/ofpart_core.c
··· 23 23 int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts); 24 24 }; 25 25 26 + #ifdef CONFIG_MTD_OF_PARTS_BCM4908 26 27 static struct fixed_partitions_quirks bcm4908_partitions_quirks = { 27 28 .post_parse = bcm4908_partitions_post_parse, 28 29 }; 30 + #endif 29 31 32 + #ifdef CONFIG_MTD_OF_PARTS_LINKSYS_NS 30 33 static struct fixed_partitions_quirks linksys_ns_partitions_quirks = { 31 34 .post_parse = linksys_ns_partitions_post_parse, 32 35 }; 36 + #endif 33 37 34 38 static const struct of_device_id parse_ofpart_match_table[]; 35 39 ··· 81 77 of_id = of_match_node(parse_ofpart_match_table, ofpart_node); 82 78 if (dedicated && !of_id) { 83 79 /* The 'partitions' subnode might be used by another parser */ 80 + of_node_put(ofpart_node); 84 81 return 0; 85 82 } 86 83 ··· 96 91 nr_parts++; 97 92 } 98 93 99 - if (nr_parts == 0) 94 + if (nr_parts == 0) { 95 + if (dedicated) 96 + of_node_put(ofpart_node); 100 97 return 0; 98 + } 101 99 102 100 parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); 103 - if (!parts) 101 + if (!parts) { 102 + if (dedicated) 103 + of_node_put(ofpart_node); 104 104 return -ENOMEM; 105 + } 105 106 106 107 i = 0; 107 108 for_each_child_of_node(ofpart_node, pp) { ··· 186 175 if (quirks && quirks->post_parse) 187 176 quirks->post_parse(master, parts, nr_parts); 188 177 178 + if (dedicated) 179 + of_node_put(ofpart_node); 180 + 189 181 *pparts = parts; 190 182 return nr_parts; 191 183 ··· 197 183 master->name, pp, mtd_node); 198 184 ret = -EINVAL; 199 185 ofpart_none: 186 + if (dedicated) 187 + of_node_put(ofpart_node); 200 188 of_node_put(pp); 201 189 kfree(parts); 202 190 return ret; ··· 208 192 /* Generic */ 209 193 { .compatible = "fixed-partitions" }, 210 194 /* Customized */ 195 + #ifdef CONFIG_MTD_OF_PARTS_BCM4908 211 196 { .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, }, 197 + #endif 198 + #ifdef CONFIG_MTD_OF_PARTS_LINKSYS_NS 212 199 { .compatible = "linksys,ns-partitions", .data = &linksys_ns_partitions_quirks, }, 200 + #endif 213 201 {}, 214 202 }; 215 203 MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
-7
drivers/mtd/parsers/ofpart_linksys_ns.h
··· 6 6 int linksys_ns_partitions_post_parse(struct mtd_info *mtd, 7 7 struct mtd_partition *parts, 8 8 int nr_parts); 9 - #else 10 - static inline int linksys_ns_partitions_post_parse(struct mtd_info *mtd, 11 - struct mtd_partition *parts, 12 - int nr_parts) 13 - { 14 - return -EOPNOTSUPP; 15 - } 16 9 #endif 17 10 18 11 #endif
+2 -6
drivers/mtd/spi-nor/controllers/hisi-sfc.c
··· 394 394 static int hisi_spi_nor_register_all(struct hifmc_host *host) 395 395 { 396 396 struct device *dev = host->dev; 397 - struct device_node *np; 398 397 int ret; 399 398 400 - for_each_available_child_of_node(dev->of_node, np) { 399 + for_each_available_child_of_node_scoped(dev->of_node, np) { 401 400 ret = hisi_spi_nor_register(np, host); 402 - if (ret) { 403 - of_node_put(np); 401 + if (ret) 404 402 goto fail; 405 - } 406 403 407 404 if (host->num_chip == HIFMC_MAX_CHIP_NUM) { 408 405 dev_warn(dev, "Flash device number exceeds the maximum chipselect number\n"); 409 - of_node_put(np); 410 406 break; 411 407 } 412 408 }
+144 -18
include/linux/mtd/spinand.h
··· 26 26 SPI_MEM_OP_NO_DUMMY, \ 27 27 SPI_MEM_OP_NO_DATA) 28 28 29 - #define SPINAND_WR_EN_DIS_1S_0_0_OP(enable) \ 30 - SPI_MEM_OP(SPI_MEM_OP_CMD((enable) ? 0x06 : 0x04, 1), \ 29 + #define SPINAND_WR_EN_1S_0_0_OP \ 30 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x06, 1), \ 31 + SPI_MEM_OP_NO_ADDR, \ 32 + SPI_MEM_OP_NO_DUMMY, \ 33 + SPI_MEM_OP_NO_DATA) 34 + 35 + #define SPINAND_WR_DIS_1S_0_0_OP \ 36 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x04, 1), \ 31 37 SPI_MEM_OP_NO_ADDR, \ 32 38 SPI_MEM_OP_NO_DUMMY, \ 33 39 SPI_MEM_OP_NO_DATA) ··· 239 233 SPI_MEM_OP_DATA_OUT(len, buf, 8)) 240 234 241 235 /** 242 - * Standard SPI NAND flash commands 236 + * Octal DDR SPI NAND flash operations 243 237 */ 244 - #define SPINAND_CMD_PROG_LOAD_X4 0x32 245 - #define SPINAND_CMD_PROG_LOAD_RDM_DATA_X4 0x34 238 + 239 + #define SPINAND_RESET_8D_0_0_OP \ 240 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0xff, 8), \ 241 + SPI_MEM_OP_NO_ADDR, \ 242 + SPI_MEM_OP_NO_DUMMY, \ 243 + SPI_MEM_OP_NO_DATA) 244 + 245 + #define SPINAND_READID_8D_8D_8D_OP(naddr, ndummy, buf, len) \ 246 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x9f, 8), \ 247 + SPI_MEM_DTR_OP_ADDR(naddr, 0, 8), \ 248 + SPI_MEM_DTR_OP_DUMMY(ndummy, 8), \ 249 + SPI_MEM_DTR_OP_DATA_IN(len, buf, 8)) 250 + 251 + #define SPINAND_WR_EN_8D_0_0_OP \ 252 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x06, 8), \ 253 + SPI_MEM_OP_NO_ADDR, \ 254 + SPI_MEM_OP_NO_DUMMY, \ 255 + SPI_MEM_OP_NO_DATA) 256 + 257 + #define SPINAND_WR_DIS_8D_0_0_OP \ 258 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x04, 8), \ 259 + SPI_MEM_OP_NO_ADDR, \ 260 + SPI_MEM_OP_NO_DUMMY, \ 261 + SPI_MEM_OP_NO_DATA) 262 + 263 + #define SPINAND_SET_FEATURE_8D_8D_8D_OP(reg, valptr) \ 264 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x1f, 8), \ 265 + SPI_MEM_DTR_OP_RPT_ADDR(reg, 8), \ 266 + SPI_MEM_OP_NO_DUMMY, \ 267 + SPI_MEM_DTR_OP_DATA_OUT(2, valptr, 8)) 268 + 269 + #define SPINAND_GET_FEATURE_8D_8D_8D_OP(reg, valptr) \ 270 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x0f, 8), \ 271 + SPI_MEM_DTR_OP_RPT_ADDR(reg, 8), \ 272 + SPI_MEM_DTR_OP_DUMMY(14, 8), \ 273 + SPI_MEM_DTR_OP_DATA_IN(2, valptr, 8)) 274 + 275 + #define SPINAND_BLK_ERASE_8D_8D_0_OP(addr) \ 276 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0xd8, 8), \ 277 + SPI_MEM_DTR_OP_ADDR(2, addr, 8), \ 278 + SPI_MEM_OP_NO_DUMMY, \ 279 + SPI_MEM_OP_NO_DATA) 280 + 281 + #define SPINAND_PAGE_READ_8D_8D_0_OP(addr) \ 282 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x13, 8), \ 283 + SPI_MEM_DTR_OP_ADDR(2, addr, 8), \ 284 + SPI_MEM_OP_NO_DUMMY, \ 285 + SPI_MEM_OP_NO_DATA) 286 + 287 + #define SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(addr, ndummy, buf, len, freq) \ 288 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x9d, 8), \ 289 + SPI_MEM_DTR_OP_ADDR(2, addr, 8), \ 290 + SPI_MEM_DTR_OP_DUMMY(ndummy, 8), \ 291 + SPI_MEM_DTR_OP_DATA_IN(len, buf, 8), \ 292 + SPI_MEM_OP_MAX_FREQ(freq)) 293 + 294 + #define SPINAND_PROG_EXEC_8D_8D_0_OP(addr) \ 295 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x10, 8), \ 296 + SPI_MEM_DTR_OP_ADDR(2, addr, 8), \ 297 + SPI_MEM_OP_NO_DUMMY, \ 298 + SPI_MEM_OP_NO_DATA) 299 + 300 + #define SPINAND_PROG_LOAD_8D_8D_8D_OP(reset, addr, buf, len) \ 301 + SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD((reset ? 0xc2 : 0xc4), 8), \ 302 + SPI_MEM_DTR_OP_ADDR(2, addr, 8), \ 303 + SPI_MEM_OP_NO_DUMMY, \ 304 + SPI_MEM_DTR_OP_DATA_OUT(len, buf, 8)) 246 305 247 306 /* feature register */ 248 307 #define REG_BLOCK_LOCK 0xa0 ··· 332 261 struct spinand_op; 333 262 struct spinand_device; 334 263 335 - #define SPINAND_MAX_ID_LEN 5 264 + #define SPINAND_MAX_ID_LEN 6 336 265 /* 337 266 * For erase, write and read operation, we got the following timings : 338 267 * tBERS (erase) 1ms to 4ms ··· 358 287 359 288 /** 360 289 * struct spinand_id - SPI NAND id structure 361 - * @data: buffer containing the id bytes. Currently 4 bytes large, but can 290 + * @data: buffer containing the id bytes. Currently 6 bytes large, but can 362 291 * be extended if required 363 292 * @len: ID length 364 293 */ ··· 425 354 /* SPI NAND manufacturers */ 426 355 extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; 427 356 extern const struct spinand_manufacturer ato_spinand_manufacturer; 357 + extern const struct spinand_manufacturer dosilicon_spinand_manufacturer; 428 358 extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer; 429 359 extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; 430 360 extern const struct spinand_manufacturer fmsh_spinand_manufacturer; ··· 554 482 }; 555 483 556 484 /** 485 + * enum spinand_bus_interface - SPI NAND bus interface types 486 + * @SSDR: Bus configuration supporting all 1S-XX-XX operations, including dual and quad 487 + * @ODTR: Bus configuration supporting only 8D-8D-8D operations 488 + */ 489 + enum spinand_bus_interface { 490 + SSDR, 491 + ODTR, 492 + }; 493 + 494 + /** 557 495 * struct spinand_info - Structure used to describe SPI NAND chips 558 496 * @model: model name 559 497 * @devid: device ID ··· 575 493 * @op_variants.read_cache: variants of the read-cache operation 576 494 * @op_variants.write_cache: variants of the write-cache operation 577 495 * @op_variants.update_cache: variants of the update-cache operation 496 + * @vendor_ops: vendor specific operations 578 497 * @select_target: function used to select a target/die. Required only for 579 498 * multi-die chips 580 499 * @configure_chip: Align the chip configuration with the core settings ··· 600 517 const struct spinand_op_variants *write_cache; 601 518 const struct spinand_op_variants *update_cache; 602 519 } op_variants; 520 + const struct spinand_op_variants *vendor_ops; 603 521 int (*select_target)(struct spinand_device *spinand, 604 522 unsigned int target); 605 - int (*configure_chip)(struct spinand_device *spinand); 523 + int (*configure_chip)(struct spinand_device *spinand, 524 + enum spinand_bus_interface iface); 606 525 int (*set_cont_read)(struct spinand_device *spinand, 607 526 bool enable); 608 527 struct spinand_fact_otp fact_otp; ··· 627 542 .write_cache = __write, \ 628 543 .update_cache = __update, \ 629 544 } 545 + 546 + #define SPINAND_INFO_VENDOR_OPS(__ops) \ 547 + .vendor_ops = __ops 630 548 631 549 #define SPINAND_ECCINFO(__ooblayout, __get_status) \ 632 550 .eccinfo = { \ ··· 688 600 }; 689 601 690 602 /** 603 + * struct spinand_mem_ops - SPI NAND memory operations 604 + * @reset: reset op template 605 + * @readid: read ID op template 606 + * @wr_en: write enable op template 607 + * @wr_dis: write disable op template 608 + * @set_feature: set feature op template 609 + * @get_feature: get feature op template 610 + * @blk_erase: blk erase op template 611 + * @page_read: page read op template 612 + * @prog_exec: prog exec op template 613 + * @read_cache: read cache op template 614 + * @write_cache: write cache op template 615 + * @update_cache: update cache op template 616 + */ 617 + struct spinand_mem_ops { 618 + struct spi_mem_op reset; 619 + struct spi_mem_op readid; 620 + struct spi_mem_op wr_en; 621 + struct spi_mem_op wr_dis; 622 + struct spi_mem_op set_feature; 623 + struct spi_mem_op get_feature; 624 + struct spi_mem_op blk_erase; 625 + struct spi_mem_op page_read; 626 + struct spi_mem_op prog_exec; 627 + const struct spi_mem_op *read_cache; 628 + const struct spi_mem_op *write_cache; 629 + const struct spi_mem_op *update_cache; 630 + }; 631 + 632 + /** 691 633 * struct spinand_device - SPI NAND device instance 692 634 * @base: NAND device instance 693 635 * @spimem: pointer to the SPI mem object 694 636 * @lock: lock used to serialize accesses to the NAND 695 637 * @id: NAND ID as returned by READ_ID 696 638 * @flags: NAND flags 697 - * @op_templates: various SPI mem op templates 698 - * @op_templates.read_cache: read cache op template 699 - * @op_templates.write_cache: write cache op template 700 - * @op_templates.update_cache: update cache op template 639 + * @ssdr_op_templates: Templates for all single SDR SPI mem operations 640 + * @odtr_op_templates: Templates for all octal DTR SPI mem operations 641 + * @op_templates: Templates for all SPI mem operations 642 + * @bus_iface: Current bus interface 701 643 * @select_target: select a specific target/die. Usually called before sending 702 644 * a command addressing a page or an eraseblock embedded in 703 645 * this die. Only required if your chip exposes several dies ··· 761 643 struct spinand_id id; 762 644 u32 flags; 763 645 764 - struct { 765 - const struct spi_mem_op *read_cache; 766 - const struct spi_mem_op *write_cache; 767 - const struct spi_mem_op *update_cache; 768 - } op_templates; 646 + struct spinand_mem_ops ssdr_op_templates; 647 + struct spinand_mem_ops odtr_op_templates; 648 + struct spinand_mem_ops *op_templates; 649 + enum spinand_bus_interface bus_iface; 769 650 770 651 struct spinand_dirmap *dirmaps; 771 652 ··· 781 664 const struct spinand_manufacturer *manufacturer; 782 665 void *priv; 783 666 784 - int (*configure_chip)(struct spinand_device *spinand); 667 + int (*configure_chip)(struct spinand_device *spinand, 668 + enum spinand_bus_interface iface); 785 669 bool cont_read_possible; 786 670 int (*set_cont_read)(struct spinand_device *spinand, 787 671 bool enable); ··· 794 676 int (*set_read_retry)(struct spinand_device *spinand, 795 677 unsigned int retry_mode); 796 678 }; 679 + 680 + struct spi_mem_op spinand_fill_wr_en_op(struct spinand_device *spinand); 681 + struct spi_mem_op spinand_fill_set_feature_op(struct spinand_device *spinand, u64 reg, const void *valptr); 682 + struct spi_mem_op spinand_fill_get_feature_op(struct spinand_device *spinand, u64 reg, void *valptr); 683 + struct spi_mem_op spinand_fill_prog_exec_op(struct spinand_device *spinand, u64 addr); 684 + 685 + #define SPINAND_OP(spinand, op_name, ...) \ 686 + spinand_fill_ ## op_name ## _op(spinand, ##__VA_ARGS__) 797 687 798 688 /** 799 689 * mtd_to_spinand() - Get the SPI NAND device attached to an MTD instance
+8
include/linux/spi/spi-mem.h
··· 51 51 .dtr = true, \ 52 52 } 53 53 54 + #define SPI_MEM_DTR_OP_RPT_ADDR(__val, __buswidth) \ 55 + { \ 56 + .nbytes = 2, \ 57 + .val = __val | __val << 8, \ 58 + .buswidth = __buswidth, \ 59 + .dtr = true, \ 60 + } 61 + 54 62 #define SPI_MEM_OP_NO_ADDR { } 55 63 56 64 #define SPI_MEM_OP_DUMMY(__nbytes, __buswidth) \