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-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux

Pull mtd updates from Miquel Raynal:
"MTD core changes:
- Fix refcount error in del_mtd_device()
- Fix possible resource leak in init_mtd()
- Set ROOT_DEV for partitions marked as rootfs in DT
- Describe marking rootfs partitions in the bindings
- Fix device name leak when register device fails in add_mtd_device()
- Try to find OF node for every MTD partition
- simplify (a bit) code find partition-matching dynamic OF node

MTD driver changes:
- pxa2xx-flash maps: fix memory leak in probe
- BCM parser: refer to ARCH_BCMBCA instead of ARCH_BCM4908
- lpddr2_nvm: Fix possible null-ptr-deref
- inftlcore: fix repeated words in comments
- lart: remove driver
- tplink:
- Add TP-Link SafeLoader partitions table parser and bindings
- Describe TP-Link SafeLoader parser
- Describe TP-Link SafeLoader dynamic subpartitions
- mtdoops:
- Panic caused mtdoops to call mtdoops_erase function immediately
- Add mtdoops_erase function and move mtdoops_inc_counter after it
- Change printk() to counterpart pr_ functions

MTD binding cleanup:
- Fixed-partitions: Fix 'sercomm,scpart-id' schema
- Standardize the style in the examples
- Drop object types when referencing other files
- Argue in favor of keeping additionalProperties set to true
- NVMEM-cells:
- Inherit from MTD partitions
- Drop range property from example
- Partitions:
- Change qcom,smem-part partition type
- Constrain the list of parsers
- Physmap: Reuse the generic definitions
- SPI-NOR: Drop common properties
- Sunxi-nand: Add an example to validate the bindings
- Onenand: Mention the expected node name
- Ingenic: Mark partitions in the controller node as deprecated
- NAND:
- Standardize the child node name
- Drop common properties already defined in generic files
- nand-chip.yaml should reference mtd.yaml
- Remove useless file about partitions
- Clarify all partition subnodes

SPI NOR core changes:
- Add support for flash reset using the dt reset-gpios property.
- Update hwcaps.mask to include 8D-8D-8D read and page program ops
when xSPI profile 1.0 table is defined.
- Bypass zero erase size in spi_nor_find_best_erase_type().
- Fix select_uniform_erase to skip 0 erase size
- Add generic flash driver. If a flash is not found in the flash_info
array, fall back to the generic flash driver which is described
solely by the flash's SFDP tables.
- Fix the number of bytes for the dummy cycles in
spi_nor_spimem_check_readop().
- Introduce SPI_NOR_QUAD_PP flag, as PP_1_1_4 is not SFDP
discoverable.

SPI NOR manufacturer drivers changes:
- Spansion:
- use PARSE_SFDP for s28hs512t,
- add support for s28hl512t, s28hl01gt, and s28hs01gt.
- Gigadevice: Replace default_init() with post_bfpt() for gd25q256.
- Micron - ST: Enable locking for mt25qu256a.
- Winbond: Add support for W25Q512NW-IQ.
- ISSI: Use PARSE_SFDP and SPI_NOR_QUAD_PP.

Raw NAND core changes:
- Drop obsolete dependencies on COMPILE_TEST
- MAINTAINERS: rectify entry for MESON NAND controller bindings
- Drop EXPORT_SYMBOL_GPL for nanddev_erase()

Raw NAND driver changes:
- marvell: Enable NFC/DEVBUS arbiter
- gpmi: Use pm_runtime_resume_and_get instead of pm_runtime_get_sync
- mpc5121: Replace NO_IRQ by 0
- lpc32xx_{slc,mlc}:
- Switch to using pm_ptr()
- Switch to using gpiod API
- lpc32xx_mlc: Switch to using pm_ptr()
- cadence: Support 64-bit slave dma interface
- rockchip: Describe rk3128-nfc in the bindings
- brcmnand: Update interrupts description in the bindings

SPI-NAND driver changes:
- winbond:
- Add Winbond W25N02KV flash support
- Fix flash identification"

* tag 'mtd/for-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (76 commits)
mtd: rawnand: Drop obsolete dependencies on COMPILE_TEST
mtd: maps: pxa2xx-flash: fix memory leak in probe
mtd: core: Fix refcount error in del_mtd_device()
mtd: spi-nor: add SFDP fixups for Quad Page Program
mtd: spi-nor: issi: is25wp256: Init flash based on SFDP
mtd: spi-nor: winbond: add support for W25Q512NW-IQ
mtd: spi-nor: micron-st: Enable locking for mt25qu256a
mtd: spi-nor: Fix the number of bytes for the dummy cycles
mtd: spi-nor: gigadevice: gd25q256: replace gd25q256_default_init with gd25q256_post_bfpt
mtd: spi-nor: Fix formatting in spi_nor_read_raw() kerneldoc comment
mtd: spi-nor: sysfs: print JEDEC ID for generic flash driver
mtd: spi-nor: add generic flash driver
mtd: spi-nor: fix select_uniform_erase to skip 0 erase size
mtd: spi-nor: move function declaration out of sfdp.h
mtd: spi-nor: remember full JEDEC flash ID
mtd: spi-nor: sysfs: hide manufacturer if it is not set
mtd: spi-nor: hide jedec_id sysfs attribute if not present
mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type()
mtd: rawnand: marvell: Enable NFC/DEVBUS arbiter
mtd: parsers: refer to ARCH_BCMBCA instead of ARCH_BCM4908
...

+1153 -1256
+6
Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
··· 5 5 Description: (RO) The JEDEC ID of the SPI NOR flash as reported by the 6 6 flash device. 7 7 8 + The attribute is not present if the flash doesn't support 9 + the "Read JEDEC ID" command (9Fh). This is the case for 10 + non-JEDEC compliant flashes. 8 11 9 12 What: /sys/bus/spi/devices/.../spi-nor/manufacturer 10 13 Date: April 2021 ··· 15 12 Contact: linux-mtd@lists.infradead.org 16 13 Description: (RO) Manufacturer of the SPI NOR flash. 17 14 15 + The attribute is not present if the flash device isn't 16 + known to the kernel and is only probed by its SFDP 17 + tables. 18 18 19 19 What: /sys/bus/spi/devices/.../spi-nor/partname 20 20 Date: April 2021
+25 -9
Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml
··· 14 14 - Maxime Ripard <mripard@kernel.org> 15 15 16 16 properties: 17 - "#address-cells": true 18 - "#size-cells": true 19 - 20 17 compatible: 21 18 enum: 22 19 - allwinner,sun4i-a10-nand ··· 46 49 dma-names: 47 50 const: rxtx 48 51 49 - pinctrl-names: true 50 - 51 52 patternProperties: 52 - "^pinctrl-[0-9]+$": true 53 - 54 - "^nand@[a-f0-9]+$": 53 + "^nand@[a-f0-9]$": 55 54 type: object 56 55 properties: 57 56 reg: ··· 84 91 - clocks 85 92 - clock-names 86 93 87 - additionalProperties: false 94 + unevaluatedProperties: false 95 + 96 + examples: 97 + - | 98 + #include <dt-bindings/interrupt-controller/arm-gic.h> 99 + #include <dt-bindings/clock/sun6i-rtc.h> 100 + #include <dt-bindings/clock/sun8i-a23-a33-ccu.h> 101 + #include <dt-bindings/reset/sun8i-a23-a33-ccu.h> 102 + 103 + nand-controller@1c03000 { 104 + compatible = "allwinner,sun8i-a23-nand-controller"; 105 + reg = <0x01c03000 0x1000>; 106 + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; 107 + clocks = <&ccu CLK_BUS_NAND>, <&ccu CLK_NAND>; 108 + clock-names = "ahb", "mod"; 109 + resets = <&ccu RST_BUS_NAND>; 110 + reset-names = "ahb"; 111 + dmas = <&dma 5>; 112 + dma-names = "rxtx"; 113 + pinctrl-names = "default"; 114 + pinctrl-0 = <&nand_pins &nand_cs0_pin &nand_rb0_pin>; 115 + #address-cells = <1>; 116 + #size-cells = <0>; 117 + }; 88 118 89 119 ...
+1 -4
Documentation/devicetree/bindings/mtd/arasan,nand-controller.yaml
··· 35 35 interrupts: 36 36 maxItems: 1 37 37 38 - "#address-cells": true 39 - "#size-cells": true 40 - 41 38 required: 42 39 - compatible 43 40 - reg ··· 42 45 - clock-names 43 46 - interrupts 44 47 45 - additionalProperties: true 48 + unevaluatedProperties: true 46 49 47 50 examples: 48 51 - |
+15 -15
Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml
··· 34 34 examples: 35 35 - | 36 36 smcc: memory-controller@e000e000 { 37 - compatible = "arm,pl353-smc-r2p1", "arm,primecell"; 38 - reg = <0xe000e000 0x0001000>; 39 - clock-names = "memclk", "apb_pclk"; 40 - clocks = <&clkc 11>, <&clkc 44>; 41 - ranges = <0x0 0x0 0xe1000000 0x1000000 /* Nand CS region */ 42 - 0x1 0x0 0xe2000000 0x2000000 /* SRAM/NOR CS0 region */ 43 - 0x2 0x0 0xe4000000 0x2000000>; /* SRAM/NOR CS1 region */ 44 - #address-cells = <2>; 45 - #size-cells = <1>; 37 + compatible = "arm,pl353-smc-r2p1", "arm,primecell"; 38 + reg = <0xe000e000 0x0001000>; 39 + clock-names = "memclk", "apb_pclk"; 40 + clocks = <&clkc 11>, <&clkc 44>; 41 + ranges = <0x0 0x0 0xe1000000 0x1000000 /* Nand CS region */ 42 + 0x1 0x0 0xe2000000 0x2000000 /* SRAM/NOR CS0 region */ 43 + 0x2 0x0 0xe4000000 0x2000000>; /* SRAM/NOR CS1 region */ 44 + #address-cells = <2>; 45 + #size-cells = <1>; 46 46 47 - nfc0: nand-controller@0,0 { 48 - compatible = "arm,pl353-nand-r2p1"; 49 - reg = <0 0 0x1000000>; 50 - #address-cells = <1>; 51 - #size-cells = <0>; 52 - }; 47 + nfc0: nand-controller@0,0 { 48 + compatible = "arm,pl353-nand-r2p1"; 49 + reg = <0 0 0x1000000>; 50 + #address-cells = <1>; 51 + #size-cells = <0>; 52 + }; 53 53 };
+2 -4
Documentation/devicetree/bindings/mtd/atmel-nand.txt
··· 45 45 - atmel,rb: an integer identifying the native Ready/Busy pin. Only meaningful 46 46 on sama5 SoCs. 47 47 48 - All generic properties described in 49 - Documentation/devicetree/bindings/mtd/{common,nand}.txt also apply to the NAND 50 - device node, and NAND partitions should be defined under the NAND node as 51 - described in Documentation/devicetree/bindings/mtd/partition.txt. 48 + All generic properties are described in the generic yaml files under 49 + Documentation/devicetree/bindings/mtd/. 52 50 53 51 * ECC engine (PMECC) bindings: 54 52
+52 -44
Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
··· 86 86 minItems: 1 87 87 items: 88 88 - description: NAND CTLRDY interrupt 89 - - description: FLASH_DMA_DONE if flash DMA is available 90 - - description: FLASH_EDU_DONE if EDU is available 89 + - description: FLASH_DMA_DONE (if flash DMA is available) or FLASH_EDU_DONE (if EDU is available) 91 90 92 91 interrupt-names: 93 92 minItems: 1 94 93 items: 95 94 - const: nand_ctlrdy 96 - - const: flash_dma_done 97 - - const: flash_edu_done 95 + - enum: 96 + - flash_dma_done 97 + - flash_edu_done 98 98 99 99 clocks: 100 100 maxItems: 1 ··· 173 173 - const: nand 174 174 - const: iproc-idm 175 175 - const: iproc-ext 176 + - if: 177 + properties: 178 + interrupts: 179 + minItems: 2 180 + then: 181 + required: 182 + - interrupt-names 176 183 177 184 unevaluatedProperties: false 178 185 ··· 191 184 examples: 192 185 - | 193 186 nand-controller@f0442800 { 194 - compatible = "brcm,brcmnand-v7.0", "brcm,brcmnand"; 195 - reg = <0xf0442800 0x600>, 196 - <0xf0443000 0x100>; 197 - reg-names = "nand", "flash-dma"; 198 - interrupt-parent = <&hif_intr2_intc>; 199 - interrupts = <24>, <4>; 187 + compatible = "brcm,brcmnand-v7.0", "brcm,brcmnand"; 188 + reg = <0xf0442800 0x600>, 189 + <0xf0443000 0x100>; 190 + reg-names = "nand", "flash-dma"; 191 + interrupt-parent = <&hif_intr2_intc>; 192 + interrupts = <24>, <4>; 193 + interrupt-names = "nand_ctlrdy", "flash_dma_done"; 194 + 195 + #address-cells = <1>; 196 + #size-cells = <0>; 197 + 198 + nand@1 { 199 + compatible = "brcm,nandcs"; 200 + reg = <1>; // Chip select 1 201 + nand-on-flash-bbt; 202 + nand-ecc-strength = <12>; 203 + nand-ecc-step-size = <512>; 200 204 201 205 #address-cells = <1>; 202 - #size-cells = <0>; 203 - 204 - nand@1 { 205 - compatible = "brcm,nandcs"; 206 - reg = <1>; // Chip select 1 207 - nand-on-flash-bbt; 208 - nand-ecc-strength = <12>; 209 - nand-ecc-step-size = <512>; 210 - 211 - #address-cells = <1>; 212 - #size-cells = <1>; 213 - }; 206 + #size-cells = <1>; 207 + }; 214 208 }; 215 209 - | 216 210 nand-controller@10000200 { 217 - compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", 218 - "brcm,brcmnand-v4.0", "brcm,brcmnand"; 219 - reg = <0x10000200 0x180>, 220 - <0x100000b0 0x10>, 221 - <0x10000600 0x200>; 222 - reg-names = "nand", "nand-int-base", "nand-cache"; 223 - interrupt-parent = <&periph_intc>; 224 - interrupts = <50>; 225 - clocks = <&periph_clk 20>; 226 - clock-names = "nand"; 211 + compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", 212 + "brcm,brcmnand-v4.0", "brcm,brcmnand"; 213 + reg = <0x10000200 0x180>, 214 + <0x100000b0 0x10>, 215 + <0x10000600 0x200>; 216 + reg-names = "nand", "nand-int-base", "nand-cache"; 217 + interrupt-parent = <&periph_intc>; 218 + interrupts = <50>; 219 + clocks = <&periph_clk 20>; 220 + clock-names = "nand"; 221 + 222 + #address-cells = <1>; 223 + #size-cells = <0>; 224 + 225 + nand@0 { 226 + compatible = "brcm,nandcs"; 227 + reg = <0>; 228 + nand-on-flash-bbt; 229 + nand-ecc-strength = <1>; 230 + nand-ecc-step-size = <512>; 227 231 228 232 #address-cells = <1>; 229 - #size-cells = <0>; 230 - 231 - nand@0 { 232 - compatible = "brcm,nandcs"; 233 - reg = <0>; 234 - nand-on-flash-bbt; 235 - nand-ecc-strength = <1>; 236 - nand-ecc-step-size = <512>; 237 - 238 - #address-cells = <1>; 239 - #size-cells = <1>; 240 - }; 233 + #size-cells = <1>; 234 + }; 241 235 };
+1 -1
Documentation/devicetree/bindings/mtd/denali,nand.yaml
··· 145 145 #size-cells = <0>; 146 146 147 147 nand@0 { 148 - reg = <0>; 148 + reg = <0>; 149 149 }; 150 150 };
+62 -62
Documentation/devicetree/bindings/mtd/ingenic,nand.yaml
··· 32 32 33 33 partitions: 34 34 type: object 35 + deprecated: true 35 36 description: 36 37 Node containing description of fixed partitions. 37 - See Documentation/devicetree/bindings/mtd/partition.txt 38 38 39 39 patternProperties: 40 40 "^nand@[a-f0-9]$": ··· 58 58 - | 59 59 #include <dt-bindings/clock/ingenic,jz4780-cgu.h> 60 60 memory-controller@13410000 { 61 - compatible = "ingenic,jz4780-nemc"; 62 - reg = <0x13410000 0x10000>; 63 - #address-cells = <2>; 64 - #size-cells = <1>; 65 - ranges = <1 0 0x1b000000 0x1000000>, 66 - <2 0 0x1a000000 0x1000000>, 67 - <3 0 0x19000000 0x1000000>, 68 - <4 0 0x18000000 0x1000000>, 69 - <5 0 0x17000000 0x1000000>, 70 - <6 0 0x16000000 0x1000000>; 61 + compatible = "ingenic,jz4780-nemc"; 62 + reg = <0x13410000 0x10000>; 63 + #address-cells = <2>; 64 + #size-cells = <1>; 65 + ranges = <1 0 0x1b000000 0x1000000>, 66 + <2 0 0x1a000000 0x1000000>, 67 + <3 0 0x19000000 0x1000000>, 68 + <4 0 0x18000000 0x1000000>, 69 + <5 0 0x17000000 0x1000000>, 70 + <6 0 0x16000000 0x1000000>; 71 71 72 - clocks = <&cgu JZ4780_CLK_NEMC>; 72 + clocks = <&cgu JZ4780_CLK_NEMC>; 73 73 74 - nand-controller@1 { 75 - compatible = "ingenic,jz4780-nand"; 76 - reg = <1 0 0x1000000>; 74 + nand-controller@1 { 75 + compatible = "ingenic,jz4780-nand"; 76 + reg = <1 0 0x1000000>; 77 77 78 - #address-cells = <1>; 79 - #size-cells = <0>; 78 + #address-cells = <1>; 79 + #size-cells = <0>; 80 80 81 - ecc-engine = <&bch>; 81 + ecc-engine = <&bch>; 82 82 83 - ingenic,nemc-tAS = <10>; 84 - ingenic,nemc-tAH = <5>; 85 - ingenic,nemc-tBP = <10>; 86 - ingenic,nemc-tAW = <15>; 87 - ingenic,nemc-tSTRV = <100>; 83 + ingenic,nemc-tAS = <10>; 84 + ingenic,nemc-tAH = <5>; 85 + ingenic,nemc-tBP = <10>; 86 + ingenic,nemc-tAW = <15>; 87 + ingenic,nemc-tSTRV = <100>; 88 88 89 - pinctrl-names = "default"; 90 - pinctrl-0 = <&pins_nemc>; 89 + pinctrl-names = "default"; 90 + pinctrl-0 = <&pins_nemc>; 91 91 92 - nand@1 { 93 - reg = <1>; 92 + nand@1 { 93 + reg = <1>; 94 94 95 - nand-ecc-step-size = <1024>; 96 - nand-ecc-strength = <24>; 97 - nand-ecc-mode = "hw"; 98 - nand-on-flash-bbt; 95 + nand-ecc-step-size = <1024>; 96 + nand-ecc-strength = <24>; 97 + nand-ecc-mode = "hw"; 98 + nand-on-flash-bbt; 99 99 100 - pinctrl-names = "default"; 101 - pinctrl-0 = <&pins_nemc_cs1>; 100 + pinctrl-names = "default"; 101 + pinctrl-0 = <&pins_nemc_cs1>; 102 102 103 - partitions { 104 - compatible = "fixed-partitions"; 105 - #address-cells = <2>; 106 - #size-cells = <2>; 103 + partitions { 104 + compatible = "fixed-partitions"; 105 + #address-cells = <2>; 106 + #size-cells = <2>; 107 107 108 - partition@0 { 109 - label = "u-boot-spl"; 110 - reg = <0x0 0x0 0x0 0x800000>; 108 + partition@0 { 109 + label = "u-boot-spl"; 110 + reg = <0x0 0x0 0x0 0x800000>; 111 + }; 112 + 113 + partition@800000 { 114 + label = "u-boot"; 115 + reg = <0x0 0x800000 0x0 0x200000>; 116 + }; 117 + 118 + partition@a00000 { 119 + label = "u-boot-env"; 120 + reg = <0x0 0xa00000 0x0 0x200000>; 121 + }; 122 + 123 + partition@c00000 { 124 + label = "boot"; 125 + reg = <0x0 0xc00000 0x0 0x4000000>; 126 + }; 127 + 128 + partition@4c00000 { 129 + label = "system"; 130 + reg = <0x0 0x4c00000 0x1 0xfb400000>; 131 + }; 132 + }; 111 133 }; 112 - 113 - partition@800000 { 114 - label = "u-boot"; 115 - reg = <0x0 0x800000 0x0 0x200000>; 116 - }; 117 - 118 - partition@a00000 { 119 - label = "u-boot-env"; 120 - reg = <0x0 0xa00000 0x0 0x200000>; 121 - }; 122 - 123 - partition@c00000 { 124 - label = "boot"; 125 - reg = <0x0 0xc00000 0x0 0x4000000>; 126 - }; 127 - 128 - partition@4c00000 { 129 - label = "system"; 130 - reg = <0x0 0x4c00000 0x1 0xfb400000>; 131 - }; 132 - }; 133 134 }; 134 - }; 135 135 };
+20 -28
Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml
··· 39 39 - const: tx 40 40 - const: rx 41 41 42 - "#address-cells": 43 - const: 1 44 - 45 - "#size-cells": 46 - const: 0 47 - 48 42 patternProperties: 49 - "^nand@[a-f0-9]+$": 43 + "^nand@[a-f0-9]$": 50 44 type: object 51 45 properties: 52 46 reg: ··· 61 67 - clocks 62 68 - dmas 63 69 - dma-names 64 - - "#address-cells" 65 - - "#size-cells" 66 70 67 - additionalProperties: false 71 + unevaluatedProperties: false 68 72 69 73 examples: 70 74 - | 71 75 nand-controller@e0f00000 { 72 - compatible = "intel,lgm-ebunand"; 73 - reg = <0xe0f00000 0x100>, 74 - <0xe1000000 0x300>, 75 - <0xe1400000 0x8000>, 76 - <0xe1c00000 0x1000>, 77 - <0x17400000 0x4>, 78 - <0x17c00000 0x4>; 79 - reg-names = "ebunand", "hsnand", "nand_cs0", "nand_cs1", 80 - "addr_sel0", "addr_sel1"; 81 - clocks = <&cgu0 125>; 82 - dmas = <&dma0 8>, <&dma0 9>; 83 - dma-names = "tx", "rx"; 84 - #address-cells = <1>; 85 - #size-cells = <0>; 76 + compatible = "intel,lgm-ebunand"; 77 + reg = <0xe0f00000 0x100>, 78 + <0xe1000000 0x300>, 79 + <0xe1400000 0x8000>, 80 + <0xe1c00000 0x1000>, 81 + <0x17400000 0x4>, 82 + <0x17c00000 0x4>; 83 + reg-names = "ebunand", "hsnand", "nand_cs0", "nand_cs1", 84 + "addr_sel0", "addr_sel1"; 85 + clocks = <&cgu0 125>; 86 + dmas = <&dma0 8>, <&dma0 9>; 87 + dma-names = "tx", "rx"; 88 + #address-cells = <1>; 89 + #size-cells = <0>; 86 90 87 - nand@0 { 88 - reg = <0>; 89 - nand-ecc-mode = "hw"; 90 - }; 91 + nand@0 { 92 + reg = <0>; 93 + nand-ecc-mode = "hw"; 94 + }; 91 95 }; 92 96 93 97 ...
+7 -13
Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
··· 70 70 be used on such systems, to denote the absence of a reliable reset 71 71 mechanism. 72 72 73 - partitions: 74 - type: object 75 - 76 - '#address-cells': true 77 - '#size-cells': true 78 - 79 - patternProperties: 80 - # Note: use 'partitions' node for new users 81 - '^partition@': 82 - type: object 83 - 84 - "^otp(-[0-9]+)?$": 85 - type: object 73 + reset-gpios: 74 + description: 75 + A GPIO line connected to the RESET (active low) signal of the device. 76 + If "broken-flash-reset" is present then having this property does not 77 + make any difference. 86 78 87 79 unevaluatedProperties: false 88 80 89 81 examples: 90 82 - | 83 + #include <dt-bindings/gpio/gpio.h> 91 84 spi { 92 85 #address-cells = <1>; 93 86 #size-cells = <0>; ··· 90 97 reg = <0>; 91 98 spi-max-frequency = <40000000>; 92 99 m25p,fast-read; 100 + reset-gpios = <&gpio 12 GPIO_ACTIVE_LOW>; 93 101 }; 94 102 }; 95 103 ...
+1 -1
Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt
··· 19 19 - nxp,wr_low: WR_LOW 20 20 21 21 Optional subnodes: 22 - - Partitions, see Documentation/devicetree/bindings/mtd/partition.txt 22 + - Partitions, see Documentation/devicetree/bindings/mtd/mtd.yaml 23 23 24 24 Example: 25 25
+1 -1
Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt
··· 20 20 - nxp,rsetup: Read setup time (R_SETUP) 21 21 22 22 Optional subnodes: 23 - - Partitions, see Documentation/devicetree/bindings/mtd/partition.txt 23 + - Partitions, see Documentation/devicetree/bindings/mtd/mtd.yaml 24 24 25 25 Example: 26 26
+7 -7
Documentation/devicetree/bindings/mtd/microchip,mchp48l640.yaml
··· 34 34 examples: 35 35 - | 36 36 spi { 37 - #address-cells = <1>; 38 - #size-cells = <0>; 37 + #address-cells = <1>; 38 + #size-cells = <0>; 39 39 40 - eeram@0 { 41 - compatible = "microchip,48l640"; 42 - reg = <0>; 43 - spi-max-frequency = <20000000>; 44 - }; 40 + eeram@0 { 41 + compatible = "microchip,48l640"; 42 + reg = <0>; 43 + spi-max-frequency = <20000000>; 44 + }; 45 45 }; 46 46 ...
+3 -4
Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
··· 13 13 Flash chips (Memory Technology Devices) are often used for solid state 14 14 file systems on embedded devices. 15 15 16 + allOf: 17 + - $ref: "mtd.yaml#" 18 + 16 19 properties: 17 20 compatible: 18 21 oneOf: ··· 123 120 124 121 big-endian: true 125 122 little-endian: true 126 - 127 - patternProperties: 128 - '@[0-9a-f]+$': 129 - $ref: partitions/partition.yaml 130 123 131 124 required: 132 125 - compatible
+22 -2
Documentation/devicetree/bindings/mtd/mtd.yaml
··· 12 12 13 13 properties: 14 14 $nodename: 15 - pattern: "^flash(@.*)?$" 15 + pattern: "^(flash|.*sram)(@.*)?$" 16 16 17 17 label: 18 18 description: ··· 21 21 based name) in order to ease flash device identification and/or 22 22 describe what they are used for. 23 23 24 + '#address-cells': 25 + deprecated: true 26 + 27 + '#size-cells': 28 + deprecated: true 29 + 30 + partitions: 31 + $ref: /schemas/mtd/partitions/partitions.yaml 32 + 33 + required: 34 + - compatible 35 + 24 36 patternProperties: 37 + "@[0-9a-f]+$": 38 + $ref: partitions/partition.yaml 39 + deprecated: true 40 + 41 + "^partition@[0-9a-f]+": 42 + $ref: partitions/partition.yaml 43 + deprecated: true 44 + 25 45 "^otp(-[0-9]+)?$": 26 - type: object 27 46 $ref: ../nvmem/nvmem.yaml# 28 47 29 48 description: | ··· 59 40 required: 60 41 - compatible 61 42 43 + # This is a generic file other binding inherit from 62 44 additionalProperties: true 63 45 64 46 examples:
+1 -1
Documentation/devicetree/bindings/mtd/mtk-nand.txt
··· 131 131 }; 132 132 133 133 NAND chip optional subnodes: 134 - - Partitions, see Documentation/devicetree/bindings/mtd/partition.txt 134 + - Partitions, see Documentation/devicetree/bindings/mtd/mtd.yaml 135 135 136 136 Example: 137 137 nand@0 {
+4
Documentation/devicetree/bindings/mtd/nand-chip.yaml
··· 9 9 maintainers: 10 10 - Miquel Raynal <miquel.raynal@bootlin.com> 11 11 12 + allOf: 13 + - $ref: "mtd.yaml#" 14 + 12 15 description: | 13 16 This file covers the generic description of a NAND chip. It implies that the 14 17 bus interface should not be taken into account: both raw NAND devices and ··· 70 67 required: 71 68 - reg 72 69 70 + # This file can be referenced by more specific devices (like spi-nands) 73 71 additionalProperties: true
+1 -1
Documentation/devicetree/bindings/mtd/nand-controller.yaml
··· 51 51 52 52 patternProperties: 53 53 "^nand@[a-f0-9]$": 54 - type: object 55 54 $ref: "nand-chip.yaml#" 56 55 57 56 properties: ··· 129 130 - "#address-cells" 130 131 - "#size-cells" 131 132 133 + # This is a generic file other binding inherit from and extend 132 134 additionalProperties: true 133 135 134 136 examples:
-33
Documentation/devicetree/bindings/mtd/partition.txt
··· 1 - Flash partitions in device tree 2 - =============================== 3 - 4 - Flash devices can be partitioned into one or more functional ranges (e.g. "boot 5 - code", "nvram", "kernel"). 6 - 7 - Different devices may be partitioned in a different ways. Some may use a fixed 8 - flash layout set at production time. Some may use on-flash table that describes 9 - the geometry and naming/purpose of each functional region. It is also possible 10 - to see these methods mixed. 11 - 12 - To assist system software in locating partitions, we allow describing which 13 - method is used for a given flash device. To describe the method there should be 14 - a subnode of the flash device that is named 'partitions'. It must have a 15 - 'compatible' property, which is used to identify the method to use. 16 - 17 - When a single partition is represented with a DT node (it depends on a used 18 - format) it may also be described using above rules ('compatible' and optionally 19 - some extra properties / subnodes). It allows describing more complex, 20 - hierarchical (multi-level) layouts and should be used if there is some 21 - significant relation between partitions or some partition internally uses 22 - another partitioning method. 23 - 24 - Available bindings are listed in the "partitions" subdirectory. 25 - 26 - 27 - Deprecated: partitions defined in flash node 28 - ============================================ 29 - 30 - For backwards compatibility partitions as direct subnodes of the flash device are 31 - supported. This use is discouraged. 32 - NOTE: also for backwards compatibility, direct subnodes that have a compatible 33 - string are not considered partitions, as they may be used for other bindings.
+2
Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml
··· 9 9 maintainers: 10 10 - Linus Walleij <linus.walleij@linaro.org> 11 11 12 + select: false 13 + 12 14 description: | 13 15 The ARM Firmware Suite is a flash partitioning system found on the 14 16 ARM reference designs: Integrator AP, Integrator CP, Versatile AB,
+2
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 + 20 22 properties: 21 23 compatible: 22 24 const: brcm,bcm4908-partitions
+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 + 38 40 properties: 39 41 compatible: 40 42 const: brcm,bcm947xx-cfe-partitions
+12 -18
Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
··· 31 31 32 32 patternProperties: 33 33 "@[0-9a-f]+$": 34 - allOf: 35 - - $ref: "partition.yaml#" 36 - - if: 37 - properties: 38 - compatible: 39 - contains: 40 - const: sercomm,sc-partitions 41 - then: 42 - properties: 43 - sercomm,scpart-id: 44 - description: Partition id in Sercomm partition map. Mtd 45 - parser uses this id to find a record in the partition map 46 - containing offset and size of the current partition. The 47 - values from partition map overrides partition offset and 48 - size defined in reg property of the dts. Frequently these 49 - values are the same, but may differ if device has bad 50 - eraseblocks on a flash. 51 - $ref: /schemas/types.yaml#/definitions/uint32 34 + $ref: partition.yaml# 35 + 36 + properties: 37 + sercomm,scpart-id: 38 + description: Partition id in Sercomm partition map. Mtd parser 39 + uses this id to find a record in the partition map containing 40 + offset and size of the current partition. The values from 41 + partition map overrides partition offset and size defined in 42 + reg property of the dts. Frequently these values are the same, 43 + but may differ if device has bad eraseblocks on a flash. 44 + $ref: /schemas/types.yaml#/definitions/uint32 52 45 53 46 required: 54 47 - "#address-cells" ··· 77 84 partition@0 { 78 85 label = "filesystem"; 79 86 reg = <0x00000000 0x1 0x00000000>; 87 + linux,rootfs; 80 88 }; 81 89 }; 82 90
+2
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 + 21 23 properties: 22 24 compatible: 23 25 const: linksys,ns-partitions
+2 -2
Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml
··· 17 17 - Ansuel Smith <ansuelsmth@gmail.com> 18 18 19 19 allOf: 20 + - $ref: /schemas/mtd/partitions/partition.yaml# 20 21 - $ref: /schemas/nvmem/nvmem.yaml# 21 22 22 23 properties: ··· 27 26 required: 28 27 - compatible 29 28 30 - additionalProperties: true 29 + unevaluatedProperties: false 31 30 32 31 examples: 33 32 - | ··· 85 84 compatible = "nvmem-cells"; 86 85 label = "calibration"; 87 86 reg = <0xf00000 0x100000>; 88 - ranges = <0 0xf00000 0x100000>; 89 87 #address-cells = <1>; 90 88 #size-cells = <1>; 91 89
+5
Documentation/devicetree/bindings/mtd/partitions/partition.yaml
··· 52 52 immune to paired-pages corruptions 53 53 type: boolean 54 54 55 + linux,rootfs: 56 + description: Marks partition that contains root filesystem to mount and boot 57 + user space from 58 + 55 59 if: 56 60 not: 57 61 required: [ reg ] ··· 64 60 $nodename: 65 61 pattern: '^partition-.*$' 66 62 63 + # This is a generic file other binding inherit from and extend 67 64 additionalProperties: true
+41
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 + 25 + properties: 26 + compatible: true 27 + 28 + '#address-cells': 29 + enum: [1, 2] 30 + 31 + '#size-cells': 32 + enum: [1, 2] 33 + 34 + patternProperties: 35 + "partition(-.+|@[0-9a-f]+)": 36 + $ref: partition.yaml 37 + 38 + required: 39 + - compatible 40 + 41 + unevaluatedProperties: false
+17 -15
Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml
··· 15 15 varies between partition table revisions. V3 supports maximum 16 partitions 16 16 and V4 supports 48 partitions. 17 17 18 + select: false 19 + 18 20 properties: 19 21 compatible: 20 22 const: qcom,smem-part 21 23 22 24 patternProperties: 23 25 "^partition-[0-9a-z]+$": 24 - $ref: partition.yaml# 26 + $ref: nvmem-cells.yaml 25 27 26 28 required: 27 29 - compatible ··· 41 39 - | 42 40 /* Example declaring dynamic partition */ 43 41 flash { 44 - partitions { 45 - compatible = "qcom,smem-part"; 42 + partitions { 43 + compatible = "qcom,smem-part"; 46 44 47 - partition-art { 48 - compatible = "nvmem-cells"; 49 - #address-cells = <1>; 50 - #size-cells = <1>; 51 - label = "0:art"; 45 + partition-art { 46 + compatible = "nvmem-cells"; 47 + #address-cells = <1>; 48 + #size-cells = <1>; 49 + label = "0:art"; 52 50 53 - macaddr_art_0: macaddr@0 { 54 - reg = <0x0 0x6>; 55 - }; 51 + macaddr_art_0: macaddr@0 { 52 + reg = <0x0 0x6>; 53 + }; 56 54 57 - macaddr_art_6: macaddr@6 { 58 - reg = <0x6 0x6>; 59 - }; 55 + macaddr_art_6: macaddr@6 { 56 + reg = <0x6 0x6>; 57 + }; 58 + }; 60 59 }; 61 - }; 62 60 };
+6
Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml
··· 16 16 maintainers: 17 17 - Linus Walleij <linus.walleij@linaro.org> 18 18 19 + select: false 20 + 19 21 properties: 20 22 compatible: 21 23 const: redboot-fis ··· 27 25 description: a index to the eraseblock containing the FIS directory on this 28 26 device. On a flash memory with 32KB eraseblocks, 0 means the first 29 27 eraseblock at 0x00000000, 1 means the second eraseblock at 0x00008000 and so on. 28 + 29 + '#address-cells': false 30 + 31 + '#size-cells': false 30 32 31 33 required: 32 34 - compatible
+57
Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-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/tplink,safeloader-partitions.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: TP-Link SafeLoader partitions 8 + 9 + description: | 10 + TP-Link home routers store various data on flash (e.g. bootloader, 11 + flash layout, firmware, product info, configuration, calibration 12 + data). That requires flash partitioning. 13 + 14 + Flash space layout of TP-Link devices is stored on flash itself using 15 + a custom ASCII-based format. That format was first found in TP-Link 16 + devices with a custom SafeLoader bootloader. Later it was adapted to 17 + CFE and U-Boot bootloaders. 18 + 19 + Partitions specified in partitions table cover whole flash space. Some 20 + contain static data that shouldn't get modified (device's MAC or WiFi 21 + calibration data). Others are semi-static (like kernel). Finally some 22 + partitions contain fully changeable content (like rootfs). 23 + 24 + This binding describes partitioning method and defines offset of ASCII 25 + based partitions table. That offset is picked at manufacturing process 26 + and doesn't change. 27 + 28 + maintainers: 29 + - Rafał Miłecki <rafal@milecki.pl> 30 + 31 + properties: 32 + compatible: 33 + const: tplink,safeloader-partitions 34 + 35 + partitions-table-offset: 36 + description: Flash offset of partitions table 37 + $ref: /schemas/types.yaml#/definitions/uint32 38 + 39 + patternProperties: 40 + "^partition-.*$": 41 + $ref: partition.yaml# 42 + 43 + required: 44 + - partitions-table-offset 45 + 46 + additionalProperties: false 47 + 48 + examples: 49 + - | 50 + partitions { 51 + compatible = "tplink,safeloader-partitions"; 52 + partitions-table-offset = <0x100000>; 53 + 54 + partition-file-system { 55 + linux,rootfs; 56 + }; 57 + };
+57 -60
Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
··· 31 31 - const: core 32 32 - const: aon 33 33 34 - "#address-cells": true 35 - "#size-cells": true 36 - 37 34 patternProperties: 38 35 "^nand@[a-f0-9]$": 39 36 type: object ··· 136 139 - | 137 140 #include <dt-bindings/clock/qcom,gcc-ipq806x.h> 138 141 nand-controller@1ac00000 { 139 - compatible = "qcom,ipq806x-nand"; 140 - reg = <0x1ac00000 0x800>; 142 + compatible = "qcom,ipq806x-nand"; 143 + reg = <0x1ac00000 0x800>; 141 144 142 - clocks = <&gcc EBI2_CLK>, 143 - <&gcc EBI2_AON_CLK>; 144 - clock-names = "core", "aon"; 145 + clocks = <&gcc EBI2_CLK>, 146 + <&gcc EBI2_AON_CLK>; 147 + clock-names = "core", "aon"; 145 148 146 - dmas = <&adm_dma 3>; 147 - dma-names = "rxtx"; 148 - qcom,cmd-crci = <15>; 149 - qcom,data-crci = <3>; 149 + dmas = <&adm_dma 3>; 150 + dma-names = "rxtx"; 151 + qcom,cmd-crci = <15>; 152 + qcom,data-crci = <3>; 150 153 151 - #address-cells = <1>; 152 - #size-cells = <0>; 154 + #address-cells = <1>; 155 + #size-cells = <0>; 153 156 154 - nand@0 { 155 - reg = <0>; 157 + nand@0 { 158 + reg = <0>; 156 159 157 - nand-ecc-strength = <4>; 158 - nand-bus-width = <8>; 160 + nand-ecc-strength = <4>; 161 + nand-bus-width = <8>; 159 162 160 - qcom,boot-partitions = <0x0 0x58a0000>; 163 + qcom,boot-partitions = <0x0 0x58a0000>; 161 164 162 - partitions { 163 - compatible = "fixed-partitions"; 164 - #address-cells = <1>; 165 - #size-cells = <1>; 165 + partitions { 166 + compatible = "fixed-partitions"; 167 + #address-cells = <1>; 168 + #size-cells = <1>; 166 169 167 - partition@0 { 168 - label = "boot-nand"; 169 - reg = <0 0x58a0000>; 170 - }; 170 + partition@0 { 171 + label = "boot-nand"; 172 + reg = <0 0x58a0000>; 173 + }; 171 174 172 - partition@58a0000 { 173 - label = "fs-nand"; 174 - reg = <0x58a0000 0x4000000>; 175 - }; 175 + partition@58a0000 { 176 + label = "fs-nand"; 177 + reg = <0x58a0000 0x4000000>; 178 + }; 179 + }; 176 180 }; 177 - }; 178 181 }; 179 182 180 183 #include <dt-bindings/clock/qcom,gcc-ipq4019.h> 181 184 nand-controller@79b0000 { 182 - compatible = "qcom,ipq4019-nand"; 183 - reg = <0x79b0000 0x1000>; 185 + compatible = "qcom,ipq4019-nand"; 186 + reg = <0x79b0000 0x1000>; 184 187 185 - clocks = <&gcc GCC_QPIC_CLK>, 186 - <&gcc GCC_QPIC_AHB_CLK>; 187 - clock-names = "core", "aon"; 188 + clocks = <&gcc GCC_QPIC_CLK>, 189 + <&gcc GCC_QPIC_AHB_CLK>; 190 + clock-names = "core", "aon"; 188 191 189 - dmas = <&qpicbam 0>, 190 - <&qpicbam 1>, 191 - <&qpicbam 2>; 192 - dma-names = "tx", "rx", "cmd"; 192 + dmas = <&qpicbam 0>, 193 + <&qpicbam 1>, 194 + <&qpicbam 2>; 195 + dma-names = "tx", "rx", "cmd"; 193 196 194 - #address-cells = <1>; 195 - #size-cells = <0>; 197 + #address-cells = <1>; 198 + #size-cells = <0>; 196 199 197 - nand@0 { 198 - reg = <0>; 199 - nand-ecc-strength = <4>; 200 - nand-bus-width = <8>; 200 + nand@0 { 201 + reg = <0>; 202 + nand-ecc-strength = <4>; 203 + nand-bus-width = <8>; 201 204 202 - partitions { 203 - compatible = "fixed-partitions"; 204 - #address-cells = <1>; 205 - #size-cells = <1>; 205 + partitions { 206 + compatible = "fixed-partitions"; 207 + #address-cells = <1>; 208 + #size-cells = <1>; 206 209 207 - partition@0 { 208 - label = "boot-nand"; 209 - reg = <0 0x58a0000>; 210 - }; 210 + partition@0 { 211 + label = "boot-nand"; 212 + reg = <0 0x58a0000>; 213 + }; 211 214 212 - partition@58a0000 { 213 - label = "fs-nand"; 214 - reg = <0x58a0000 0x4000000>; 215 - }; 215 + partition@58a0000 { 216 + label = "fs-nand"; 217 + reg = <0x58a0000 0x4000000>; 218 + }; 219 + }; 216 220 }; 217 - }; 218 221 }; 219 222 220 223 ...
+3 -1
Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml
··· 19 19 - const: rockchip,rk2928-nfc 20 20 - const: rockchip,rv1108-nfc 21 21 - items: 22 - - const: rockchip,rk3036-nfc 22 + - enum: 23 + - rockchip,rk3036-nfc 24 + - rockchip,rk3128-nfc 23 25 - const: rockchip,rk2928-nfc 24 26 - items: 25 27 - const: rockchip,rk3308-nfc
+24 -23
Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
··· 101 101 #include <dt-bindings/interrupt-controller/arm-gic.h> 102 102 #include <dt-bindings/clock/stm32mp1-clks.h> 103 103 #include <dt-bindings/reset/stm32mp1-resets.h> 104 - nand-controller@58002000 { 105 - compatible = "st,stm32mp15-fmc2"; 106 - reg = <0x58002000 0x1000>, 107 - <0x80000000 0x1000>, 108 - <0x88010000 0x1000>, 109 - <0x88020000 0x1000>, 110 - <0x81000000 0x1000>, 111 - <0x89010000 0x1000>, 112 - <0x89020000 0x1000>; 113 - interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; 114 - dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, 115 - <&mdma1 20 0x2 0x12000a08 0x0 0x0>, 116 - <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; 117 - dma-names = "tx", "rx", "ecc"; 118 - clocks = <&rcc FMC_K>; 119 - resets = <&rcc FMC_R>; 120 - #address-cells = <1>; 121 - #size-cells = <0>; 122 104 123 - nand@0 { 124 - reg = <0>; 125 - nand-on-flash-bbt; 105 + nand-controller@58002000 { 106 + compatible = "st,stm32mp15-fmc2"; 107 + reg = <0x58002000 0x1000>, 108 + <0x80000000 0x1000>, 109 + <0x88010000 0x1000>, 110 + <0x88020000 0x1000>, 111 + <0x81000000 0x1000>, 112 + <0x89010000 0x1000>, 113 + <0x89020000 0x1000>; 114 + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; 115 + dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, 116 + <&mdma1 20 0x2 0x12000a08 0x0 0x0>, 117 + <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; 118 + dma-names = "tx", "rx", "ecc"; 119 + clocks = <&rcc FMC_K>; 120 + resets = <&rcc FMC_R>; 126 121 #address-cells = <1>; 127 - #size-cells = <1>; 128 - }; 122 + #size-cells = <0>; 123 + 124 + nand@0 { 125 + reg = <0>; 126 + nand-on-flash-bbt; 127 + #address-cells = <1>; 128 + #size-cells = <1>; 129 + }; 129 130 }; 130 131 131 132 ...
+18 -18
Documentation/devicetree/bindings/mtd/ti,am654-hbmc.yaml
··· 44 44 examples: 45 45 - | 46 46 bus { 47 - #address-cells = <2>; 48 - #size-cells = <2>; 49 - 50 - hbmc: memory-controller@47034000 { 51 - compatible = "ti,am654-hbmc"; 52 - reg = <0x0 0x47034000 0x0 0x100>, 53 - <0x5 0x00000000 0x1 0x0000000>; 54 - ranges = <0x0 0x0 0x5 0x00000000 0x4000000>, /* CS0 - 64MB */ 55 - <0x1 0x0 0x5 0x04000000 0x4000000>; /* CS1 - 64MB */ 56 - clocks = <&k3_clks 102 0>; 57 47 #address-cells = <2>; 58 - #size-cells = <1>; 59 - power-domains = <&k3_pds 55>; 60 - mux-controls = <&hbmc_mux 0>; 48 + #size-cells = <2>; 61 49 62 - flash@0,0 { 63 - compatible = "cypress,hyperflash", "cfi-flash"; 64 - reg = <0x0 0x0 0x4000000>; 65 - #address-cells = <1>; 50 + hbmc: memory-controller@47034000 { 51 + compatible = "ti,am654-hbmc"; 52 + reg = <0x0 0x47034000 0x0 0x100>, 53 + <0x5 0x00000000 0x1 0x0000000>; 54 + ranges = <0x0 0x0 0x5 0x00000000 0x4000000>, /* CS0 - 64MB */ 55 + <0x1 0x0 0x5 0x04000000 0x4000000>; /* CS1 - 64MB */ 56 + clocks = <&k3_clks 102 0>; 57 + #address-cells = <2>; 66 58 #size-cells = <1>; 59 + power-domains = <&k3_pds 55>; 60 + mux-controls = <&hbmc_mux 0>; 61 + 62 + flash@0,0 { 63 + compatible = "cypress,hyperflash", "cfi-flash"; 64 + reg = <0x0 0x0 0x4000000>; 65 + #address-cells = <1>; 66 + #size-cells = <1>; 67 + }; 67 68 }; 68 - }; 69 69 };
+3
Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
··· 15 15 as child nodes of the GPMC controller. 16 16 17 17 properties: 18 + $nodename: 19 + pattern: "^onenand@[0-9],[0,9]$" 20 + 18 21 compatible: 19 22 const: ti,omap2-onenand 20 23
+1 -1
MAINTAINERS
··· 13464 13464 M: Liang Yang <liang.yang@amlogic.com> 13465 13465 L: linux-mtd@lists.infradead.org 13466 13466 S: Maintained 13467 - F: Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt 13467 + F: Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml 13468 13468 F: drivers/mtd/nand/raw/meson_* 13469 13469 13470 13470 MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS
-8
drivers/mtd/devices/Kconfig
··· 136 136 doesn't have access to, memory beyond the mem=xxx limit, nvram, 137 137 memory on the video card, etc... 138 138 139 - config MTD_LART 140 - tristate "28F160xx flash driver for LART" 141 - depends on SA1100_LART 142 - help 143 - This enables the flash driver for LART. Please note that you do 144 - not need any mapping/chip driver for LART. This one does it all 145 - for you, so go disable all of those if you enabled some of them (: 146 - 147 139 config MTD_MTDRAM 148 140 tristate "Test driver using RAM" 149 141 help
-1
drivers/mtd/devices/Makefile
··· 9 9 obj-$(CONFIG_MTD_PMC551) += pmc551.o 10 10 obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o 11 11 obj-$(CONFIG_MTD_MTDRAM) += mtdram.o 12 - obj-$(CONFIG_MTD_LART) += lart.o 13 12 obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 14 13 obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o 15 14 obj-$(CONFIG_MTD_MCHP23K256) += mchp23k256.o
-682
drivers/mtd/devices/lart.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - 3 - /* 4 - * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. 5 - * 6 - * Author: Abraham vd Merwe <abraham@2d3d.co.za> 7 - * 8 - * Copyright (c) 2001, 2d3D, Inc. 9 - * 10 - * References: 11 - * 12 - * [1] 3 Volt Fast Boot Block Flash Memory" Intel Datasheet 13 - * - Order Number: 290644-005 14 - * - January 2000 15 - * 16 - * [2] MTD internal API documentation 17 - * - http://www.linux-mtd.infradead.org/ 18 - * 19 - * Limitations: 20 - * 21 - * Even though this driver is written for 3 Volt Fast Boot 22 - * Block Flash Memory, it is rather specific to LART. With 23 - * Minor modifications, notably the without data/address line 24 - * mangling and different bus settings, etc. it should be 25 - * trivial to adapt to other platforms. 26 - * 27 - * If somebody would sponsor me a different board, I'll 28 - * adapt the driver (: 29 - */ 30 - 31 - /* debugging */ 32 - //#define LART_DEBUG 33 - 34 - #include <linux/kernel.h> 35 - #include <linux/module.h> 36 - #include <linux/types.h> 37 - #include <linux/init.h> 38 - #include <linux/errno.h> 39 - #include <linux/string.h> 40 - #include <linux/mtd/mtd.h> 41 - #include <linux/mtd/partitions.h> 42 - 43 - #ifndef CONFIG_SA1100_LART 44 - #error This is for LART architecture only 45 - #endif 46 - 47 - static char module_name[] = "lart"; 48 - 49 - /* 50 - * These values is specific to 28Fxxxx3 flash memory. 51 - * See section 2.3.1 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet 52 - */ 53 - #define FLASH_BLOCKSIZE_PARAM (4096 * BUSWIDTH) 54 - #define FLASH_NUMBLOCKS_16m_PARAM 8 55 - #define FLASH_NUMBLOCKS_8m_PARAM 8 56 - 57 - /* 58 - * These values is specific to 28Fxxxx3 flash memory. 59 - * See section 2.3.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet 60 - */ 61 - #define FLASH_BLOCKSIZE_MAIN (32768 * BUSWIDTH) 62 - #define FLASH_NUMBLOCKS_16m_MAIN 31 63 - #define FLASH_NUMBLOCKS_8m_MAIN 15 64 - 65 - /* 66 - * These values are specific to LART 67 - */ 68 - 69 - /* general */ 70 - #define BUSWIDTH 4 /* don't change this - a lot of the code _will_ break if you change this */ 71 - #define FLASH_OFFSET 0xe8000000 /* see linux/arch/arm/mach-sa1100/lart.c */ 72 - 73 - /* blob */ 74 - #define NUM_BLOB_BLOCKS FLASH_NUMBLOCKS_16m_PARAM 75 - #define PART_BLOB_START 0x00000000 76 - #define PART_BLOB_LEN (NUM_BLOB_BLOCKS * FLASH_BLOCKSIZE_PARAM) 77 - 78 - /* kernel */ 79 - #define NUM_KERNEL_BLOCKS 7 80 - #define PART_KERNEL_START (PART_BLOB_START + PART_BLOB_LEN) 81 - #define PART_KERNEL_LEN (NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE_MAIN) 82 - 83 - /* initial ramdisk */ 84 - #define NUM_INITRD_BLOCKS 24 85 - #define PART_INITRD_START (PART_KERNEL_START + PART_KERNEL_LEN) 86 - #define PART_INITRD_LEN (NUM_INITRD_BLOCKS * FLASH_BLOCKSIZE_MAIN) 87 - 88 - /* 89 - * See section 4.0 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet 90 - */ 91 - #define READ_ARRAY 0x00FF00FF /* Read Array/Reset */ 92 - #define READ_ID_CODES 0x00900090 /* Read Identifier Codes */ 93 - #define ERASE_SETUP 0x00200020 /* Block Erase */ 94 - #define ERASE_CONFIRM 0x00D000D0 /* Block Erase and Program Resume */ 95 - #define PGM_SETUP 0x00400040 /* Program */ 96 - #define STATUS_READ 0x00700070 /* Read Status Register */ 97 - #define STATUS_CLEAR 0x00500050 /* Clear Status Register */ 98 - #define STATUS_BUSY 0x00800080 /* Write State Machine Status (WSMS) */ 99 - #define STATUS_ERASE_ERR 0x00200020 /* Erase Status (ES) */ 100 - #define STATUS_PGM_ERR 0x00100010 /* Program Status (PS) */ 101 - 102 - /* 103 - * See section 4.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet 104 - */ 105 - #define FLASH_MANUFACTURER 0x00890089 106 - #define FLASH_DEVICE_8mbit_TOP 0x88f188f1 107 - #define FLASH_DEVICE_8mbit_BOTTOM 0x88f288f2 108 - #define FLASH_DEVICE_16mbit_TOP 0x88f388f3 109 - #define FLASH_DEVICE_16mbit_BOTTOM 0x88f488f4 110 - 111 - /***************************************************************************************************/ 112 - 113 - /* 114 - * The data line mapping on LART is as follows: 115 - * 116 - * U2 CPU | U3 CPU 117 - * ------------------- 118 - * 0 20 | 0 12 119 - * 1 22 | 1 14 120 - * 2 19 | 2 11 121 - * 3 17 | 3 9 122 - * 4 24 | 4 0 123 - * 5 26 | 5 2 124 - * 6 31 | 6 7 125 - * 7 29 | 7 5 126 - * 8 21 | 8 13 127 - * 9 23 | 9 15 128 - * 10 18 | 10 10 129 - * 11 16 | 11 8 130 - * 12 25 | 12 1 131 - * 13 27 | 13 3 132 - * 14 30 | 14 6 133 - * 15 28 | 15 4 134 - */ 135 - 136 - /* Mangle data (x) */ 137 - #define DATA_TO_FLASH(x) \ 138 - ( \ 139 - (((x) & 0x08009000) >> 11) + \ 140 - (((x) & 0x00002000) >> 10) + \ 141 - (((x) & 0x04004000) >> 8) + \ 142 - (((x) & 0x00000010) >> 4) + \ 143 - (((x) & 0x91000820) >> 3) + \ 144 - (((x) & 0x22080080) >> 2) + \ 145 - ((x) & 0x40000400) + \ 146 - (((x) & 0x00040040) << 1) + \ 147 - (((x) & 0x00110000) << 4) + \ 148 - (((x) & 0x00220100) << 5) + \ 149 - (((x) & 0x00800208) << 6) + \ 150 - (((x) & 0x00400004) << 9) + \ 151 - (((x) & 0x00000001) << 12) + \ 152 - (((x) & 0x00000002) << 13) \ 153 - ) 154 - 155 - /* Unmangle data (x) */ 156 - #define FLASH_TO_DATA(x) \ 157 - ( \ 158 - (((x) & 0x00010012) << 11) + \ 159 - (((x) & 0x00000008) << 10) + \ 160 - (((x) & 0x00040040) << 8) + \ 161 - (((x) & 0x00000001) << 4) + \ 162 - (((x) & 0x12200104) << 3) + \ 163 - (((x) & 0x08820020) << 2) + \ 164 - ((x) & 0x40000400) + \ 165 - (((x) & 0x00080080) >> 1) + \ 166 - (((x) & 0x01100000) >> 4) + \ 167 - (((x) & 0x04402000) >> 5) + \ 168 - (((x) & 0x20008200) >> 6) + \ 169 - (((x) & 0x80000800) >> 9) + \ 170 - (((x) & 0x00001000) >> 12) + \ 171 - (((x) & 0x00004000) >> 13) \ 172 - ) 173 - 174 - /* 175 - * The address line mapping on LART is as follows: 176 - * 177 - * U3 CPU | U2 CPU 178 - * ------------------- 179 - * 0 2 | 0 2 180 - * 1 3 | 1 3 181 - * 2 9 | 2 9 182 - * 3 13 | 3 8 183 - * 4 8 | 4 7 184 - * 5 12 | 5 6 185 - * 6 11 | 6 5 186 - * 7 10 | 7 4 187 - * 8 4 | 8 10 188 - * 9 5 | 9 11 189 - * 10 6 | 10 12 190 - * 11 7 | 11 13 191 - * 192 - * BOOT BLOCK BOUNDARY 193 - * 194 - * 12 15 | 12 15 195 - * 13 14 | 13 14 196 - * 14 16 | 14 16 197 - * 198 - * MAIN BLOCK BOUNDARY 199 - * 200 - * 15 17 | 15 18 201 - * 16 18 | 16 17 202 - * 17 20 | 17 20 203 - * 18 19 | 18 19 204 - * 19 21 | 19 21 205 - * 206 - * As we can see from above, the addresses aren't mangled across 207 - * block boundaries, so we don't need to worry about address 208 - * translations except for sending/reading commands during 209 - * initialization 210 - */ 211 - 212 - /* Mangle address (x) on chip U2 */ 213 - #define ADDR_TO_FLASH_U2(x) \ 214 - ( \ 215 - (((x) & 0x00000f00) >> 4) + \ 216 - (((x) & 0x00042000) << 1) + \ 217 - (((x) & 0x0009c003) << 2) + \ 218 - (((x) & 0x00021080) << 3) + \ 219 - (((x) & 0x00000010) << 4) + \ 220 - (((x) & 0x00000040) << 5) + \ 221 - (((x) & 0x00000024) << 7) + \ 222 - (((x) & 0x00000008) << 10) \ 223 - ) 224 - 225 - /* Unmangle address (x) on chip U2 */ 226 - #define FLASH_U2_TO_ADDR(x) \ 227 - ( \ 228 - (((x) << 4) & 0x00000f00) + \ 229 - (((x) >> 1) & 0x00042000) + \ 230 - (((x) >> 2) & 0x0009c003) + \ 231 - (((x) >> 3) & 0x00021080) + \ 232 - (((x) >> 4) & 0x00000010) + \ 233 - (((x) >> 5) & 0x00000040) + \ 234 - (((x) >> 7) & 0x00000024) + \ 235 - (((x) >> 10) & 0x00000008) \ 236 - ) 237 - 238 - /* Mangle address (x) on chip U3 */ 239 - #define ADDR_TO_FLASH_U3(x) \ 240 - ( \ 241 - (((x) & 0x00000080) >> 3) + \ 242 - (((x) & 0x00000040) >> 1) + \ 243 - (((x) & 0x00052020) << 1) + \ 244 - (((x) & 0x00084f03) << 2) + \ 245 - (((x) & 0x00029010) << 3) + \ 246 - (((x) & 0x00000008) << 5) + \ 247 - (((x) & 0x00000004) << 7) \ 248 - ) 249 - 250 - /* Unmangle address (x) on chip U3 */ 251 - #define FLASH_U3_TO_ADDR(x) \ 252 - ( \ 253 - (((x) << 3) & 0x00000080) + \ 254 - (((x) << 1) & 0x00000040) + \ 255 - (((x) >> 1) & 0x00052020) + \ 256 - (((x) >> 2) & 0x00084f03) + \ 257 - (((x) >> 3) & 0x00029010) + \ 258 - (((x) >> 5) & 0x00000008) + \ 259 - (((x) >> 7) & 0x00000004) \ 260 - ) 261 - 262 - /***************************************************************************************************/ 263 - 264 - static __u8 read8 (__u32 offset) 265 - { 266 - volatile __u8 *data = (__u8 *) (FLASH_OFFSET + offset); 267 - #ifdef LART_DEBUG 268 - printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.2x\n", __func__, offset, *data); 269 - #endif 270 - return (*data); 271 - } 272 - 273 - static __u32 read32 (__u32 offset) 274 - { 275 - volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset); 276 - #ifdef LART_DEBUG 277 - printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.8x\n", __func__, offset, *data); 278 - #endif 279 - return (*data); 280 - } 281 - 282 - static void write32 (__u32 x,__u32 offset) 283 - { 284 - volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset); 285 - *data = x; 286 - #ifdef LART_DEBUG 287 - printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n", __func__, offset, *data); 288 - #endif 289 - } 290 - 291 - /***************************************************************************************************/ 292 - 293 - /* 294 - * Probe for 16mbit flash memory on a LART board without doing 295 - * too much damage. Since we need to write 1 dword to memory, 296 - * we're f**cked if this happens to be DRAM since we can't 297 - * restore the memory (otherwise we might exit Read Array mode). 298 - * 299 - * Returns 1 if we found 16mbit flash memory on LART, 0 otherwise. 300 - */ 301 - static int flash_probe (void) 302 - { 303 - __u32 manufacturer,devtype; 304 - 305 - /* setup "Read Identifier Codes" mode */ 306 - write32 (DATA_TO_FLASH (READ_ID_CODES),0x00000000); 307 - 308 - /* probe U2. U2/U3 returns the same data since the first 3 309 - * address lines is mangled in the same way */ 310 - manufacturer = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000000))); 311 - devtype = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000001))); 312 - 313 - /* put the flash back into command mode */ 314 - write32 (DATA_TO_FLASH (READ_ARRAY),0x00000000); 315 - 316 - return (manufacturer == FLASH_MANUFACTURER && (devtype == FLASH_DEVICE_16mbit_TOP || devtype == FLASH_DEVICE_16mbit_BOTTOM)); 317 - } 318 - 319 - /* 320 - * Erase one block of flash memory at offset ``offset'' which is any 321 - * address within the block which should be erased. 322 - * 323 - * Returns 1 if successful, 0 otherwise. 324 - */ 325 - static inline int erase_block (__u32 offset) 326 - { 327 - __u32 status; 328 - 329 - #ifdef LART_DEBUG 330 - printk (KERN_DEBUG "%s(): 0x%.8x\n", __func__, offset); 331 - #endif 332 - 333 - /* erase and confirm */ 334 - write32 (DATA_TO_FLASH (ERASE_SETUP),offset); 335 - write32 (DATA_TO_FLASH (ERASE_CONFIRM),offset); 336 - 337 - /* wait for block erase to finish */ 338 - do 339 - { 340 - write32 (DATA_TO_FLASH (STATUS_READ),offset); 341 - status = FLASH_TO_DATA (read32 (offset)); 342 - } 343 - while ((~status & STATUS_BUSY) != 0); 344 - 345 - /* put the flash back into command mode */ 346 - write32 (DATA_TO_FLASH (READ_ARRAY),offset); 347 - 348 - /* was the erase successful? */ 349 - if ((status & STATUS_ERASE_ERR)) 350 - { 351 - printk (KERN_WARNING "%s: erase error at address 0x%.8x.\n",module_name,offset); 352 - return (0); 353 - } 354 - 355 - return (1); 356 - } 357 - 358 - static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) 359 - { 360 - __u32 addr,len; 361 - int i,first; 362 - 363 - #ifdef LART_DEBUG 364 - printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len); 365 - #endif 366 - 367 - /* 368 - * check that both start and end of the requested erase are 369 - * aligned with the erasesize at the appropriate addresses. 370 - * 371 - * skip all erase regions which are ended before the start of 372 - * the requested erase. Actually, to save on the calculations, 373 - * we skip to the first erase region which starts after the 374 - * start of the requested erase, and then go back one. 375 - */ 376 - for (i = 0; i < mtd->numeraseregions && instr->addr >= mtd->eraseregions[i].offset; i++) ; 377 - i--; 378 - 379 - /* 380 - * ok, now i is pointing at the erase region in which this 381 - * erase request starts. Check the start of the requested 382 - * erase range is aligned with the erase size which is in 383 - * effect here. 384 - */ 385 - if (i < 0 || (instr->addr & (mtd->eraseregions[i].erasesize - 1))) 386 - return -EINVAL; 387 - 388 - /* Remember the erase region we start on */ 389 - first = i; 390 - 391 - /* 392 - * next, check that the end of the requested erase is aligned 393 - * with the erase region at that address. 394 - * 395 - * as before, drop back one to point at the region in which 396 - * the address actually falls 397 - */ 398 - for (; i < mtd->numeraseregions && instr->addr + instr->len >= mtd->eraseregions[i].offset; i++) ; 399 - i--; 400 - 401 - /* is the end aligned on a block boundary? */ 402 - if (i < 0 || ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1))) 403 - return -EINVAL; 404 - 405 - addr = instr->addr; 406 - len = instr->len; 407 - 408 - i = first; 409 - 410 - /* now erase those blocks */ 411 - while (len) 412 - { 413 - if (!erase_block (addr)) 414 - return (-EIO); 415 - 416 - addr += mtd->eraseregions[i].erasesize; 417 - len -= mtd->eraseregions[i].erasesize; 418 - 419 - if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++; 420 - } 421 - 422 - return (0); 423 - } 424 - 425 - static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retlen,u_char *buf) 426 - { 427 - #ifdef LART_DEBUG 428 - printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len); 429 - #endif 430 - 431 - /* we always read len bytes */ 432 - *retlen = len; 433 - 434 - /* first, we read bytes until we reach a dword boundary */ 435 - if (from & (BUSWIDTH - 1)) 436 - { 437 - int gap = BUSWIDTH - (from & (BUSWIDTH - 1)); 438 - 439 - while (len && gap--) { 440 - *buf++ = read8 (from++); 441 - len--; 442 - } 443 - } 444 - 445 - /* now we read dwords until we reach a non-dword boundary */ 446 - while (len >= BUSWIDTH) 447 - { 448 - *((__u32 *) buf) = read32 (from); 449 - 450 - buf += BUSWIDTH; 451 - from += BUSWIDTH; 452 - len -= BUSWIDTH; 453 - } 454 - 455 - /* top up the last unaligned bytes */ 456 - if (len & (BUSWIDTH - 1)) 457 - while (len--) *buf++ = read8 (from++); 458 - 459 - return (0); 460 - } 461 - 462 - /* 463 - * Write one dword ``x'' to flash memory at offset ``offset''. ``offset'' 464 - * must be 32 bits, i.e. it must be on a dword boundary. 465 - * 466 - * Returns 1 if successful, 0 otherwise. 467 - */ 468 - static inline int write_dword (__u32 offset,__u32 x) 469 - { 470 - __u32 status; 471 - 472 - #ifdef LART_DEBUG 473 - printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n", __func__, offset, x); 474 - #endif 475 - 476 - /* setup writing */ 477 - write32 (DATA_TO_FLASH (PGM_SETUP),offset); 478 - 479 - /* write the data */ 480 - write32 (x,offset); 481 - 482 - /* wait for the write to finish */ 483 - do 484 - { 485 - write32 (DATA_TO_FLASH (STATUS_READ),offset); 486 - status = FLASH_TO_DATA (read32 (offset)); 487 - } 488 - while ((~status & STATUS_BUSY) != 0); 489 - 490 - /* put the flash back into command mode */ 491 - write32 (DATA_TO_FLASH (READ_ARRAY),offset); 492 - 493 - /* was the write successful? */ 494 - if ((status & STATUS_PGM_ERR) || read32 (offset) != x) 495 - { 496 - printk (KERN_WARNING "%s: write error at address 0x%.8x.\n",module_name,offset); 497 - return (0); 498 - } 499 - 500 - return (1); 501 - } 502 - 503 - static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf) 504 - { 505 - __u8 tmp[4]; 506 - int i,n; 507 - 508 - #ifdef LART_DEBUG 509 - printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len); 510 - #endif 511 - 512 - /* sanity checks */ 513 - if (!len) return (0); 514 - 515 - /* first, we write a 0xFF.... padded byte until we reach a dword boundary */ 516 - if (to & (BUSWIDTH - 1)) 517 - { 518 - __u32 aligned = to & ~(BUSWIDTH - 1); 519 - int gap = to - aligned; 520 - 521 - i = n = 0; 522 - 523 - while (gap--) tmp[i++] = 0xFF; 524 - while (len && i < BUSWIDTH) { 525 - tmp[i++] = buf[n++]; 526 - len--; 527 - } 528 - while (i < BUSWIDTH) tmp[i++] = 0xFF; 529 - 530 - if (!write_dword (aligned,*((__u32 *) tmp))) return (-EIO); 531 - 532 - to += n; 533 - buf += n; 534 - *retlen += n; 535 - } 536 - 537 - /* now we write dwords until we reach a non-dword boundary */ 538 - while (len >= BUSWIDTH) 539 - { 540 - if (!write_dword (to,*((__u32 *) buf))) return (-EIO); 541 - 542 - to += BUSWIDTH; 543 - buf += BUSWIDTH; 544 - *retlen += BUSWIDTH; 545 - len -= BUSWIDTH; 546 - } 547 - 548 - /* top up the last unaligned bytes, padded with 0xFF.... */ 549 - if (len & (BUSWIDTH - 1)) 550 - { 551 - i = n = 0; 552 - 553 - while (len--) tmp[i++] = buf[n++]; 554 - while (i < BUSWIDTH) tmp[i++] = 0xFF; 555 - 556 - if (!write_dword (to,*((__u32 *) tmp))) return (-EIO); 557 - 558 - *retlen += n; 559 - } 560 - 561 - return (0); 562 - } 563 - 564 - /***************************************************************************************************/ 565 - 566 - static struct mtd_info mtd; 567 - 568 - static struct mtd_erase_region_info erase_regions[] = { 569 - /* parameter blocks */ 570 - { 571 - .offset = 0x00000000, 572 - .erasesize = FLASH_BLOCKSIZE_PARAM, 573 - .numblocks = FLASH_NUMBLOCKS_16m_PARAM, 574 - }, 575 - /* main blocks */ 576 - { 577 - .offset = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM, 578 - .erasesize = FLASH_BLOCKSIZE_MAIN, 579 - .numblocks = FLASH_NUMBLOCKS_16m_MAIN, 580 - } 581 - }; 582 - 583 - static const struct mtd_partition lart_partitions[] = { 584 - /* blob */ 585 - { 586 - .name = "blob", 587 - .offset = PART_BLOB_START, 588 - .size = PART_BLOB_LEN, 589 - }, 590 - /* kernel */ 591 - { 592 - .name = "kernel", 593 - .offset = PART_KERNEL_START, /* MTDPART_OFS_APPEND */ 594 - .size = PART_KERNEL_LEN, 595 - }, 596 - /* initial ramdisk / file system */ 597 - { 598 - .name = "file system", 599 - .offset = PART_INITRD_START, /* MTDPART_OFS_APPEND */ 600 - .size = PART_INITRD_LEN, /* MTDPART_SIZ_FULL */ 601 - } 602 - }; 603 - #define NUM_PARTITIONS ARRAY_SIZE(lart_partitions) 604 - 605 - static int __init lart_flash_init (void) 606 - { 607 - int result; 608 - memset (&mtd,0,sizeof (mtd)); 609 - printk ("MTD driver for LART. Written by Abraham vd Merwe <abraham@2d3d.co.za>\n"); 610 - printk ("%s: Probing for 28F160x3 flash on LART...\n",module_name); 611 - if (!flash_probe ()) 612 - { 613 - printk (KERN_WARNING "%s: Found no LART compatible flash device\n",module_name); 614 - return (-ENXIO); 615 - } 616 - printk ("%s: This looks like a LART board to me.\n",module_name); 617 - mtd.name = module_name; 618 - mtd.type = MTD_NORFLASH; 619 - mtd.writesize = 1; 620 - mtd.writebufsize = 4; 621 - mtd.flags = MTD_CAP_NORFLASH; 622 - mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; 623 - mtd.erasesize = FLASH_BLOCKSIZE_MAIN; 624 - mtd.numeraseregions = ARRAY_SIZE(erase_regions); 625 - mtd.eraseregions = erase_regions; 626 - mtd._erase = flash_erase; 627 - mtd._read = flash_read; 628 - mtd._write = flash_write; 629 - mtd.owner = THIS_MODULE; 630 - 631 - #ifdef LART_DEBUG 632 - printk (KERN_DEBUG 633 - "mtd.name = %s\n" 634 - "mtd.size = 0x%.8x (%uM)\n" 635 - "mtd.erasesize = 0x%.8x (%uK)\n" 636 - "mtd.numeraseregions = %d\n", 637 - mtd.name, 638 - mtd.size,mtd.size / (1024*1024), 639 - mtd.erasesize,mtd.erasesize / 1024, 640 - mtd.numeraseregions); 641 - 642 - if (mtd.numeraseregions) 643 - for (result = 0; result < mtd.numeraseregions; result++) 644 - printk (KERN_DEBUG 645 - "\n\n" 646 - "mtd.eraseregions[%d].offset = 0x%.8x\n" 647 - "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n" 648 - "mtd.eraseregions[%d].numblocks = %d\n", 649 - result,mtd.eraseregions[result].offset, 650 - result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024, 651 - result,mtd.eraseregions[result].numblocks); 652 - 653 - printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); 654 - 655 - for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) 656 - printk (KERN_DEBUG 657 - "\n\n" 658 - "lart_partitions[%d].name = %s\n" 659 - "lart_partitions[%d].offset = 0x%.8x\n" 660 - "lart_partitions[%d].size = 0x%.8x (%uK)\n", 661 - result,lart_partitions[result].name, 662 - result,lart_partitions[result].offset, 663 - result,lart_partitions[result].size,lart_partitions[result].size / 1024); 664 - #endif 665 - 666 - result = mtd_device_register(&mtd, lart_partitions, 667 - ARRAY_SIZE(lart_partitions)); 668 - 669 - return (result); 670 - } 671 - 672 - static void __exit lart_flash_exit (void) 673 - { 674 - mtd_device_unregister(&mtd); 675 - } 676 - 677 - module_init (lart_flash_init); 678 - module_exit (lart_flash_exit); 679 - 680 - MODULE_LICENSE("GPL"); 681 - MODULE_AUTHOR("Abraham vd Merwe <abraham@2d3d.co.za>"); 682 - MODULE_DESCRIPTION("MTD driver for Intel 28F160F3 on LART board");
+1 -1
drivers/mtd/inftlcore.c
··· 356 356 * Newest unit in chain now contains data from _all_ older units. 357 357 * So go through and erase each unit in chain, oldest first. (This 358 358 * is important, by doing oldest first if we crash/reboot then it 359 - * it is relatively simple to clean up the mess). 359 + * is relatively simple to clean up the mess). 360 360 */ 361 361 pr_debug("INFTL: want to erase virtual chain %d\n", thisVUC); 362 362
+2
drivers/mtd/lpddr/lpddr2_nvm.c
··· 433 433 434 434 /* lpddr2_nvm address range */ 435 435 add_range = platform_get_resource(pdev, IORESOURCE_MEM, 0); 436 + if (!add_range) 437 + return -ENODEV; 436 438 437 439 /* Populate map_info data structure */ 438 440 *map = (struct map_info) {
+2
drivers/mtd/maps/pxa2xx-flash.c
··· 64 64 if (!info->map.virt) { 65 65 printk(KERN_WARNING "Failed to ioremap %s\n", 66 66 info->map.name); 67 + kfree(info); 67 68 return -ENOMEM; 68 69 } 69 70 info->map.cached = ioremap_cache(info->map.phys, info->map.size); ··· 86 85 iounmap((void *)info->map.virt); 87 86 if (info->map.cached) 88 87 iounmap(info->map.cached); 88 + kfree(info); 89 89 return -EIO; 90 90 } 91 91 info->mtd->dev.parent = &pdev->dev;
+32 -23
drivers/mtd/mtdcore.c
··· 28 28 #include <linux/leds.h> 29 29 #include <linux/debugfs.h> 30 30 #include <linux/nvmem-provider.h> 31 + #include <linux/root_dev.h> 31 32 32 33 #include <linux/mtd/mtd.h> 33 34 #include <linux/mtd/partitions.h> ··· 552 551 struct device_node *partitions, *parent_dn, *mtd_dn = NULL; 553 552 const char *pname, *prefix = "partition-"; 554 553 int plen, mtd_name_len, offset, prefix_len; 555 - struct mtd_info *parent; 556 - bool found = false; 557 554 558 555 /* Check if MTD already has a device node */ 559 - if (dev_of_node(&mtd->dev)) 556 + if (mtd_get_of_node(mtd)) 560 557 return; 561 558 562 - /* Check if a partitions node exist */ 563 559 if (!mtd_is_partition(mtd)) 564 560 return; 565 - parent = mtd->parent; 566 - parent_dn = of_node_get(dev_of_node(&parent->dev)); 561 + 562 + parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); 567 563 if (!parent_dn) 568 564 return; 569 565 570 - partitions = of_get_child_by_name(parent_dn, "partitions"); 566 + if (mtd_is_partition(mtd->parent)) 567 + partitions = of_node_get(parent_dn); 568 + else 569 + partitions = of_get_child_by_name(parent_dn, "partitions"); 571 570 if (!partitions) 572 571 goto exit_parent; 573 572 ··· 576 575 577 576 /* Search if a partition is defined with the same name */ 578 577 for_each_child_of_node(partitions, mtd_dn) { 579 - offset = 0; 580 - 581 578 /* Skip partition with no/wrong prefix */ 582 - if (!of_node_name_prefix(mtd_dn, "partition-")) 579 + if (!of_node_name_prefix(mtd_dn, prefix)) 583 580 continue; 584 581 585 582 /* Label have priority. Check that first */ 586 - if (of_property_read_string(mtd_dn, "label", &pname)) { 587 - of_property_read_string(mtd_dn, "name", &pname); 583 + if (!of_property_read_string(mtd_dn, "label", &pname)) { 584 + offset = 0; 585 + } else { 586 + pname = mtd_dn->name; 588 587 offset = prefix_len; 589 588 } 590 589 591 590 plen = strlen(pname) - offset; 592 591 if (plen == mtd_name_len && 593 592 !strncmp(mtd->name, pname + offset, plen)) { 594 - found = true; 593 + mtd_set_of_node(mtd, mtd_dn); 595 594 break; 596 595 } 597 596 } 598 597 599 - if (!found) 600 - goto exit_partitions; 601 - 602 - /* Set of_node only for nvmem */ 603 - if (of_device_is_compatible(mtd_dn, "nvmem-cells")) 604 - mtd_set_of_node(mtd, mtd_dn); 605 - 606 - exit_partitions: 607 598 of_node_put(partitions); 608 599 exit_parent: 609 600 of_node_put(parent_dn); ··· 716 723 mtd_check_of_node(mtd); 717 724 of_node_get(mtd_get_of_node(mtd)); 718 725 error = device_register(&mtd->dev); 719 - if (error) 726 + if (error) { 727 + put_device(&mtd->dev); 720 728 goto fail_added; 729 + } 721 730 722 731 /* Add the nvmem provider */ 723 732 error = mtd_nvmem_add(mtd); ··· 738 743 not->add(mtd); 739 744 740 745 mutex_unlock(&mtd_table_mutex); 746 + 747 + if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { 748 + if (IS_BUILTIN(CONFIG_MTD)) { 749 + pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); 750 + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); 751 + } else { 752 + pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n", 753 + mtd->index, mtd->name); 754 + } 755 + } 756 + 741 757 /* We _know_ we aren't being removed, because 742 758 our caller is still holding us here. So none 743 759 of this try_ nonsense, and no bitching about it ··· 780 774 { 781 775 int ret; 782 776 struct mtd_notifier *not; 777 + struct device_node *mtd_of_node; 783 778 784 779 mutex_lock(&mtd_table_mutex); 785 780 ··· 799 792 mtd->index, mtd->name, mtd->usecount); 800 793 ret = -EBUSY; 801 794 } else { 795 + mtd_of_node = mtd_get_of_node(mtd); 802 796 debugfs_remove_recursive(mtd->dbg.dfs_dir); 803 797 804 798 /* Try to remove the NVMEM provider */ ··· 811 803 memset(&mtd->dev, 0, sizeof(mtd->dev)); 812 804 813 805 idr_remove(&mtd_idr, mtd->index); 814 - of_node_put(mtd_get_of_node(mtd)); 806 + of_node_put(mtd_of_node); 815 807 816 808 module_put(THIS_MODULE); 817 809 ret = 0; ··· 2491 2483 out_procfs: 2492 2484 if (proc_mtd) 2493 2485 remove_proc_entry("mtd", NULL); 2486 + bdi_unregister(mtd_bdi); 2494 2487 bdi_put(mtd_bdi); 2495 2488 err_bdi: 2496 2489 class_unregister(&mtd_class);
+62 -47
drivers/mtd/mtdoops.c
··· 7 7 * Author: Richard Purdie <rpurdie@openedhand.com> 8 8 */ 9 9 10 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 + 10 12 #include <linux/kernel.h> 11 13 #include <linux/module.h> 12 14 #include <linux/console.h> ··· 95 93 96 94 ret = mtd_erase(mtd, &erase); 97 95 if (ret) { 98 - printk(KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] on \"%s\" failed\n", 99 - (unsigned long long)erase.addr, 100 - (unsigned long long)erase.len, mtddev); 96 + pr_warn("erase of region [0x%llx, 0x%llx] on \"%s\" failed\n", 97 + (unsigned long long)erase.addr, 98 + (unsigned long long)erase.len, mtddev); 101 99 return ret; 102 100 } 103 101 ··· 108 106 return 0; 109 107 } 110 108 111 - static void mtdoops_inc_counter(struct mtdoops_context *cxt) 109 + static void mtdoops_erase(struct mtdoops_context *cxt) 112 110 { 113 - cxt->nextpage++; 114 - if (cxt->nextpage >= cxt->oops_pages) 115 - cxt->nextpage = 0; 116 - cxt->nextcount++; 117 - if (cxt->nextcount == 0xffffffff) 118 - cxt->nextcount = 0; 119 - 120 - if (page_is_used(cxt, cxt->nextpage)) { 121 - schedule_work(&cxt->work_erase); 122 - return; 123 - } 124 - 125 - printk(KERN_DEBUG "mtdoops: ready %d, %d (no erase)\n", 126 - cxt->nextpage, cxt->nextcount); 127 - } 128 - 129 - /* Scheduled work - when we can't proceed without erasing a block */ 130 - static void mtdoops_workfunc_erase(struct work_struct *work) 131 - { 132 - struct mtdoops_context *cxt = 133 - container_of(work, struct mtdoops_context, work_erase); 134 111 struct mtd_info *mtd = cxt->mtd; 135 112 int i = 0, j, ret, mod; 136 113 ··· 126 145 127 146 while ((ret = mtd_block_isbad(mtd, cxt->nextpage * record_size)) > 0) { 128 147 badblock: 129 - printk(KERN_WARNING "mtdoops: bad block at %08lx\n", 130 - cxt->nextpage * record_size); 148 + pr_warn("bad block at %08lx\n", 149 + cxt->nextpage * record_size); 131 150 i++; 132 151 cxt->nextpage = cxt->nextpage + (mtd->erasesize / record_size); 133 152 if (cxt->nextpage >= cxt->oops_pages) 134 153 cxt->nextpage = 0; 135 154 if (i == cxt->oops_pages / (mtd->erasesize / record_size)) { 136 - printk(KERN_ERR "mtdoops: all blocks bad!\n"); 155 + pr_err("all blocks bad!\n"); 137 156 return; 138 157 } 139 158 } 140 159 141 160 if (ret < 0) { 142 - printk(KERN_ERR "mtdoops: mtd_block_isbad failed, aborting\n"); 161 + pr_err("mtd_block_isbad failed, aborting\n"); 143 162 return; 144 163 } 145 164 ··· 147 166 ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size); 148 167 149 168 if (ret >= 0) { 150 - printk(KERN_DEBUG "mtdoops: ready %d, %d\n", 151 - cxt->nextpage, cxt->nextcount); 169 + pr_debug("ready %d, %d\n", 170 + cxt->nextpage, cxt->nextcount); 152 171 return; 153 172 } 154 173 155 174 if (ret == -EIO) { 156 175 ret = mtd_block_markbad(mtd, cxt->nextpage * record_size); 157 176 if (ret < 0 && ret != -EOPNOTSUPP) { 158 - printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n"); 177 + pr_err("block_markbad failed, aborting\n"); 159 178 return; 160 179 } 161 180 } 162 181 goto badblock; 182 + } 183 + 184 + /* Scheduled work - when we can't proceed without erasing a block */ 185 + static void mtdoops_workfunc_erase(struct work_struct *work) 186 + { 187 + struct mtdoops_context *cxt = 188 + container_of(work, struct mtdoops_context, work_erase); 189 + mtdoops_erase(cxt); 190 + } 191 + 192 + static void mtdoops_inc_counter(struct mtdoops_context *cxt, int panic) 193 + { 194 + cxt->nextpage++; 195 + if (cxt->nextpage >= cxt->oops_pages) 196 + cxt->nextpage = 0; 197 + cxt->nextcount++; 198 + if (cxt->nextcount == 0xffffffff) 199 + cxt->nextcount = 0; 200 + 201 + if (page_is_used(cxt, cxt->nextpage)) { 202 + pr_debug("not ready %d, %d (erase %s)\n", 203 + cxt->nextpage, cxt->nextcount, 204 + panic ? "immediately" : "scheduled"); 205 + if (panic) { 206 + /* In case of panic, erase immediately */ 207 + mtdoops_erase(cxt); 208 + } else { 209 + /* Otherwise, schedule work to erase it "nicely" */ 210 + schedule_work(&cxt->work_erase); 211 + } 212 + } else { 213 + pr_debug("ready %d, %d (no erase)\n", 214 + cxt->nextpage, cxt->nextcount); 215 + } 163 216 } 164 217 165 218 static void mtdoops_write(struct mtdoops_context *cxt, int panic) ··· 216 201 ret = mtd_panic_write(mtd, cxt->nextpage * record_size, 217 202 record_size, &retlen, cxt->oops_buf); 218 203 if (ret == -EOPNOTSUPP) { 219 - printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n"); 204 + pr_err("Cannot write from panic without panic_write\n"); 220 205 goto out; 221 206 } 222 207 } else ··· 224 209 record_size, &retlen, cxt->oops_buf); 225 210 226 211 if (retlen != record_size || ret < 0) 227 - printk(KERN_ERR "mtdoops: write failure at %ld (%td of %ld written), error %d\n", 212 + pr_err("write failure at %ld (%td of %ld written), error %d\n", 228 213 cxt->nextpage * record_size, retlen, record_size, ret); 229 214 mark_page_used(cxt, cxt->nextpage); 230 215 memset(cxt->oops_buf, 0xff, record_size); 231 216 232 - mtdoops_inc_counter(cxt); 217 + mtdoops_inc_counter(cxt, panic); 233 218 out: 234 219 clear_bit(0, &cxt->oops_buf_busy); 235 220 } ··· 259 244 &retlen, (u_char *)&hdr); 260 245 if (retlen != sizeof(hdr) || 261 246 (ret < 0 && !mtd_is_bitflip(ret))) { 262 - printk(KERN_ERR "mtdoops: read failure at %ld (%zu of %zu read), err %d\n", 247 + pr_err("read failure at %ld (%zu of %zu read), err %d\n", 263 248 page * record_size, retlen, sizeof(hdr), ret); 264 249 continue; 265 250 } ··· 294 279 cxt->nextcount = maxcount; 295 280 } 296 281 297 - mtdoops_inc_counter(cxt); 282 + mtdoops_inc_counter(cxt, 0); 298 283 } 299 284 300 285 static void mtdoops_do_dump(struct kmsg_dumper *dumper, ··· 339 324 return; 340 325 341 326 if (mtd->size < mtd->erasesize * 2) { 342 - printk(KERN_ERR "mtdoops: MTD partition %d not big enough for mtdoops\n", 327 + pr_err("MTD partition %d not big enough for mtdoops\n", 343 328 mtd->index); 344 329 return; 345 330 } 346 331 if (mtd->erasesize < record_size) { 347 - printk(KERN_ERR "mtdoops: eraseblock size of MTD partition %d too small\n", 332 + pr_err("eraseblock size of MTD partition %d too small\n", 348 333 mtd->index); 349 334 return; 350 335 } 351 336 if (mtd->size > MTDOOPS_MAX_MTD_SIZE) { 352 - printk(KERN_ERR "mtdoops: mtd%d is too large (limit is %d MiB)\n", 337 + pr_err("mtd%d is too large (limit is %d MiB)\n", 353 338 mtd->index, MTDOOPS_MAX_MTD_SIZE / 1024 / 1024); 354 339 return; 355 340 } ··· 360 345 DIV_ROUND_UP(mtdoops_pages, 361 346 BITS_PER_LONG))); 362 347 if (!cxt->oops_page_used) { 363 - printk(KERN_ERR "mtdoops: could not allocate page array\n"); 348 + pr_err("could not allocate page array\n"); 364 349 return; 365 350 } 366 351 ··· 368 353 cxt->dump.dump = mtdoops_do_dump; 369 354 err = kmsg_dump_register(&cxt->dump); 370 355 if (err) { 371 - printk(KERN_ERR "mtdoops: registering kmsg dumper failed, error %d\n", err); 356 + pr_err("registering kmsg dumper failed, error %d\n", err); 372 357 vfree(cxt->oops_page_used); 373 358 cxt->oops_page_used = NULL; 374 359 return; ··· 377 362 cxt->mtd = mtd; 378 363 cxt->oops_pages = (int)mtd->size / record_size; 379 364 find_next_position(cxt); 380 - printk(KERN_INFO "mtdoops: Attached to MTD device %d\n", mtd->index); 365 + pr_info("Attached to MTD device %d\n", mtd->index); 381 366 } 382 367 383 368 static void mtdoops_notify_remove(struct mtd_info *mtd) ··· 388 373 return; 389 374 390 375 if (kmsg_dump_unregister(&cxt->dump) < 0) 391 - printk(KERN_WARNING "mtdoops: could not unregister kmsg_dumper\n"); 376 + pr_warn("could not unregister kmsg_dumper\n"); 392 377 393 378 cxt->mtd = NULL; 394 379 flush_work(&cxt->work_erase); ··· 408 393 char *endp; 409 394 410 395 if (strlen(mtddev) == 0) { 411 - printk(KERN_ERR "mtdoops: mtd device (mtddev=name/number) must be supplied\n"); 396 + pr_err("mtd device (mtddev=name/number) must be supplied\n"); 412 397 return -EINVAL; 413 398 } 414 399 if ((record_size & 4095) != 0) { 415 - printk(KERN_ERR "mtdoops: record_size must be a multiple of 4096\n"); 400 + pr_err("record_size must be a multiple of 4096\n"); 416 401 return -EINVAL; 417 402 } 418 403 if (record_size < 4096) { 419 - printk(KERN_ERR "mtdoops: record_size must be over 4096 bytes\n"); 404 + pr_err("record_size must be over 4096 bytes\n"); 420 405 return -EINVAL; 421 406 } 422 407
+1 -2
drivers/mtd/nand/core.c
··· 126 126 * 127 127 * Return: 0 in case of success, a negative error code otherwise. 128 128 */ 129 - int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos) 129 + static int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos) 130 130 { 131 131 if (nanddev_isbad(nand, pos) || nanddev_isreserved(nand, pos)) { 132 132 pr_warn("attempt to erase a bad/reserved block @%llx\n", ··· 136 136 137 137 return nand->ops->erase(nand, pos); 138 138 } 139 - EXPORT_SYMBOL_GPL(nanddev_erase); 140 139 141 140 /** 142 141 * nanddev_mtd_erase() - Generic mtd->_erase() implementation for NAND devices
+3 -3
drivers/mtd/nand/raw/Kconfig
··· 415 415 416 416 config MTD_NAND_CADENCE 417 417 tristate "Support Cadence NAND (HPNFC) controller" 418 - depends on (OF || COMPILE_TEST) && HAS_IOMEM 418 + depends on OF && HAS_IOMEM 419 419 help 420 420 Enable the driver for NAND flash on platforms using a Cadence NAND 421 421 controller. ··· 430 430 431 431 config MTD_NAND_INTEL_LGM 432 432 tristate "Support for NAND controller on Intel LGM SoC" 433 - depends on OF || COMPILE_TEST 433 + depends on OF 434 434 depends on HAS_IOMEM 435 435 help 436 436 Enables support for NAND Flash chips on Intel's LGM SoC. ··· 450 450 451 451 config MTD_NAND_PL35X 452 452 tristate "ARM PL35X NAND controller" 453 - depends on OF || COMPILE_TEST 453 + depends on OF 454 454 depends on PL353_SMC 455 455 help 456 456 Enables support for PrimeCell SMC PL351 and PL353 NAND
+58 -12
drivers/mtd/nand/raw/cadence-nand-controller.c
··· 1184 1184 if (cadence_nand_read_bch_caps(cdns_ctrl)) 1185 1185 return -EIO; 1186 1186 1187 + #ifndef CONFIG_64BIT 1188 + if (cdns_ctrl->caps2.data_dma_width == 8) { 1189 + dev_err(cdns_ctrl->dev, 1190 + "cannot access 64-bit dma on !64-bit architectures"); 1191 + return -EIO; 1192 + } 1193 + #endif 1194 + 1187 1195 /* 1188 1196 * Set IO width access to 8. 1189 1197 * It is because during SW device discovering width access ··· 1890 1882 return status; 1891 1883 1892 1884 if (!cdns_ctrl->caps1->has_dma) { 1893 - int len_in_words = len >> 2; 1885 + u8 data_dma_width = cdns_ctrl->caps2.data_dma_width; 1886 + 1887 + int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3; 1894 1888 1895 1889 /* read alingment data */ 1896 - ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words); 1890 + if (data_dma_width == 4) 1891 + ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words); 1892 + #ifdef CONFIG_64BIT 1893 + else 1894 + readsq(cdns_ctrl->io.virt, buf, len_in_words); 1895 + #endif 1896 + 1897 1897 if (sdma_size > len) { 1898 + int read_bytes = (data_dma_width == 4) ? 1899 + len_in_words << 2 : len_in_words << 3; 1900 + 1898 1901 /* read rest data from slave DMA interface if any */ 1899 - ioread32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf, 1900 - sdma_size / 4 - len_in_words); 1902 + if (data_dma_width == 4) 1903 + ioread32_rep(cdns_ctrl->io.virt, 1904 + cdns_ctrl->buf, 1905 + sdma_size / 4 - len_in_words); 1906 + #ifdef CONFIG_64BIT 1907 + else 1908 + readsq(cdns_ctrl->io.virt, cdns_ctrl->buf, 1909 + sdma_size / 8 - len_in_words); 1910 + #endif 1911 + 1901 1912 /* copy rest of data */ 1902 - memcpy(buf + (len_in_words << 2), cdns_ctrl->buf, 1903 - len - (len_in_words << 2)); 1913 + memcpy(buf + read_bytes, cdns_ctrl->buf, 1914 + len - read_bytes); 1904 1915 } 1905 1916 return 0; 1906 1917 } ··· 1963 1936 return status; 1964 1937 1965 1938 if (!cdns_ctrl->caps1->has_dma) { 1966 - int len_in_words = len >> 2; 1939 + u8 data_dma_width = cdns_ctrl->caps2.data_dma_width; 1967 1940 1968 - iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words); 1941 + int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3; 1942 + 1943 + if (data_dma_width == 4) 1944 + iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words); 1945 + #ifdef CONFIG_64BIT 1946 + else 1947 + writesq(cdns_ctrl->io.virt, buf, len_in_words); 1948 + #endif 1949 + 1969 1950 if (sdma_size > len) { 1951 + int written_bytes = (data_dma_width == 4) ? 1952 + len_in_words << 2 : len_in_words << 3; 1953 + 1970 1954 /* copy rest of data */ 1971 - memcpy(cdns_ctrl->buf, buf + (len_in_words << 2), 1972 - len - (len_in_words << 2)); 1955 + memcpy(cdns_ctrl->buf, buf + written_bytes, 1956 + len - written_bytes); 1957 + 1973 1958 /* write all expected by nand controller data */ 1974 - iowrite32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf, 1975 - sdma_size / 4 - len_in_words); 1959 + if (data_dma_width == 4) 1960 + iowrite32_rep(cdns_ctrl->io.virt, 1961 + cdns_ctrl->buf, 1962 + sdma_size / 4 - len_in_words); 1963 + #ifdef CONFIG_64BIT 1964 + else 1965 + writesq(cdns_ctrl->io.virt, cdns_ctrl->buf, 1966 + sdma_size / 8 - len_in_words); 1967 + #endif 1976 1968 } 1977 1969 1978 1970 return 0;
+4 -8
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
··· 148 148 struct resources *r = &this->resources; 149 149 int ret; 150 150 151 - ret = pm_runtime_get_sync(this->dev); 152 - if (ret < 0) { 153 - pm_runtime_put_noidle(this->dev); 151 + ret = pm_runtime_resume_and_get(this->dev); 152 + if (ret < 0) 154 153 return ret; 155 - } 156 154 157 155 ret = gpmi_reset_block(r->gpmi_regs, false); 158 156 if (ret) ··· 2502 2504 for (i = 0; i < GPMI_MAX_TRANSFERS; i++) 2503 2505 this->transfers[i].direction = DMA_NONE; 2504 2506 2505 - ret = pm_runtime_get_sync(this->dev); 2506 - if (ret < 0) { 2507 - pm_runtime_put_noidle(this->dev); 2507 + ret = pm_runtime_resume_and_get(this->dev); 2508 + if (ret < 0) 2508 2509 return ret; 2509 - } 2510 2510 2511 2511 /* 2512 2512 * This driver currently supports only one NAND chip. Plus, dies share
+21 -25
drivers/mtd/nand/raw/lpc32xx_mlc.c
··· 25 25 #include <linux/completion.h> 26 26 #include <linux/interrupt.h> 27 27 #include <linux/of.h> 28 - #include <linux/of_gpio.h> 28 + #include <linux/gpio/consumer.h> 29 29 #include <linux/mtd/lpc32xx_mlc.h> 30 30 #include <linux/io.h> 31 31 #include <linux/mm.h> ··· 122 122 uint32_t rd_low; 123 123 uint32_t wr_high; 124 124 uint32_t wr_low; 125 - int wp_gpio; 126 125 struct mtd_partition *parts; 127 126 unsigned num_parts; 128 127 }; ··· 176 177 struct nand_chip nand_chip; 177 178 struct lpc32xx_mlc_platform_data *pdata; 178 179 struct clk *clk; 180 + struct gpio_desc *wp_gpio; 179 181 void __iomem *io_base; 180 182 int irq; 181 183 struct lpc32xx_nand_cfg_mlc *ncfg; ··· 370 370 */ 371 371 static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) 372 372 { 373 - if (gpio_is_valid(host->ncfg->wp_gpio)) 374 - gpio_set_value(host->ncfg->wp_gpio, 0); 373 + if (host->wp_gpio) 374 + gpiod_set_value_cansleep(host->wp_gpio, 1); 375 375 } 376 376 377 377 /* ··· 379 379 */ 380 380 static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) 381 381 { 382 - if (gpio_is_valid(host->ncfg->wp_gpio)) 383 - gpio_set_value(host->ncfg->wp_gpio, 1); 382 + if (host->wp_gpio) 383 + gpiod_set_value_cansleep(host->wp_gpio, 0); 384 384 } 385 385 386 386 static void lpc32xx_dma_complete_func(void *completion) ··· 636 636 return NULL; 637 637 } 638 638 639 - ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0); 640 - 641 639 return ncfg; 642 640 } 643 641 ··· 711 713 "Missing or bad NAND config from device tree\n"); 712 714 return -ENOENT; 713 715 } 714 - if (host->ncfg->wp_gpio == -EPROBE_DEFER) 715 - return -EPROBE_DEFER; 716 - if (gpio_is_valid(host->ncfg->wp_gpio) && 717 - gpio_request(host->ncfg->wp_gpio, "NAND WP")) { 718 - dev_err(&pdev->dev, "GPIO not available\n"); 719 - return -EBUSY; 716 + 717 + /* Start with WP disabled, if available */ 718 + host->wp_gpio = gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW); 719 + res = PTR_ERR_OR_ZERO(host->wp_gpio); 720 + if (res) { 721 + if (res != -EPROBE_DEFER) 722 + dev_err(&pdev->dev, "WP GPIO is not available: %d\n", 723 + res); 724 + return res; 720 725 } 721 - lpc32xx_wp_disable(host); 726 + 727 + gpiod_set_consumer_name(host->wp_gpio, "NAND WP"); 722 728 723 729 host->pdata = dev_get_platdata(&pdev->dev); 724 730 ··· 819 817 clk_put(host->clk); 820 818 free_gpio: 821 819 lpc32xx_wp_enable(host); 822 - gpio_free(host->ncfg->wp_gpio); 820 + gpiod_put(host->wp_gpio); 823 821 824 822 return res; 825 823 } ··· 845 843 clk_put(host->clk); 846 844 847 845 lpc32xx_wp_enable(host); 848 - gpio_free(host->ncfg->wp_gpio); 846 + gpiod_put(host->wp_gpio); 849 847 850 848 return 0; 851 849 } 852 850 853 - #ifdef CONFIG_PM 854 851 static int lpc32xx_nand_resume(struct platform_device *pdev) 855 852 { 856 853 struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); ··· 881 880 return 0; 882 881 } 883 882 884 - #else 885 - #define lpc32xx_nand_resume NULL 886 - #define lpc32xx_nand_suspend NULL 887 - #endif 888 - 889 883 static const struct of_device_id lpc32xx_nand_match[] = { 890 884 { .compatible = "nxp,lpc3220-mlc" }, 891 885 { /* sentinel */ }, ··· 890 894 static struct platform_driver lpc32xx_nand_driver = { 891 895 .probe = lpc32xx_nand_probe, 892 896 .remove = lpc32xx_nand_remove, 893 - .resume = lpc32xx_nand_resume, 894 - .suspend = lpc32xx_nand_suspend, 897 + .resume = pm_ptr(lpc32xx_nand_resume), 898 + .suspend = pm_ptr(lpc32xx_nand_suspend), 895 899 .driver = { 896 900 .name = DRV_NAME, 897 901 .of_match_table = lpc32xx_nand_match,
+19 -24
drivers/mtd/nand/raw/lpc32xx_slc.c
··· 23 23 #include <linux/mm.h> 24 24 #include <linux/dma-mapping.h> 25 25 #include <linux/dmaengine.h> 26 - #include <linux/gpio.h> 26 + #include <linux/gpio/consumer.h> 27 27 #include <linux/of.h> 28 - #include <linux/of_gpio.h> 29 28 #include <linux/mtd/lpc32xx_slc.h> 30 29 31 30 #define LPC32XX_MODNAME "lpc32xx-nand" ··· 207 208 uint32_t rwidth; 208 209 uint32_t rhold; 209 210 uint32_t rsetup; 210 - int wp_gpio; 211 211 struct mtd_partition *parts; 212 212 unsigned num_parts; 213 213 }; ··· 215 217 struct nand_chip nand_chip; 216 218 struct lpc32xx_slc_platform_data *pdata; 217 219 struct clk *clk; 220 + struct gpio_desc *wp_gpio; 218 221 void __iomem *io_base; 219 222 struct lpc32xx_nand_cfg_slc *ncfg; 220 223 ··· 308 309 */ 309 310 static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) 310 311 { 311 - if (gpio_is_valid(host->ncfg->wp_gpio)) 312 - gpio_set_value(host->ncfg->wp_gpio, 0); 312 + if (host->wp_gpio) 313 + gpiod_set_value_cansleep(host->wp_gpio, 1); 313 314 } 314 315 315 316 /* ··· 317 318 */ 318 319 static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) 319 320 { 320 - if (gpio_is_valid(host->ncfg->wp_gpio)) 321 - gpio_set_value(host->ncfg->wp_gpio, 1); 321 + if (host->wp_gpio) 322 + gpiod_set_value_cansleep(host->wp_gpio, 0); 322 323 } 323 324 324 325 /* ··· 763 764 return NULL; 764 765 } 765 766 766 - ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0); 767 - 768 767 return ncfg; 769 768 } 770 769 ··· 849 852 "Missing or bad NAND config from device tree\n"); 850 853 return -ENOENT; 851 854 } 852 - if (host->ncfg->wp_gpio == -EPROBE_DEFER) 853 - return -EPROBE_DEFER; 854 - if (gpio_is_valid(host->ncfg->wp_gpio) && devm_gpio_request(&pdev->dev, 855 - host->ncfg->wp_gpio, "NAND WP")) { 856 - dev_err(&pdev->dev, "GPIO not available\n"); 857 - return -EBUSY; 855 + 856 + /* Start with WP disabled, if available */ 857 + host->wp_gpio = gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW); 858 + res = PTR_ERR_OR_ZERO(host->wp_gpio); 859 + if (res) { 860 + if (res != -EPROBE_DEFER) 861 + dev_err(&pdev->dev, "WP GPIO is not available: %d\n", 862 + res); 863 + return res; 858 864 } 859 - lpc32xx_wp_disable(host); 865 + 866 + gpiod_set_consumer_name(host->wp_gpio, "NAND WP"); 860 867 861 868 host->pdata = dev_get_platdata(&pdev->dev); 862 869 ··· 969 968 return 0; 970 969 } 971 970 972 - #ifdef CONFIG_PM 973 971 static int lpc32xx_nand_resume(struct platform_device *pdev) 974 972 { 975 973 struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); ··· 1007 1007 return 0; 1008 1008 } 1009 1009 1010 - #else 1011 - #define lpc32xx_nand_resume NULL 1012 - #define lpc32xx_nand_suspend NULL 1013 - #endif 1014 - 1015 1010 static const struct of_device_id lpc32xx_nand_match[] = { 1016 1011 { .compatible = "nxp,lpc3220-slc" }, 1017 1012 { /* sentinel */ }, ··· 1016 1021 static struct platform_driver lpc32xx_nand_driver = { 1017 1022 .probe = lpc32xx_nand_probe, 1018 1023 .remove = lpc32xx_nand_remove, 1019 - .resume = lpc32xx_nand_resume, 1020 - .suspend = lpc32xx_nand_suspend, 1024 + .resume = pm_ptr(lpc32xx_nand_resume), 1025 + .suspend = pm_ptr(lpc32xx_nand_suspend), 1021 1026 .driver = { 1022 1027 .name = LPC32XX_MODNAME, 1023 1028 .of_match_table = lpc32xx_nand_match,
+3 -1
drivers/mtd/nand/raw/marvell_nand.c
··· 114 114 #define GENCONF_SOC_DEVICE_MUX_ECC_CLK_RST BIT(20) 115 115 #define GENCONF_SOC_DEVICE_MUX_ECC_CORE_RST BIT(21) 116 116 #define GENCONF_SOC_DEVICE_MUX_NFC_INT_EN BIT(25) 117 + #define GENCONF_SOC_DEVICE_MUX_NFC_DEVBUS_ARB_EN BIT(27) 117 118 #define GENCONF_CLK_GATING_CTRL 0x220 118 119 #define GENCONF_CLK_GATING_CTRL_ND_GATE BIT(2) 119 120 #define GENCONF_ND_CLK_CTRL 0x700 ··· 2881 2880 GENCONF_SOC_DEVICE_MUX_NFC_EN | 2882 2881 GENCONF_SOC_DEVICE_MUX_ECC_CLK_RST | 2883 2882 GENCONF_SOC_DEVICE_MUX_ECC_CORE_RST | 2884 - GENCONF_SOC_DEVICE_MUX_NFC_INT_EN); 2883 + GENCONF_SOC_DEVICE_MUX_NFC_INT_EN | 2884 + GENCONF_SOC_DEVICE_MUX_NFC_DEVBUS_ARB_EN); 2885 2885 2886 2886 regmap_update_bits(sysctrl_base, GENCONF_CLK_GATING_CTRL, 2887 2887 GENCONF_CLK_GATING_CTRL_ND_GATE,
+1 -1
drivers/mtd/nand/raw/mpc5121_nfc.c
··· 663 663 } 664 664 665 665 prv->irq = irq_of_parse_and_map(dn, 0); 666 - if (prv->irq == NO_IRQ) { 666 + if (!prv->irq) { 667 667 dev_err(dev, "Error mapping IRQ!\n"); 668 668 return -EINVAL; 669 669 }
+77 -2
drivers/mtd/nand/spi/winbond.c
··· 74 74 return spi_mem_exec_op(spinand->spimem, &op); 75 75 } 76 76 77 + static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section, 78 + struct mtd_oob_region *region) 79 + { 80 + if (section > 3) 81 + return -ERANGE; 82 + 83 + region->offset = 64 + (16 * section); 84 + region->length = 13; 85 + 86 + return 0; 87 + } 88 + 89 + static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section, 90 + struct mtd_oob_region *region) 91 + { 92 + if (section > 3) 93 + return -ERANGE; 94 + 95 + region->offset = (16 * section) + 2; 96 + region->length = 14; 97 + 98 + return 0; 99 + } 100 + 101 + static const struct mtd_ooblayout_ops w25n02kv_ooblayout = { 102 + .ecc = w25n02kv_ooblayout_ecc, 103 + .free = w25n02kv_ooblayout_free, 104 + }; 105 + 106 + static int w25n02kv_ecc_get_status(struct spinand_device *spinand, 107 + u8 status) 108 + { 109 + struct nand_device *nand = spinand_to_nand(spinand); 110 + u8 mbf = 0; 111 + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); 112 + 113 + switch (status & STATUS_ECC_MASK) { 114 + case STATUS_ECC_NO_BITFLIPS: 115 + return 0; 116 + 117 + case STATUS_ECC_UNCOR_ERROR: 118 + return -EBADMSG; 119 + 120 + case STATUS_ECC_HAS_BITFLIPS: 121 + /* 122 + * Let's try to retrieve the real maximum number of bitflips 123 + * in order to avoid forcing the wear-leveling layer to move 124 + * data around if it's not necessary. 125 + */ 126 + if (spi_mem_exec_op(spinand->spimem, &op)) 127 + return nanddev_get_ecc_conf(nand)->strength; 128 + 129 + mbf >>= 4; 130 + 131 + if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) 132 + return nanddev_get_ecc_conf(nand)->strength; 133 + 134 + return mbf; 135 + 136 + default: 137 + break; 138 + } 139 + 140 + return -EINVAL; 141 + } 142 + 77 143 static const struct spinand_info winbond_spinand_table[] = { 78 144 SPINAND_INFO("W25M02GV", 79 - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab), 145 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), 80 146 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), 81 147 NAND_ECCREQ(1, 512), 82 148 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ··· 152 86 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), 153 87 SPINAND_SELECT_TARGET(w25m02gv_select_target)), 154 88 SPINAND_INFO("W25N01GV", 155 - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa), 89 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21), 156 90 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 157 91 NAND_ECCREQ(1, 512), 158 92 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ··· 160 94 &update_cache_variants), 161 95 0, 162 96 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), 97 + SPINAND_INFO("W25N02KV", 98 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22), 99 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 100 + NAND_ECCREQ(8, 512), 101 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 102 + &write_cache_variants, 103 + &update_cache_variants), 104 + 0, 105 + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), 163 106 }; 164 107 165 108 static int winbond_spinand_init(struct spinand_device *spinand)
+17 -2
drivers/mtd/parsers/Kconfig
··· 22 22 23 23 config MTD_BRCM_U_BOOT 24 24 tristate "Broadcom's U-Boot partition parser" 25 - depends on ARCH_BCM4908 || COMPILE_TEST 25 + depends on ARCH_BCMBCA || COMPILE_TEST 26 26 help 27 27 Broadcom uses a custom way of storing U-Boot environment variables. 28 28 They are placed inside U-Boot partition itself at unspecified offset. ··· 75 75 This provides a open firmware device tree partition parser 76 76 which derives the partition map from the children of the 77 77 flash memory node, as described in 78 - Documentation/devicetree/bindings/mtd/partition.txt. 78 + Documentation/devicetree/bindings/mtd/mtd.yaml. 79 79 80 80 config MTD_OF_PARTS_BCM4908 81 81 bool "BCM4908 partitioning support" ··· 122 122 You will still need the parsing functions to be called by the driver 123 123 for your particular device. It won't happen automatically. The 124 124 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. 125 + 126 + config MTD_PARSER_TPLINK_SAFELOADER 127 + tristate "TP-Link Safeloader partitions parser" 128 + depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) 129 + help 130 + TP-Link home routers use flash partitions to store various data. Info 131 + about flash space layout is stored in a partitions table using a 132 + custom ASCII-based format. 133 + 134 + That format was first found in devices with SafeLoader bootloader and 135 + was named after it. Later it was adapted to CFE and U-Boot 136 + bootloaders. 137 + 138 + This driver reads partitions table, parses it and creates MTD 139 + partitions. 125 140 126 141 config MTD_PARSER_TRX 127 142 tristate "Parser for TRX format partitions"
+1
drivers/mtd/parsers/Makefile
··· 10 10 ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o 11 11 obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o 12 12 obj-$(CONFIG_MTD_AFS_PARTS) += afs.o 13 + obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o 13 14 obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o 14 15 obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o 15 16 obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
+80 -5
drivers/mtd/spi-nor/core.c
··· 1184 1184 continue; 1185 1185 1186 1186 erase = &map->erase_type[i]; 1187 + if (!erase->size) 1188 + continue; 1187 1189 1188 1190 /* Alignment is not mandatory for overlaid regions */ 1189 1191 if (region->offset & SNOR_OVERLAID_REGION && ··· 1634 1632 &spi_nor_xmc, 1635 1633 }; 1636 1634 1635 + static const struct flash_info spi_nor_generic_flash = { 1636 + .name = "spi-nor-generic", 1637 + /* 1638 + * JESD216 rev A doesn't specify the page size, therefore we need a 1639 + * sane default. 1640 + */ 1641 + .page_size = 256, 1642 + .parse_sfdp = true, 1643 + }; 1644 + 1637 1645 static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, 1638 1646 const u8 *id) 1639 1647 { ··· 1676 1664 return ERR_PTR(ret); 1677 1665 } 1678 1666 1667 + /* Cache the complete flash ID. */ 1668 + nor->id = devm_kmemdup(nor->dev, id, SPI_NOR_MAX_ID_LEN, GFP_KERNEL); 1669 + if (!nor->id) 1670 + return ERR_PTR(-ENOMEM); 1671 + 1679 1672 info = spi_nor_match_id(nor, id); 1673 + 1674 + /* Fallback to a generic flash described only by its SFDP data. */ 1675 + if (!info) { 1676 + ret = spi_nor_check_sfdp_signature(nor); 1677 + if (!ret) 1678 + info = &spi_nor_generic_flash; 1679 + } 1680 + 1680 1681 if (!info) { 1681 1682 dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", 1682 1683 SPI_NOR_MAX_ID_LEN, id); ··· 1939 1914 spi_nor_spimem_setup_op(nor, &op, read->proto); 1940 1915 1941 1916 /* convert the dummy cycles to the number of bytes */ 1942 - op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8; 1917 + op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) * 1918 + op.dummy.buswidth / 8; 1943 1919 if (spi_nor_protocol_is_dtr(nor->read_proto)) 1944 1920 op.dummy.nbytes *= 2; 1945 1921 ··· 2117 2091 * spi_nor_select_uniform_erase() - select optimum uniform erase type 2118 2092 * @map: the erase map of the SPI NOR 2119 2093 * @wanted_size: the erase type size to search for. Contains the value of 2120 - * info->sector_size or of the "small sector" size in case 2121 - * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined. 2094 + * info->sector_size, the "small sector" size in case 2095 + * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if 2096 + * there is no information about the sector size. The 2097 + * latter is the case if the flash parameters are parsed 2098 + * solely by SFDP, then the largest supported erase type 2099 + * is selected. 2122 2100 * 2123 2101 * Once the optimum uniform sector erase command is found, disable all the 2124 2102 * other. ··· 2142 2112 continue; 2143 2113 2144 2114 tested_erase = &map->erase_type[i]; 2115 + 2116 + /* Skip masked erase types. */ 2117 + if (!tested_erase->size) 2118 + continue; 2145 2119 2146 2120 /* 2147 2121 * If the current erase size is the one, stop here: ··· 2599 2565 params->hwcaps.mask |= SNOR_HWCAPS_PP; 2600 2566 spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP], 2601 2567 SPINOR_OP_PP, SNOR_PROTO_1_1_1); 2568 + 2569 + if (info->flags & SPI_NOR_QUAD_PP) { 2570 + params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4; 2571 + spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4], 2572 + SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4); 2573 + } 2602 2574 } 2603 2575 2604 2576 /** ··· 2880 2840 2881 2841 void spi_nor_restore(struct spi_nor *nor) 2882 2842 { 2843 + int ret; 2844 + 2883 2845 /* restore the addressing mode */ 2884 2846 if (nor->addr_nbytes == 4 && !(nor->flags & SNOR_F_4B_OPCODES) && 2885 - nor->flags & SNOR_F_BROKEN_RESET) 2886 - nor->params->set_4byte_addr_mode(nor, false); 2847 + nor->flags & SNOR_F_BROKEN_RESET) { 2848 + ret = nor->params->set_4byte_addr_mode(nor, false); 2849 + if (ret) 2850 + /* 2851 + * Do not stop the execution in the hope that the flash 2852 + * will default to the 3-byte address mode after the 2853 + * software reset. 2854 + */ 2855 + dev_err(nor->dev, "Failed to exit 4-byte address mode, err = %d\n", ret); 2856 + } 2887 2857 2888 2858 if (nor->flags & SNOR_F_SOFT_RESET) 2889 2859 spi_nor_soft_reset(nor); ··· 2985 2935 mtd->_put_device = spi_nor_put_device; 2986 2936 } 2987 2937 2938 + static int spi_nor_hw_reset(struct spi_nor *nor) 2939 + { 2940 + struct gpio_desc *reset; 2941 + 2942 + reset = devm_gpiod_get_optional(nor->dev, "reset", GPIOD_OUT_LOW); 2943 + if (IS_ERR_OR_NULL(reset)) 2944 + return PTR_ERR_OR_ZERO(reset); 2945 + 2946 + /* 2947 + * Experimental delay values by looking at different flash device 2948 + * vendors datasheets. 2949 + */ 2950 + usleep_range(1, 5); 2951 + gpiod_set_value_cansleep(reset, 1); 2952 + usleep_range(100, 150); 2953 + gpiod_set_value_cansleep(reset, 0); 2954 + usleep_range(1000, 1200); 2955 + 2956 + return 0; 2957 + } 2958 + 2988 2959 int spi_nor_scan(struct spi_nor *nor, const char *name, 2989 2960 const struct spi_nor_hwcaps *hwcaps) 2990 2961 { ··· 3037 2966 GFP_KERNEL); 3038 2967 if (!nor->bouncebuf) 3039 2968 return -ENOMEM; 2969 + 2970 + ret = spi_nor_hw_reset(nor); 2971 + if (ret) 2972 + return ret; 3040 2973 3041 2974 info = spi_nor_get_flash_info(nor, name); 3042 2975 if (IS_ERR(info))
+5
drivers/mtd/spi-nor/core.h
··· 458 458 * SPI_NOR_NO_ERASE: no erase command needed. 459 459 * NO_CHIP_ERASE: chip does not support chip erase. 460 460 * SPI_NOR_NO_FR: can't do fastread. 461 + * SPI_NOR_QUAD_PP: flash supports Quad Input Page Program. 461 462 * 462 463 * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. 463 464 * Used when SFDP tables are not defined in the flash. These ··· 508 507 #define SPI_NOR_NO_ERASE BIT(6) 509 508 #define NO_CHIP_ERASE BIT(7) 510 509 #define SPI_NOR_NO_FR BIT(8) 510 + #define SPI_NOR_QUAD_PP BIT(9) 511 511 512 512 u8 no_sfdp_flags; 513 513 #define SPI_NOR_SKIP_SFDP BIT(0) ··· 702 700 u8 *buf, size_t len); 703 701 int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, 704 702 const u8 *buf, size_t len); 703 + 704 + int spi_nor_check_sfdp_signature(struct spi_nor *nor); 705 + int spi_nor_parse_sfdp(struct spi_nor *nor); 705 706 706 707 static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) 707 708 {
+1 -1
drivers/mtd/spi-nor/debugfs.c
··· 81 81 int i; 82 82 83 83 seq_printf(s, "name\t\t%s\n", info->name); 84 - seq_printf(s, "id\t\t%*ph\n", info->id_len, info->id); 84 + seq_printf(s, "id\t\t%*ph\n", SPI_NOR_MAX_ID_LEN, nor->id); 85 85 string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf)); 86 86 seq_printf(s, "size\t\t%s\n", buf); 87 87 seq_printf(s, "write size\t%u\n", params->writesize);
+17 -7
drivers/mtd/spi-nor/gigadevice.c
··· 8 8 9 9 #include "core.h" 10 10 11 - static void gd25q256_default_init(struct spi_nor *nor) 11 + static int 12 + gd25q256_post_bfpt(struct spi_nor *nor, 13 + const struct sfdp_parameter_header *bfpt_header, 14 + const struct sfdp_bfpt *bfpt) 12 15 { 13 16 /* 14 - * Some manufacturer like GigaDevice may use different 15 - * bit to set QE on different memories, so the MFR can't 16 - * indicate the quad_enable method for this case, we need 17 - * to set it in the default_init fixup hook. 17 + * GD25Q256C supports the first version of JESD216 which does not define 18 + * the Quad Enable methods. Overwrite the default Quad Enable method. 19 + * 20 + * GD25Q256 GENERATION | SFDP MAJOR VERSION | SFDP MINOR VERSION 21 + * GD25Q256C | SFDP_JESD216_MAJOR | SFDP_JESD216_MINOR 22 + * GD25Q256D | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR 23 + * GD25Q256E | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR 18 24 */ 19 - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; 25 + if (bfpt_header->major == SFDP_JESD216_MAJOR && 26 + bfpt_header->minor == SFDP_JESD216_MINOR) 27 + nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; 28 + 29 + return 0; 20 30 } 21 31 22 32 static const struct spi_nor_fixups gd25q256_fixups = { 23 - .default_init = gd25q256_default_init, 33 + .post_bfpt = gd25q256_post_bfpt, 24 34 }; 25 35 26 36 static const struct flash_info gigadevice_nor_parts[] = {
+3 -2
drivers/mtd/spi-nor/issi.c
··· 70 70 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 71 71 { "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256) 72 72 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 73 - { "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512) 74 - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 73 + { "is25wp256", INFO(0x9d7019, 0, 0, 0) 74 + PARSE_SFDP 75 75 FIXUP_FLAGS(SPI_NOR_4B_OPCODES) 76 + FLAGS(SPI_NOR_QUAD_PP) 76 77 .fixups = &is25lp256_fixups }, 77 78 78 79 /* PMC */
+9 -3
drivers/mtd/spi-nor/micron-st.c
··· 52 52 struct spi_mem_op op; 53 53 u8 *buf = nor->bouncebuf; 54 54 int ret; 55 + u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; 55 56 56 57 /* Use 20 dummy cycles for memory array reads. */ 57 58 *buf = 20; 58 59 op = (struct spi_mem_op) 59 - MICRON_ST_NOR_WR_ANY_REG_OP(3, SPINOR_REG_MT_CFR1V, 1, buf); 60 + MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 61 + SPINOR_REG_MT_CFR1V, 1, buf); 60 62 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 61 63 if (ret) 62 64 return ret; 63 65 64 66 buf[0] = SPINOR_MT_OCT_DTR; 65 67 op = (struct spi_mem_op) 66 - MICRON_ST_NOR_WR_ANY_REG_OP(3, SPINOR_REG_MT_CFR0V, 1, buf); 68 + MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 69 + SPINOR_REG_MT_CFR0V, 1, buf); 67 70 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 68 71 if (ret) 69 72 return ret; ··· 101 98 buf[0] = SPINOR_MT_EXSPI; 102 99 buf[1] = SPINOR_REG_MT_CFR1V_DEF; 103 100 op = (struct spi_mem_op) 104 - MICRON_ST_NOR_WR_ANY_REG_OP(4, SPINOR_REG_MT_CFR0V, 2, buf); 101 + MICRON_ST_NOR_WR_ANY_REG_OP(nor->addr_nbytes, 102 + SPINOR_REG_MT_CFR0V, 2, buf); 105 103 ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); 106 104 if (ret) 107 105 return ret; ··· 205 201 MFR_FLAGS(USE_FSR) 206 202 }, 207 203 { "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512) 204 + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 205 + SPI_NOR_BP3_SR_BIT6) 208 206 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 209 207 FIXUP_FLAGS(SPI_NOR_4B_OPCODES) 210 208 MFR_FLAGS(USE_FSR)
+35 -2
drivers/mtd/spi-nor/sfdp.c
··· 135 135 /** 136 136 * spi_nor_read_raw() - raw read of serial flash memory. read_opcode, 137 137 * addr_nbytes and read_dummy members of the struct spi_nor 138 - * should be previously 139 - * set. 138 + * should be previously set. 140 139 * @nor: pointer to a 'struct spi_nor' 141 140 * @addr: offset in the serial flash memory 142 141 * @len: number of bytes to read ··· 1182 1183 dummy = round_up(dummy, 2); 1183 1184 1184 1185 /* Update the fast read settings. */ 1186 + nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR; 1185 1187 spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8_DTR], 1186 1188 0, dummy, opcode, 1187 1189 SNOR_PROTO_8_8_8_DTR); 1190 + 1191 + /* 1192 + * Page Program is "Required Command" in the xSPI Profile 1.0. Update 1193 + * the params->hwcaps.mask here. 1194 + */ 1195 + nor->params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR; 1188 1196 1189 1197 out: 1190 1198 kfree(dwords); ··· 1253 1247 1254 1248 if (nor->info->fixups && nor->info->fixups->post_sfdp) 1255 1249 nor->info->fixups->post_sfdp(nor); 1250 + } 1251 + 1252 + /** 1253 + * spi_nor_check_sfdp_signature() - check for a valid SFDP signature 1254 + * @nor: pointer to a 'struct spi_nor' 1255 + * 1256 + * Used to detect if the flash supports the RDSFDP command as well as the 1257 + * presence of a valid SFDP table. 1258 + * 1259 + * Return: 0 on success, -errno otherwise. 1260 + */ 1261 + int spi_nor_check_sfdp_signature(struct spi_nor *nor) 1262 + { 1263 + u32 signature; 1264 + int err; 1265 + 1266 + /* Get the SFDP header. */ 1267 + err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(signature), 1268 + &signature); 1269 + if (err < 0) 1270 + return err; 1271 + 1272 + /* Check the SFDP signature. */ 1273 + if (le32_to_cpu(signature) != SFDP_SIGNATURE) 1274 + return -EINVAL; 1275 + 1276 + return 0; 1256 1277 } 1257 1278 1258 1279 /**
-2
drivers/mtd/spi-nor/sfdp.h
··· 107 107 u8 id_msb; 108 108 }; 109 109 110 - int spi_nor_parse_sfdp(struct spi_nor *nor); 111 - 112 110 #endif /* __LINUX_MTD_SFDP_H */
+39 -22
drivers/mtd/spi-nor/spansion.c
··· 49 49 struct spi_mem_op op; 50 50 u8 *buf = nor->bouncebuf; 51 51 int ret; 52 + u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; 52 53 53 54 /* Use 24 dummy cycles for memory array reads. */ 54 55 *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24; 55 56 op = (struct spi_mem_op) 56 - CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR2V, 1, buf); 57 + CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 58 + SPINOR_REG_CYPRESS_CFR2V, 1, buf); 57 59 58 60 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 59 61 if (ret) ··· 66 64 /* Set the octal and DTR enable bits. */ 67 65 buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN; 68 66 op = (struct spi_mem_op) 69 - CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR5V, 1, buf); 67 + CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 68 + SPINOR_REG_CYPRESS_CFR5V, 1, buf); 70 69 71 70 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 72 71 if (ret) 73 72 return ret; 74 73 75 74 /* Read flash ID to make sure the switch was successful. */ 76 - ret = spi_nor_read_id(nor, 4, 3, buf, SNOR_PROTO_8_8_8_DTR); 75 + ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf, 76 + SNOR_PROTO_8_8_8_DTR); 77 77 if (ret) { 78 78 dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret); 79 79 return ret; ··· 101 97 buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS; 102 98 buf[1] = 0; 103 99 op = (struct spi_mem_op) 104 - CYPRESS_NOR_WR_ANY_REG_OP(4, SPINOR_REG_CYPRESS_CFR5V, 2, buf); 100 + CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, 101 + SPINOR_REG_CYPRESS_CFR5V, 2, buf); 105 102 ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); 106 103 if (ret) 107 104 return ret; ··· 196 191 static int cypress_nor_set_page_size(struct spi_nor *nor) 197 192 { 198 193 struct spi_mem_op op = 199 - CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR3V, 194 + CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes, 195 + SPINOR_REG_CYPRESS_CFR3V, 200 196 nor->bouncebuf); 201 197 int ret; 202 198 ··· 281 275 cypress_nor_octal_dtr_dis(nor); 282 276 } 283 277 284 - static void s28hs512t_default_init(struct spi_nor *nor) 285 - { 286 - nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; 287 - nor->params->writesize = 16; 288 - } 289 - 290 - static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor) 278 + static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor) 291 279 { 292 280 /* 293 281 * On older versions of the flash the xSPI Profile 1.0 table has the ··· 309 309 nor->params->rdsr_addr_nbytes = 4; 310 310 } 311 311 312 - static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor, 313 - const struct sfdp_parameter_header *bfpt_header, 314 - const struct sfdp_bfpt *bfpt) 312 + static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor, 313 + const struct sfdp_parameter_header *bfpt_header, 314 + const struct sfdp_bfpt *bfpt) 315 315 { 316 316 return cypress_nor_set_page_size(nor); 317 317 } 318 318 319 - static const struct spi_nor_fixups s28hs512t_fixups = { 320 - .default_init = s28hs512t_default_init, 321 - .post_sfdp = s28hs512t_post_sfdp_fixup, 322 - .post_bfpt = s28hs512t_post_bfpt_fixup, 319 + static void s28hx_t_late_init(struct spi_nor *nor) 320 + { 321 + nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; 322 + nor->params->writesize = 16; 323 + } 324 + 325 + static const struct spi_nor_fixups s28hx_t_fixups = { 326 + .post_sfdp = s28hx_t_post_sfdp_fixup, 327 + .post_bfpt = s28hx_t_post_bfpt_fixup, 328 + .late_init = s28hx_t_late_init, 323 329 }; 324 330 325 331 static int ··· 459 453 .fixups = &s25hx_t_fixups }, 460 454 { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1) 461 455 FLAGS(SPI_NOR_NO_ERASE) }, 456 + { "s28hl512t", INFO(0x345a1a, 0, 256 * 1024, 256) 457 + PARSE_SFDP 458 + .fixups = &s28hx_t_fixups, 459 + }, 460 + { "s28hl01gt", INFO(0x345a1b, 0, 256 * 1024, 512) 461 + PARSE_SFDP 462 + .fixups = &s28hx_t_fixups, 463 + }, 462 464 { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256) 463 - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_DTR_READ | 464 - SPI_NOR_OCTAL_DTR_PP) 465 - .fixups = &s28hs512t_fixups, 465 + PARSE_SFDP 466 + .fixups = &s28hx_t_fixups, 467 + }, 468 + { "s28hs01gt", INFO(0x345b1b, 0, 256 * 1024, 512) 469 + PARSE_SFDP 470 + .fixups = &s28hx_t_fixups, 466 471 }, 467 472 }; 468 473
+19 -1
drivers/mtd/spi-nor/sysfs.c
··· 35 35 struct spi_device *spi = to_spi_device(dev); 36 36 struct spi_mem *spimem = spi_get_drvdata(spi); 37 37 struct spi_nor *nor = spi_mem_get_drvdata(spimem); 38 + const u8 *id = nor->info->id_len ? nor->info->id : nor->id; 39 + u8 id_len = nor->info->id_len ?: SPI_NOR_MAX_ID_LEN; 38 40 39 - return sysfs_emit(buf, "%*phN\n", nor->info->id_len, nor->info->id); 41 + return sysfs_emit(buf, "%*phN\n", id_len, id); 40 42 } 41 43 static DEVICE_ATTR_RO(jedec_id); 42 44 ··· 69 67 NULL 70 68 }; 71 69 70 + static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj, 71 + struct attribute *attr, int n) 72 + { 73 + struct spi_device *spi = to_spi_device(kobj_to_dev(kobj)); 74 + struct spi_mem *spimem = spi_get_drvdata(spi); 75 + struct spi_nor *nor = spi_mem_get_drvdata(spimem); 76 + 77 + if (attr == &dev_attr_manufacturer.attr && !nor->manufacturer) 78 + return 0; 79 + if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len && !nor->id) 80 + return 0; 81 + 82 + return 0444; 83 + } 84 + 72 85 static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj, 73 86 struct bin_attribute *attr, int n) 74 87 { ··· 99 82 100 83 static const struct attribute_group spi_nor_sysfs_group = { 101 84 .name = "spi-nor", 85 + .is_visible = spi_nor_sysfs_is_visible, 102 86 .is_bin_visible = spi_nor_sysfs_is_bin_visible, 103 87 .attrs = spi_nor_sysfs_entries, 104 88 .bin_attrs = spi_nor_sysfs_bin_entries,
+3
drivers/mtd/spi-nor/winbond.c
··· 133 133 { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024) 134 134 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ | 135 135 SPI_NOR_DUAL_READ) }, 136 + { "w25q512nwq", INFO(0xef6020, 0, 0, 0) 137 + PARSE_SFDP 138 + OTP_INFO(256, 3, 0x1000, 0x1000) }, 136 139 { "w25q512nwm", INFO(0xef8020, 0, 64 * 1024, 1024) 137 140 PARSE_SFDP 138 141 OTP_INFO(256, 3, 0x1000, 0x1000) },
-1
include/linux/mtd/nand.h
··· 999 999 1000 1000 bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos); 1001 1001 bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos); 1002 - int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos); 1003 1002 int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos); 1004 1003 1005 1004 /* ECC related functions */
+3
include/linux/mtd/spi-nor.h
··· 349 349 * @bouncebuf: bounce buffer used when the buffer passed by the MTD 350 350 * layer is not DMA-able 351 351 * @bouncebuf_size: size of the bounce buffer 352 + * @id: The flash's ID bytes. Always contains 353 + * SPI_NOR_MAX_ID_LEN bytes. 352 354 * @info: SPI NOR part JEDEC MFR ID and other info 353 355 * @manufacturer: SPI NOR manufacturer 354 356 * @addr_nbytes: number of address bytes ··· 381 379 struct spi_mem *spimem; 382 380 u8 *bouncebuf; 383 381 size_t bouncebuf_size; 382 + u8 *id; 384 383 const struct flash_info *info; 385 384 const struct spi_nor_manufacturer *manufacturer; 386 385 u8 addr_nbytes;