History

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

Pull MTD updates from Miquel Raynal: "MTD core - block2mtd: page index should use pgoff_t - maps: physmap: minimal Runtime PM support - maps: pcmciamtd: avoid possible sleep-in-atomic-context bugs - concat: Fix a comment referring to an unknown symbol Raw NAND: - Macronix: Use match_string() helper - Atmel: switch to using devm_fwnode_gpiod_get() - Denali: rework the SKIP_BYTES feature and add reset controlling - Brcmnand: set appropriate DMA mask - Cadence: add unspecified HAS_IOMEM dependency - Various cleanup. Onenand: - Rename Samsung and Omap2 drivers to avoid possible build warnings - Enable compile testing - Various build issues - Kconfig cleanup SPI-NAND: - Support for Toshiba TC58CVG2S0HRAIJ SPI-NOR: - Add support for TB selection using SR bit 6, - Add support for few flashes" * tag 'mtd/for-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (41 commits) mtd: concat: Fix a comment referring to an unknown symbol mtd: rawnand: add unspecified HAS_IOMEM dependency mtd: block2mtd: page index should use pgoff_t mtd: maps: physmap: Add minimal Runtime PM support mtd: maps: pcmciamtd: fix possible sleep-in-atomic-context bugs in pcmciamtd_set_vpp() mtd: onenand: Rename omap2 driver to avoid a build warning mtd: onenand: Use a better name for samsung driver mtd: rawnand: atmel: switch to using devm_fwnode_gpiod_get() mtd: spinand: add support for Toshiba TC58CVG2S0HRAIJ mtd: rawnand: macronix: Use match_string() helper to simplify the code mtd: sharpslpart: Fix unsigned comparison to zero mtd: onenand: Enable compile testing of OMAP and Samsung drivers mtd: onenand: samsung: Fix printing format for size_t on 64-bit mtd: onenand: samsung: Fix pointer cast -Wpointer-to-int-cast warnings on 64 bit mtd: rawnand: denali: remove hard-coded DENALI_DEFAULT_OOB_SKIP_BYTES mtd: rawnand: denali_dt: add reset controlling dt-bindings: mtd: denali_dt: document reset property mtd: rawnand: denali_dt: Add support for configuring SPARE_AREA_SKIP_BYTES mtd: rawnand: denali_dt: error out if platform has no associated data mtd: rawnand: brcmnand: Set appropriate DMA mask ...

Linus Torvalds committed 6 years ago

Commit 35c222f2 parents e84bcd6 457524326 files · +286 −162Browse files

Unified · Split

26 files
  1. Documentation/devicetree/bindings/mtd/denali-nand.txt +7 −0
  2. drivers/mtd/devices/block2mtd.c +4 −4
  3. drivers/mtd/maps/pcmciamtd.c +3 −4
  4. drivers/mtd/maps/physmap-core.c +15 −5
  5. drivers/mtd/mtdconcat.c +1 −4
  6. drivers/mtd/nand/onenand/Kconfig +7 −7
  7. drivers/mtd/nand/onenand/Makefile +2 −2
  8. drivers/mtd/nand/onenand/onenand_base.c +41 −41
  9. drivers/mtd/nand/onenand/onenand_omap2.c +0 −0
  10. drivers/mtd/nand/onenand/onenand_samsung.c +4 −5
  11. drivers/mtd/nand/raw/Kconfig +1 −1
  12. drivers/mtd/nand/raw/atmel/nand-controller.c +10 −10
  13. drivers/mtd/nand/raw/brcmnand/brcmnand.c +10 −0
  14. drivers/mtd/nand/raw/denali.c +7 −7
  15. drivers/mtd/nand/raw/denali_dt.c +50 −6
  16. drivers/mtd/nand/raw/mpc5121_nfc.c +1 −1
  17. drivers/mtd/nand/raw/nand_macronix.c +4 −7
  18. drivers/mtd/nand/spi/toshiba.c +10 −0
  19. drivers/mtd/parsers/sharpslpart.c +2 −2
  20. drivers/mtd/spi-nor/Kconfig +2 −2
  21. drivers/mtd/spi-nor/aspeed-smc.c +2 −2
  22. drivers/mtd/spi-nor/cadence-quadspi.c +2 −2
  23. drivers/mtd/spi-nor/hisi-sfc.c +3 −3
  24. drivers/mtd/spi-nor/intel-spi-pci.c +2 −0
  25. drivers/mtd/spi-nor/spi-nor.c +91 −36
  26. include/linux/mtd/spi-nor.h +5 −11
Documentation/devicetree/bindings/mtd/denali-nand.txt+7−0
@@ -14,6 +14,11 @@ Required properties: · 13 unmodified lines
14 interface clock, and the ECC circuit clock.14 interface clock, and the ECC circuit clock.
15 - clock-names: should contain "nand", "nand_x", "ecc"15 - clock-names: should contain "nand", "nand_x", "ecc"
16 16
17Optional properties:
18 - resets: may contain phandles to the controller core reset, the register
19 reset
20 - reset-names: may contain "nand", "reg"
21
17Sub-nodes:22Sub-nodes:
18 Sub-nodes represent available NAND chips.23 Sub-nodes represent available NAND chips.
19 24
@@ -46,6 +51,8 @@ nand: nand@ff900000 { · 26 unmodified lines
46 reg-names = "nand_data", "denali_reg";51 reg-names = "nand_data", "denali_reg";
47 clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>;52 clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>;
48 clock-names = "nand", "nand_x", "ecc";53 clock-names = "nand", "nand_x", "ecc";
54 resets = <&nand_rst>, <&nand_reg_rst>;
55 reset-names = "nand", "reg";
49 interrupts = <0 144 4>;56 interrupts = <0 144 4>;
50 57
51 nand@0 {58 nand@0 {
drivers/mtd/devices/block2mtd.c+4−4
@@ -44,7 +44,7 @@ struct block2mtd_dev { · 43 unmodified lines
44static LIST_HEAD(blkmtd_device_list);44static LIST_HEAD(blkmtd_device_list);
45 45
46 46
47static struct page *page_read(struct address_space *mapping, int index)47static struct page *page_read(struct address_space *mapping, pgoff_t index)
48{48{
49 return read_mapping_page(mapping, index, NULL);49 return read_mapping_page(mapping, index, NULL);
50}50}
@@ -54,7 +54,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) · 3 unmodified lines
54{54{
55 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;55 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
56 struct page *page;56 struct page *page;
57 int index = to >> PAGE_SHIFT; // page index57 pgoff_t index = to >> PAGE_SHIFT; // page index
58 int pages = len >> PAGE_SHIFT;58 int pages = len >> PAGE_SHIFT;
59 u_long *p;59 u_long *p;
60 u_long *max;60 u_long *max;
@@ -103,7 +103,7 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, · 42 unmodified lines
103{103{
104 struct block2mtd_dev *dev = mtd->priv;104 struct block2mtd_dev *dev = mtd->priv;
105 struct page *page;105 struct page *page;
106 int index = from >> PAGE_SHIFT;106 pgoff_t index = from >> PAGE_SHIFT;
107 int offset = from & (PAGE_SIZE-1);107 int offset = from & (PAGE_SIZE-1);
108 int cpylen;108 int cpylen;
109 109
@@ -137,7 +137,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, · 27 unmodified lines
137{137{
138 struct page *page;138 struct page *page;
139 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;139 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
140 int index = to >> PAGE_SHIFT; // page index140 pgoff_t index = to >> PAGE_SHIFT; // page index
141 int offset = to & ~PAGE_MASK; // page offset141 int offset = to & ~PAGE_MASK; // page offset
142 int cpylen;142 int cpylen;
143 143
drivers/mtd/maps/pcmciamtd.c+3−4
@@ -294,16 +294,15 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f · 293 unmodified lines
294}294}
295 295
296 296
297static DEFINE_SPINLOCK(pcmcia_vpp_lock);297static DEFINE_MUTEX(pcmcia_vpp_lock);
298static int pcmcia_vpp_refcnt;298static int pcmcia_vpp_refcnt;
299static void pcmciamtd_set_vpp(struct map_info *map, int on)299static void pcmciamtd_set_vpp(struct map_info *map, int on)
300{300{
301 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;301 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
302 struct pcmcia_device *link = dev->p_dev;302 struct pcmcia_device *link = dev->p_dev;
303 unsigned long flags;
304 303
305 pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);304 pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
306 spin_lock_irqsave(&pcmcia_vpp_lock, flags);305 mutex_lock(&pcmcia_vpp_lock);
307 if (on) {306 if (on) {
308 if (++pcmcia_vpp_refcnt == 1) /* first nested 'on' */307 if (++pcmcia_vpp_refcnt == 1) /* first nested 'on' */
309 pcmcia_fixup_vpp(link, dev->vpp);308 pcmcia_fixup_vpp(link, dev->vpp);
@@ -311,7 +310,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) · 1 unmodified line
311 if (--pcmcia_vpp_refcnt == 0) /* last nested 'off' */310 if (--pcmcia_vpp_refcnt == 0) /* last nested 'off' */
312 pcmcia_fixup_vpp(link, 0);311 pcmcia_fixup_vpp(link, 0);
313 }312 }
314 spin_unlock_irqrestore(&pcmcia_vpp_lock, flags);313 mutex_unlock(&pcmcia_vpp_lock);
315}314}
316 315
317 316
drivers/mtd/maps/physmap-core.c+15−5
@@ -38,6 +38,7 @@ · 37 unmodified lines
38#include <linux/mtd/cfi_endian.h>38#include <linux/mtd/cfi_endian.h>
39#include <linux/io.h>39#include <linux/io.h>
40#include <linux/of_device.h>40#include <linux/of_device.h>
41#include <linux/pm_runtime.h>
41#include <linux/gpio/consumer.h>42#include <linux/gpio/consumer.h>
42 43
43#include "physmap-gemini.h"44#include "physmap-gemini.h"
@@ -64,16 +65,16 @@ static int physmap_flash_remove(struct platform_device *dev) · 20 unmodified lines
64{65{
65 struct physmap_flash_info *info;66 struct physmap_flash_info *info;
66 struct physmap_flash_data *physmap_data;67 struct physmap_flash_data *physmap_data;
67 int i, err;68 int i, err = 0;
68 69
69 info = platform_get_drvdata(dev);70 info = platform_get_drvdata(dev);
70 if (!info)71 if (!info)
71 return 0;72 goto out;
72 73
73 if (info->cmtd) {74 if (info->cmtd) {
74 err = mtd_device_unregister(info->cmtd);75 err = mtd_device_unregister(info->cmtd);
75 if (err)76 if (err)
76 return err;77 goto out;
77 78
78 if (info->cmtd != info->mtds[0])79 if (info->cmtd != info->mtds[0])
79 mtd_concat_destroy(info->cmtd);80 mtd_concat_destroy(info->cmtd);
@@ -88,7 +89,10 @@ static int physmap_flash_remove(struct platform_device *dev) · 8 unmodified lines
88 if (physmap_data && physmap_data->exit)89 if (physmap_data && physmap_data->exit)
89 physmap_data->exit(dev);90 physmap_data->exit(dev);
90 91
91 return 0;92out:
93 pm_runtime_put(&dev->dev);
94 pm_runtime_disable(&dev->dev);
95 return err;
92}96}
93 97
94static void physmap_set_vpp(struct map_info *map, int state)98static void physmap_set_vpp(struct map_info *map, int state)
@@ -484,13 +488,19 @@ static int physmap_flash_probe(struct platform_device *dev) · 389 unmodified lines
484 return -EINVAL;488 return -EINVAL;
485 }489 }
486 490
491 pm_runtime_enable(&dev->dev);
492 pm_runtime_get_sync(&dev->dev);
493
487 if (dev->dev.of_node)494 if (dev->dev.of_node)
488 err = physmap_flash_of_init(dev);495 err = physmap_flash_of_init(dev);
489 else496 else
490 err = physmap_flash_pdata_init(dev);497 err = physmap_flash_pdata_init(dev);
491 498
492 if (err)499 if (err) {
500 pm_runtime_put(&dev->dev);
501 pm_runtime_disable(&dev->dev);
493 return err;502 return err;
503 }
494 504
495 for (i = 0; i < info->nmaps; i++) {505 for (i = 0; i < info->nmaps; i++) {
496 struct resource *res;506 struct resource *res;
drivers/mtd/mtdconcat.c+1−4
@@ -841,10 +841,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c · 840 unmodified lines
841 return &concat->mtd;841 return &concat->mtd;
842}842}
843 843
844/*844/* Cleans the context obtained from mtd_concat_create() */
845 * This function destroys an MTD object obtained from concat_mtd_devs()
846 */
847
848void mtd_concat_destroy(struct mtd_info *mtd)845void mtd_concat_destroy(struct mtd_info *mtd)
849{846{
850 struct mtd_concat *concat = CONCAT(mtd);847 struct mtd_concat *concat = CONCAT(mtd);
drivers/mtd/nand/onenand/Kconfig+7−7
@@ -25,7 +25,7 @@ config MTD_ONENAND_GENERIC · 24 unmodified lines
25 25
26config MTD_ONENAND_OMAP226config MTD_ONENAND_OMAP2
27 tristate "OneNAND on OMAP2/OMAP3 support"27 tristate "OneNAND on OMAP2/OMAP3 support"
28 depends on ARCH_OMAP2 || ARCH_OMAP328 depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && ARM)
29 depends on OF || COMPILE_TEST29 depends on OF || COMPILE_TEST
30 help30 help
31 Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC31 Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC
@@ -33,12 +33,12 @@ config MTD_ONENAND_OMAP2 · 1 unmodified line
33 Enable dmaengine and gpiolib for better performance.33 Enable dmaengine and gpiolib for better performance.
34 34
35config MTD_ONENAND_SAMSUNG35config MTD_ONENAND_SAMSUNG
36 tristate "OneNAND on Samsung SOC controller support"36 tristate "OneNAND on Samsung SOC controller support"
37 depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS437 depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS4 || COMPILE_TEST
38 help38 help
39 Support for a OneNAND flash device connected to an Samsung SOC.39 Support for a OneNAND flash device connected to an Samsung SOC.
40 S3C64XX uses command mapping method.40 S3C64XX uses command mapping method.
41 S5PC110/S5PC210 use generic OneNAND method.41 S5PC110/S5PC210 use generic OneNAND method.
42 42
43config MTD_ONENAND_OTP43config MTD_ONENAND_OTP
44 bool "OneNAND OTP Support"44 bool "OneNAND OTP Support"
drivers/mtd/nand/onenand/Makefile+2−2
@@ -8,7 +8,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o · 7 unmodified lines
8 8
9# Board specific.9# Board specific.
10obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o10obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
11obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o11obj-$(CONFIG_MTD_ONENAND_OMAP2) += onenand_omap2.o
12obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += samsung_mtd.o12obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += onenand_samsung.o
13 13
14onenand-objs = onenand_base.o onenand_bbt.o14onenand-objs = onenand_base.o onenand_bbt.o
drivers/mtd/nand/onenand/onenand_base.c+41−41
@@ -1248,44 +1248,44 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from, · 1247 unmodified lines
1248 1248
1249 stats = mtd->ecc_stats;1249 stats = mtd->ecc_stats;
1250 1250
1251 /* Read-while-load method */1251 /* Read-while-load method */
1252 1252
1253 /* Do first load to bufferRAM */1253 /* Do first load to bufferRAM */
1254 if (read < len) {1254 if (read < len) {
1255 if (!onenand_check_bufferram(mtd, from)) {1255 if (!onenand_check_bufferram(mtd, from)) {
1256 this->command(mtd, ONENAND_CMD_READ, from, writesize);1256 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1257 ret = this->wait(mtd, FL_READING);1257 ret = this->wait(mtd, FL_READING);
1258 onenand_update_bufferram(mtd, from, !ret);1258 onenand_update_bufferram(mtd, from, !ret);
1259 if (mtd_is_eccerr(ret))1259 if (mtd_is_eccerr(ret))
1260 ret = 0;1260 ret = 0;
1261 }1261 }
1262 }1262 }
1263 1263
1264 thislen = min_t(int, writesize, len - read);1264 thislen = min_t(int, writesize, len - read);
1265 column = from & (writesize - 1);1265 column = from & (writesize - 1);
1266 if (column + thislen > writesize)1266 if (column + thislen > writesize)
1267 thislen = writesize - column;1267 thislen = writesize - column;
1268 1268
1269 while (!ret) {1269 while (!ret) {
1270 /* If there is more to load then start next load */1270 /* If there is more to load then start next load */
1271 from += thislen;1271 from += thislen;
1272 if (read + thislen < len) {1272 if (read + thislen < len) {
1273 this->command(mtd, ONENAND_CMD_READ, from, writesize);1273 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1274 /*1274 /*
1275 * Chip boundary handling in DDP1275 * Chip boundary handling in DDP
1276 * Now we issued chip 1 read and pointed chip 11276 * Now we issued chip 1 read and pointed chip 1
1277 * bufferram so we have to point chip 0 bufferram.1277 * bufferram so we have to point chip 0 bufferram.
1278 */1278 */
1279 if (ONENAND_IS_DDP(this) &&1279 if (ONENAND_IS_DDP(this) &&
1280 unlikely(from == (this->chipsize >> 1))) {1280 unlikely(from == (this->chipsize >> 1))) {
1281 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);1281 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
1282 boundary = 1;1282 boundary = 1;
1283 } else1283 } else
1284 boundary = 0;1284 boundary = 0;
1285 ONENAND_SET_PREV_BUFFERRAM(this);1285 ONENAND_SET_PREV_BUFFERRAM(this);
1286 }1286 }
1287 /* While load is going, read from last bufferRAM */1287 /* While load is going, read from last bufferRAM */
1288 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);1288 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1289 1289
1290 /* Read oob area if needed */1290 /* Read oob area if needed */
1291 if (oobbuf) {1291 if (oobbuf) {
@@ -1301,24 +1301,24 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from, · 9 unmodified lines
1301 oobcolumn = 0;1301 oobcolumn = 0;
1302 }1302 }
1303 1303
1304 /* See if we are done */1304 /* See if we are done */
1305 read += thislen;1305 read += thislen;
1306 if (read == len)1306 if (read == len)
1307 break;1307 break;
1308 /* Set up for next read from bufferRAM */1308 /* Set up for next read from bufferRAM */
1309 if (unlikely(boundary))1309 if (unlikely(boundary))
1310 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);1310 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
1311 ONENAND_SET_NEXT_BUFFERRAM(this);1311 ONENAND_SET_NEXT_BUFFERRAM(this);
1312 buf += thislen;1312 buf += thislen;
1313 thislen = min_t(int, writesize, len - read);1313 thislen = min_t(int, writesize, len - read);
1314 column = 0;1314 column = 0;
1315 cond_resched();1315 cond_resched();
1316 /* Now wait for load */1316 /* Now wait for load */
1317 ret = this->wait(mtd, FL_READING);1317 ret = this->wait(mtd, FL_READING);
1318 onenand_update_bufferram(mtd, from, !ret);1318 onenand_update_bufferram(mtd, from, !ret);
1319 if (mtd_is_eccerr(ret))1319 if (mtd_is_eccerr(ret))
1320 ret = 0;1320 ret = 0;
1321 }1321 }
1322 1322
1323 /*1323 /*
1324 * Return success, if no ECC failures, else -EBADMSG1324 * Return success, if no ECC failures, else -EBADMSG
drivers/mtd/nand/onenand/onenand_omap2.crenamed from drivers/mtd/nand/onenand/omap2.c+0−0

File renamed without changes.

drivers/mtd/nand/onenand/onenand_samsung.crenamed from drivers/mtd/nand/onenand/samsung_mtd.c+4−5
@@ -248,7 +248,7 @@ static unsigned short s3c_onenand_readw(void __iomem *addr) · 247 unmodified lines
248 }248 }
249 249
250 /* BootRAM access control */250 /* BootRAM access control */
251 if ((unsigned int) addr < ONENAND_DATARAM && onenand->bootram_command) {251 if ((unsigned long)addr < ONENAND_DATARAM && onenand->bootram_command) {
252 if (word_addr == 0)252 if (word_addr == 0)
253 return s3c_read_reg(MANUFACT_ID_OFFSET);253 return s3c_read_reg(MANUFACT_ID_OFFSET);
254 if (word_addr == 1)254 if (word_addr == 1)
@@ -289,7 +289,7 @@ static void s3c_onenand_writew(unsigned short value, void __iomem *addr) · 34 unmodified lines
289 }289 }
290 290
291 /* BootRAM access control */291 /* BootRAM access control */
292 if ((unsigned int)addr < ONENAND_DATARAM) {292 if ((unsigned long)addr < ONENAND_DATARAM) {
293 if (value == ONENAND_CMD_READID) {293 if (value == ONENAND_CMD_READID) {
294 onenand->bootram_command = 1;294 onenand->bootram_command = 1;
295 return;295 return;
@@ -658,7 +658,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, · 362 unmodified lines
658 dma_dst = dma_map_single(dev, buf, count, DMA_FROM_DEVICE);658 dma_dst = dma_map_single(dev, buf, count, DMA_FROM_DEVICE);
659 }659 }
660 if (dma_mapping_error(dev, dma_dst)) {660 if (dma_mapping_error(dev, dma_dst)) {
661 dev_err(dev, "Couldn't map a %d byte buffer for DMA\n", count);661 dev_err(dev, "Couldn't map a %zu byte buffer for DMA\n", count);
662 goto normal;662 goto normal;
663 }663 }
664 err = s5pc110_dma_ops(dma_dst, dma_src,664 err = s5pc110_dma_ops(dma_dst, dma_src,
@@ -728,13 +728,12 @@ static void s3c_onenand_check_lock_status(struct mtd_info *mtd) · 63 unmodified lines
728 struct onenand_chip *this = mtd->priv;728 struct onenand_chip *this = mtd->priv;
729 struct device *dev = &onenand->pdev->dev;729 struct device *dev = &onenand->pdev->dev;
730 unsigned int block, end;730 unsigned int block, end;
731 int tmp;
732 731
733 end = this->chipsize >> this->erase_shift;732 end = this->chipsize >> this->erase_shift;
734 733
735 for (block = 0; block < end; block++) {734 for (block = 0; block < end; block++) {
736 unsigned int mem_addr = onenand->mem_addr(block, 0, 0);735 unsigned int mem_addr = onenand->mem_addr(block, 0, 0);
737 tmp = s3c_read_cmd(CMD_MAP_01(onenand, mem_addr));736 s3c_read_cmd(CMD_MAP_01(onenand, mem_addr));
738 737
739 if (s3c_read_reg(INT_ERR_STAT_OFFSET) & LOCKED_BLK) {738 if (s3c_read_reg(INT_ERR_STAT_OFFSET) & LOCKED_BLK) {
740 dev_err(dev, "block %d is write-protected!\n", block);739 dev_err(dev, "block %d is write-protected!\n", block);
drivers/mtd/nand/raw/Kconfig+1−1
@@ -452,7 +452,7 @@ config MTD_NAND_PLATFORM · 451 unmodified lines
452 452
453config MTD_NAND_CADENCE453config MTD_NAND_CADENCE
454 tristate "Support Cadence NAND (HPNFC) controller"454 tristate "Support Cadence NAND (HPNFC) controller"
455 depends on OF || COMPILE_TEST455 depends on (OF || COMPILE_TEST) && HAS_IOMEM
456 help456 help
457 Enable the driver for NAND flash on platforms using a Cadence NAND457 Enable the driver for NAND flash on platforms using a Cadence NAND
458 controller.458 controller.
drivers/mtd/nand/raw/atmel/nand-controller.c+10−10
@@ -1578,9 +1578,8 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc, · 1577 unmodified lines
1578 1578
1579 nand->numcs = numcs;1579 nand->numcs = numcs;
1580 1580
1581 gpio = devm_fwnode_get_index_gpiod_from_child(nc->dev, "det", 0,1581 gpio = devm_fwnode_gpiod_get(nc->dev, of_fwnode_handle(np),
1582 &np->fwnode, GPIOD_IN,1582 "det", GPIOD_IN, "nand-det");
1583 "nand-det");
1584 if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {1583 if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {
1585 dev_err(nc->dev,1584 dev_err(nc->dev,
1586 "Failed to get detect gpio (err = %ld)\n",1585 "Failed to get detect gpio (err = %ld)\n",
@@ -1624,9 +1623,10 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc, · 37 unmodified lines
1624 nand->cs[i].rb.type = ATMEL_NAND_NATIVE_RB;1623 nand->cs[i].rb.type = ATMEL_NAND_NATIVE_RB;
1625 nand->cs[i].rb.id = val;1624 nand->cs[i].rb.id = val;
1626 } else {1625 } else {
1627 gpio = devm_fwnode_get_index_gpiod_from_child(nc->dev,1626 gpio = devm_fwnode_gpiod_get_index(nc->dev,
1628 "rb", i, &np->fwnode,1627 of_fwnode_handle(np),
1629 GPIOD_IN, "nand-rb");1628 "rb", i, GPIOD_IN,
1629 "nand-rb");
1630 if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {1630 if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {
1631 dev_err(nc->dev,1631 dev_err(nc->dev,
1632 "Failed to get R/B gpio (err = %ld)\n",1632 "Failed to get R/B gpio (err = %ld)\n",
@@ -1640,10 +1640,10 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc, · 7 unmodified lines
1640 }1640 }
1641 }1641 }
1642 1642
1643 gpio = devm_fwnode_get_index_gpiod_from_child(nc->dev, "cs",1643 gpio = devm_fwnode_gpiod_get_index(nc->dev,
1644 i, &np->fwnode,1644 of_fwnode_handle(np),
1645 GPIOD_OUT_HIGH,1645 "cs", i, GPIOD_OUT_HIGH,
1646 "nand-cs");1646 "nand-cs");
1647 if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {1647 if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {
1648 dev_err(nc->dev,1648 dev_err(nc->dev,
1649 "Failed to get CS gpio (err = %ld)\n",1649 "Failed to get CS gpio (err = %ld)\n",
drivers/mtd/nand/raw/brcmnand/brcmnand.c+10−0
@@ -2635,6 +2635,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) · 2634 unmodified lines
2635 /* initialize the dma version */2635 /* initialize the dma version */
2636 brcmnand_flash_dma_revision_init(ctrl);2636 brcmnand_flash_dma_revision_init(ctrl);
2637 2637
2638 ret = -EIO;
2639 if (ctrl->nand_version >= 0x0700)
2640 ret = dma_set_mask_and_coherent(&pdev->dev,
2641 DMA_BIT_MASK(40));
2642 if (ret)
2643 ret = dma_set_mask_and_coherent(&pdev->dev,
2644 DMA_BIT_MASK(32));
2645 if (ret)
2646 goto err;
2647
2638 /* linked-list and stop on error */2648 /* linked-list and stop on error */
2639 flash_dma_writel(ctrl, FLASH_DMA_MODE, FLASH_DMA_MODE_MASK);2649 flash_dma_writel(ctrl, FLASH_DMA_MODE, FLASH_DMA_MODE_MASK);
2640 flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0);2650 flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0);
drivers/mtd/nand/raw/denali.c+7−7
@@ -21,7 +21,6 @@ · 20 unmodified lines
21#include "denali.h"21#include "denali.h"
22 22
23#define DENALI_NAND_NAME "denali-nand"23#define DENALI_NAND_NAME "denali-nand"
24#define DENALI_DEFAULT_OOB_SKIP_BYTES 8
25 24
26/* for Indexed Addressing */25/* for Indexed Addressing */
27#define DENALI_INDEXED_CTRL 0x0026#define DENALI_INDEXED_CTRL 0x00
@@ -1302,15 +1301,16 @@ int denali_init(struct denali_controller *denali) · 1274 unmodified lines
1302 1301
1303 /*1302 /*
1304 * Set how many bytes should be skipped before writing data in OOB.1303 * Set how many bytes should be skipped before writing data in OOB.
1305 * If a non-zero value has already been set (by firmware or something),1304 * If a platform requests a non-zero value, set it to the register.
1306 * just use it. Otherwise, set the driver's default.1305 * Otherwise, read the value out, expecting it has already been set up
1306 * by firmware.
1307 */1307 */
1308 denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES);1308 if (denali->oob_skip_bytes)
1309 if (!denali->oob_skip_bytes) {
1310 denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES;
1311 iowrite32(denali->oob_skip_bytes,1309 iowrite32(denali->oob_skip_bytes,
1312 denali->reg + SPARE_AREA_SKIP_BYTES);1310 denali->reg + SPARE_AREA_SKIP_BYTES);
1313 }1311 else
1312 denali->oob_skip_bytes = ioread32(denali->reg +
1313 SPARE_AREA_SKIP_BYTES);
1314 1314
1315 iowrite32(0, denali->reg + TRANSFER_SPARE_REG);1315 iowrite32(0, denali->reg + TRANSFER_SPARE_REG);
1316 iowrite32(GENMASK(denali->nbanks - 1, 0), denali->reg + RB_PIN_ENABLED);1316 iowrite32(GENMASK(denali->nbanks - 1, 0), denali->reg + RB_PIN_ENABLED);
drivers/mtd/nand/raw/denali_dt.c+50−6
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 */6 */
7 7
8#include <linux/clk.h>8#include <linux/clk.h>
9#include <linux/delay.h>
9#include <linux/err.h>10#include <linux/err.h>
10#include <linux/io.h>11#include <linux/io.h>
11#include <linux/ioport.h>12#include <linux/ioport.h>
@@ -14,6 +15,7 @@ · 2 unmodified lines
14#include <linux/of.h>15#include <linux/of.h>
15#include <linux/of_device.h>16#include <linux/of_device.h>
16#include <linux/platform_device.h>17#include <linux/platform_device.h>
18#include <linux/reset.h>
17 19
18#include "denali.h"20#include "denali.h"
19 21
@@ -22,11 +24,14 @@ struct denali_dt { · 2 unmodified lines
22 struct clk *clk; /* core clock */24 struct clk *clk; /* core clock */
23 struct clk *clk_x; /* bus interface clock */25 struct clk *clk_x; /* bus interface clock */
24 struct clk *clk_ecc; /* ECC circuit clock */26 struct clk *clk_ecc; /* ECC circuit clock */
27 struct reset_control *rst; /* core reset */
28 struct reset_control *rst_reg; /* register reset */
25};29};
26 30
27struct denali_dt_data {31struct denali_dt_data {
28 unsigned int revision;32 unsigned int revision;
29 unsigned int caps;33 unsigned int caps;
34 unsigned int oob_skip_bytes;
30 const struct nand_ecc_caps *ecc_caps;35 const struct nand_ecc_caps *ecc_caps;
31};36};
32 37
@@ -34,6 +39,7 @@ NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes, · 1 unmodified line
34 512, 8, 15);39 512, 8, 15);
35static const struct denali_dt_data denali_socfpga_data = {40static const struct denali_dt_data denali_socfpga_data = {
36 .caps = DENALI_CAP_HW_ECC_FIXUP,41 .caps = DENALI_CAP_HW_ECC_FIXUP,
42 .oob_skip_bytes = 2,
37 .ecc_caps = &denali_socfpga_ecc_caps,43 .ecc_caps = &denali_socfpga_ecc_caps,
38};44};
39 45
@@ -42,6 +48,7 @@ NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes, · 2 unmodified lines
42static const struct denali_dt_data denali_uniphier_v5a_data = {48static const struct denali_dt_data denali_uniphier_v5a_data = {
43 .caps = DENALI_CAP_HW_ECC_FIXUP |49 .caps = DENALI_CAP_HW_ECC_FIXUP |
44 DENALI_CAP_DMA_64BIT,50 DENALI_CAP_DMA_64BIT,
51 .oob_skip_bytes = 8,
45 .ecc_caps = &denali_uniphier_v5a_ecc_caps,52 .ecc_caps = &denali_uniphier_v5a_ecc_caps,
46};53};
47 54
@@ -51,6 +58,7 @@ static const struct denali_dt_data denali_uniphier_v5b_data = { · 3 unmodified lines
51 .revision = 0x0501,58 .revision = 0x0501,
52 .caps = DENALI_CAP_HW_ECC_FIXUP |59 .caps = DENALI_CAP_HW_ECC_FIXUP |
53 DENALI_CAP_DMA_64BIT,60 DENALI_CAP_DMA_64BIT,
61 .oob_skip_bytes = 8,
54 .ecc_caps = &denali_uniphier_v5b_ecc_caps,62 .ecc_caps = &denali_uniphier_v5b_ecc_caps,
55};63};
56 64
@@ -118,11 +126,13 @@ static int denali_dt_probe(struct platform_device *pdev) · 61 unmodified lines
118 denali = &dt->controller;126 denali = &dt->controller;
119 127
120 data = of_device_get_match_data(dev);128 data = of_device_get_match_data(dev);
121 if (data) {129 if (WARN_ON(!data))
122 denali->revision = data->revision;130 return -EINVAL;
123 denali->caps = data->caps;131
124 denali->ecc_caps = data->ecc_caps;132 denali->revision = data->revision;
125 }133 denali->caps = data->caps;
134 denali->oob_skip_bytes = data->oob_skip_bytes;
135 denali->ecc_caps = data->ecc_caps;
126 136
127 denali->dev = dev;137 denali->dev = dev;
128 denali->irq = platform_get_irq(pdev, 0);138 denali->irq = platform_get_irq(pdev, 0);
@@ -151,6 +161,14 @@ static int denali_dt_probe(struct platform_device *pdev) · 22 unmodified lines
151 if (IS_ERR(dt->clk_ecc))161 if (IS_ERR(dt->clk_ecc))
152 return PTR_ERR(dt->clk_ecc);162 return PTR_ERR(dt->clk_ecc);
153 163
164 dt->rst = devm_reset_control_get_optional_shared(dev, "nand");
165 if (IS_ERR(dt->rst))
166 return PTR_ERR(dt->rst);
167
168 dt->rst_reg = devm_reset_control_get_optional_shared(dev, "reg");
169 if (IS_ERR(dt->rst_reg))
170 return PTR_ERR(dt->rst_reg);
171
154 ret = clk_prepare_enable(dt->clk);172 ret = clk_prepare_enable(dt->clk);
155 if (ret)173 if (ret)
156 return ret;174 return ret;
@@ -166,10 +184,30 @@ static int denali_dt_probe(struct platform_device *pdev) · 9 unmodified lines
166 denali->clk_rate = clk_get_rate(dt->clk);184 denali->clk_rate = clk_get_rate(dt->clk);
167 denali->clk_x_rate = clk_get_rate(dt->clk_x);185 denali->clk_x_rate = clk_get_rate(dt->clk_x);
168 186
169 ret = denali_init(denali);187 /*
188 * Deassert the register reset, and the core reset in this order.
189 * Deasserting the core reset while the register reset is asserted
190 * will cause unpredictable behavior in the controller.
191 */
192 ret = reset_control_deassert(dt->rst_reg);
170 if (ret)193 if (ret)
171 goto out_disable_clk_ecc;194 goto out_disable_clk_ecc;
172 195
196 ret = reset_control_deassert(dt->rst);
197 if (ret)
198 goto out_assert_rst_reg;
199
200 /*
201 * When the reset is deasserted, the initialization sequence is kicked
202 * (bootstrap process). The driver must wait until it finished.
203 * Otherwise, it will result in unpredictable behavior.
204 */
205 usleep_range(200, 1000);
206
207 ret = denali_init(denali);
208 if (ret)
209 goto out_assert_rst;
210
173 for_each_child_of_node(dev->of_node, np) {211 for_each_child_of_node(dev->of_node, np) {
174 ret = denali_dt_chip_init(denali, np);212 ret = denali_dt_chip_init(denali, np);
175 if (ret) {213 if (ret) {
@@ -184,6 +222,10 @@ static int denali_dt_probe(struct platform_device *pdev) · 8 unmodified lines
184 222
185out_remove_denali:223out_remove_denali:
186 denali_remove(denali);224 denali_remove(denali);
225out_assert_rst:
226 reset_control_assert(dt->rst);
227out_assert_rst_reg:
228 reset_control_assert(dt->rst_reg);
187out_disable_clk_ecc:229out_disable_clk_ecc:
188 clk_disable_unprepare(dt->clk_ecc);230 clk_disable_unprepare(dt->clk_ecc);
189out_disable_clk_x:231out_disable_clk_x:
@@ -199,6 +241,8 @@ static int denali_dt_remove(struct platform_device *pdev) · 9 unmodified lines
199 struct denali_dt *dt = platform_get_drvdata(pdev);241 struct denali_dt *dt = platform_get_drvdata(pdev);
200 242
201 denali_remove(&dt->controller);243 denali_remove(&dt->controller);
244 reset_control_assert(dt->rst);
245 reset_control_assert(dt->rst_reg);
202 clk_disable_unprepare(dt->clk_ecc);246 clk_disable_unprepare(dt->clk_ecc);
203 clk_disable_unprepare(dt->clk_x);247 clk_disable_unprepare(dt->clk_x);
204 clk_disable_unprepare(dt->clk);248 clk_disable_unprepare(dt->clk);
drivers/mtd/nand/raw/mpc5121_nfc.c+1−1
@@ -438,7 +438,7 @@ static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, · 437 unmodified lines
438 buffer += blksize;438 buffer += blksize;
439 offset += blksize;439 offset += blksize;
440 size -= blksize;440 size -= blksize;
441 };441 }
442}442}
443 443
444/* Copy data from/to NFC main and spare buffers */444/* Copy data from/to NFC main and spare buffers */
drivers/mtd/nand/raw/nand_macronix.c+4−7
@@ -59,7 +59,7 @@ static void macronix_nand_onfi_init(struct nand_chip *chip) · 58 unmodified lines
59 */59 */
60static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)60static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
61{61{
62 unsigned int i;62 int i;
63 static const char * const broken_get_timings[] = {63 static const char * const broken_get_timings[] = {
64 "MX30LF1G18AC",64 "MX30LF1G18AC",
65 "MX30LF1G28AC",65 "MX30LF1G28AC",
@@ -80,12 +80,9 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) · 14 unmodified lines
80 if (!chip->parameters.supports_set_get_features)80 if (!chip->parameters.supports_set_get_features)
81 return;81 return;
82 82
83 for (i = 0; i < ARRAY_SIZE(broken_get_timings); i++) {83 i = match_string(broken_get_timings, ARRAY_SIZE(broken_get_timings),
84 if (!strcmp(broken_get_timings[i], chip->parameters.model))84 chip->parameters.model);
85 break;85 if (i < 0)
86 }
87
88 if (i == ARRAY_SIZE(broken_get_timings))
89 return;86 return;
90 87
91 bitmap_clear(chip->parameters.get_feature_list,88 bitmap_clear(chip->parameters.get_feature_list,
drivers/mtd/nand/spi/toshiba.c+10−0
@@ -124,6 +124,16 @@ static const struct spinand_info toshiba_spinand_table[] = { · 123 unmodified lines
124 0,124 0,
125 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,125 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
126 tc58cxgxsx_ecc_get_status)),126 tc58cxgxsx_ecc_get_status)),
127 /* 3.3V 4Gb */
128 SPINAND_INFO("TC58CVG2S0", 0xED,
129 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
130 NAND_ECCREQ(8, 512),
131 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
132 &write_cache_variants,
133 &update_cache_variants),
134 0,
135 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
136 tc58cxgxsx_ecc_get_status)),
127 /* 1.8V 1Gb */137 /* 1.8V 1Gb */
128 SPINAND_INFO("TC58CYG0S3", 0xB2,138 SPINAND_INFO("TC58CYG0S3", 0xB2,
129 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),139 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
drivers/mtd/parsers/sharpslpart.c+2−2
@@ -165,10 +165,10 @@ static int sharpsl_nand_get_logical_num(u8 *oob) · 164 unmodified lines
165 165
166static int sharpsl_nand_init_ftl(struct mtd_info *mtd, struct sharpsl_ftl *ftl)166static int sharpsl_nand_init_ftl(struct mtd_info *mtd, struct sharpsl_ftl *ftl)
167{167{
168 unsigned int block_num, log_num, phymax;168 unsigned int block_num, phymax;
169 int i, ret, log_num;
169 loff_t block_adr;170 loff_t block_adr;
170 u8 *oob;171 u8 *oob;
171 int i, ret;
172 172
173 oob = kzalloc(mtd->oobsize, GFP_KERNEL);173 oob = kzalloc(mtd->oobsize, GFP_KERNEL);
174 if (!oob)174 if (!oob)
drivers/mtd/spi-nor/Kconfig+2−2
@@ -46,11 +46,11 @@ config SPI_CADENCE_QUADSPI · 45 unmodified lines
46 Flash as an MTD device.46 Flash as an MTD device.
47 47
48config SPI_HISI_SFC48config SPI_HISI_SFC
49 tristate "Hisilicon SPI-NOR Flash Controller(SFC)"49 tristate "Hisilicon FMC SPI-NOR Flash Controller(SFC)"
50 depends on ARCH_HISI || COMPILE_TEST50 depends on ARCH_HISI || COMPILE_TEST
51 depends on HAS_IOMEM51 depends on HAS_IOMEM
52 help52 help
53 This enables support for hisilicon SPI-NOR flash controller.53 This enables support for HiSilicon FMC SPI-NOR flash controller.
54 54
55config SPI_MTK_QUADSPI55config SPI_MTK_QUADSPI
56 tristate "MediaTek Quad SPI controller"56 tristate "MediaTek Quad SPI controller"
drivers/mtd/spi-nor/aspeed-smc.c+2−2
@@ -305,7 +305,7 @@ static void aspeed_smc_stop_user(struct spi_nor *nor) · 304 unmodified lines
305 writel(ctl, chip->ctl); /* default to fread or read mode */305 writel(ctl, chip->ctl); /* default to fread or read mode */
306}306}
307 307
308static int aspeed_smc_prep(struct spi_nor *nor, enum spi_nor_ops ops)308static int aspeed_smc_prep(struct spi_nor *nor)
309{309{
310 struct aspeed_smc_chip *chip = nor->priv;310 struct aspeed_smc_chip *chip = nor->priv;
311 311
@@ -313,7 +313,7 @@ static int aspeed_smc_prep(struct spi_nor *nor, enum spi_nor_ops ops) · 1 unmodified line
313 return 0;313 return 0;
314}314}
315 315
316static void aspeed_smc_unprep(struct spi_nor *nor, enum spi_nor_ops ops)316static void aspeed_smc_unprep(struct spi_nor *nor)
317{317{
318 struct aspeed_smc_chip *chip = nor->priv;318 struct aspeed_smc_chip *chip = nor->priv;
319 319
drivers/mtd/spi-nor/cadence-quadspi.c+2−2
@@ -1062,7 +1062,7 @@ static int cqspi_erase(struct spi_nor *nor, loff_t offs) · 1061 unmodified lines
1062 return 0;1062 return 0;
1063}1063}
1064 1064
1065static int cqspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)1065static int cqspi_prep(struct spi_nor *nor)
1066{1066{
1067 struct cqspi_flash_pdata *f_pdata = nor->priv;1067 struct cqspi_flash_pdata *f_pdata = nor->priv;
1068 struct cqspi_st *cqspi = f_pdata->cqspi;1068 struct cqspi_st *cqspi = f_pdata->cqspi;
@@ -1072,7 +1072,7 @@ static int cqspi_prep(struct spi_nor *nor, enum spi_nor_ops ops) · 3 unmodified lines
1072 return 0;1072 return 0;
1073}1073}
1074 1074
1075static void cqspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)1075static void cqspi_unprep(struct spi_nor *nor)
1076{1076{
1077 struct cqspi_flash_pdata *f_pdata = nor->priv;1077 struct cqspi_flash_pdata *f_pdata = nor->priv;
1078 struct cqspi_st *cqspi = f_pdata->cqspi;1078 struct cqspi_st *cqspi = f_pdata->cqspi;
drivers/mtd/spi-nor/hisi-sfc.c+3−3
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * HiSilicon SPI Nor Flash Controller Driver3 * HiSilicon FMC SPI-NOR flash controller driver
4 *4 *
5 * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.5 * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.
6 */6 */
@@ -144,7 +144,7 @@ static void hisi_spi_nor_init(struct hifmc_host *host) · 137 unmodified lines
144 writel(reg, host->regbase + FMC_SPI_TIMING_CFG);144 writel(reg, host->regbase + FMC_SPI_TIMING_CFG);
145}145}
146 146
147static int hisi_spi_nor_prep(struct spi_nor *nor, enum spi_nor_ops ops)147static int hisi_spi_nor_prep(struct spi_nor *nor)
148{148{
149 struct hifmc_priv *priv = nor->priv;149 struct hifmc_priv *priv = nor->priv;
150 struct hifmc_host *host = priv->host;150 struct hifmc_host *host = priv->host;
@@ -167,7 +167,7 @@ out: · 16 unmodified lines
167 return ret;167 return ret;
168}168}
169 169
170static void hisi_spi_nor_unprep(struct spi_nor *nor, enum spi_nor_ops ops)170static void hisi_spi_nor_unprep(struct spi_nor *nor)
171{171{
172 struct hifmc_priv *priv = nor->priv;172 struct hifmc_priv *priv = nor->priv;
173 struct hifmc_host *host = priv->host;173 struct hifmc_host *host = priv->host;
drivers/mtd/spi-nor/intel-spi-pci.c+2−0
@@ -70,10 +70,12 @@ static const struct pci_device_id intel_spi_pci_ids[] = { · 69 unmodified lines
70 { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },70 { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
71 { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },71 { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },
72 { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },72 { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },
73 { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info },
73 { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info },74 { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info },
74 { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info },75 { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info },
75 { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info },76 { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info },
76 { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },77 { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
78 { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&bxt_info },
77 { },79 { },
78};80};
79MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);81MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
drivers/mtd/spi-nor/spi-nor.c+91−36
@@ -85,7 +85,7 @@ struct sfdp_header { · 84 unmodified lines
85#define BFPT_DWORD(i) ((i) - 1)85#define BFPT_DWORD(i) ((i) - 1)
86#define BFPT_DWORD_MAX 1686#define BFPT_DWORD_MAX 16
87 87
88/* The first version of JESB216 defined only 9 DWORDs. */88/* The first version of JESD216 defined only 9 DWORDs. */
89#define BFPT_DWORD_MAX_JESD216 989#define BFPT_DWORD_MAX_JESD216 9
90 90
91/* 1st DWORD. */91/* 1st DWORD. */
@@ -196,7 +196,7 @@ struct flash_info { · 104 unmodified lines
196 u16 page_size;196 u16 page_size;
197 u16 addr_width;197 u16 addr_width;
198 198
199 u16 flags;199 u32 flags;
200#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */200#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */
201#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */201#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */
202#define SST_WRITE BIT(2) /* use SST byte programming */202#define SST_WRITE BIT(2) /* use SST byte programming */
@@ -233,6 +233,11 @@ struct flash_info { · 30 unmodified lines
233#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */233#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */
234#define USE_CLSR BIT(14) /* use CLSR command */234#define USE_CLSR BIT(14) /* use CLSR command */
235#define SPI_NOR_OCTAL_READ BIT(15) /* Flash supports Octal Read */235#define SPI_NOR_OCTAL_READ BIT(15) /* Flash supports Octal Read */
236#define SPI_NOR_TB_SR_BIT6 BIT(16) /*
237 * Top/Bottom (TB) is bit 6 of
238 * status register. Must be used with
239 * SPI_NOR_HAS_TB.
240 */
236 241
237 /* Part specific fixup hooks. */242 /* Part specific fixup hooks. */
238 const struct spi_nor_fixups *fixups;243 const struct spi_nor_fixups *fixups;
@@ -1307,14 +1312,14 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) · 1068 unmodified lines
1307 }1312 }
1308}1313}
1309 1314
1310static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops)1315static int spi_nor_lock_and_prep(struct spi_nor *nor)
1311{1316{
1312 int ret = 0;1317 int ret = 0;
1313 1318
1314 mutex_lock(&nor->lock);1319 mutex_lock(&nor->lock);
1315 1320
1316 if (nor->controller_ops && nor->controller_ops->prepare) {1321 if (nor->controller_ops && nor->controller_ops->prepare) {
1317 ret = nor->controller_ops->prepare(nor, ops);1322 ret = nor->controller_ops->prepare(nor);
1318 if (ret) {1323 if (ret) {
1319 mutex_unlock(&nor->lock);1324 mutex_unlock(&nor->lock);
1320 return ret;1325 return ret;
@@ -1323,10 +1328,10 @@ static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) · 2 unmodified lines
1323 return ret;1328 return ret;
1324}1329}
1325 1330
1326static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops)1331static void spi_nor_unlock_and_unprep(struct spi_nor *nor)
1327{1332{
1328 if (nor->controller_ops && nor->controller_ops->unprepare)1333 if (nor->controller_ops && nor->controller_ops->unprepare)
1329 nor->controller_ops->unprepare(nor, ops);1334 nor->controller_ops->unprepare(nor);
1330 mutex_unlock(&nor->lock);1335 mutex_unlock(&nor->lock);
1331}1336}
1332 1337
@@ -1688,7 +1693,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) · 355 unmodified lines
1688 addr = instr->addr;1693 addr = instr->addr;
1689 len = instr->len;1694 len = instr->len;
1690 1695
1691 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_ERASE);1696 ret = spi_nor_lock_and_prep(nor);
1692 if (ret)1697 if (ret)
1693 return ret;1698 return ret;
1694 1699
@@ -1751,7 +1756,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) · 56 unmodified lines
1751 ret = spi_nor_write_disable(nor);1756 ret = spi_nor_write_disable(nor);
1752 1757
1753erase_err:1758erase_err:
1754 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);1759 spi_nor_unlock_and_unprep(nor);
1755 1760
1756 return ret;1761 return ret;
1757}1762}
@@ -1761,9 +1766,13 @@ static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, · 3 unmodified lines
1761{1766{
1762 struct mtd_info *mtd = &nor->mtd;1767 struct mtd_info *mtd = &nor->mtd;
1763 u8 mask = SR_BP2 | SR_BP1 | SR_BP0;1768 u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
1769 u8 tb_mask = SR_TB_BIT5;
1764 int shift = ffs(mask) - 1;1770 int shift = ffs(mask) - 1;
1765 int pow;1771 int pow;
1766 1772
1773 if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
1774 tb_mask = SR_TB_BIT6;
1775
1767 if (!(sr & mask)) {1776 if (!(sr & mask)) {
1768 /* No protection */1777 /* No protection */
1769 *ofs = 0;1778 *ofs = 0;
@@ -1771,7 +1780,7 @@ static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, · 1 unmodified line
1771 } else {1780 } else {
1772 pow = ((sr & mask) ^ mask) >> shift;1781 pow = ((sr & mask) ^ mask) >> shift;
1773 *len = mtd->size >> pow;1782 *len = mtd->size >> pow;
1774 if (nor->flags & SNOR_F_HAS_SR_TB && sr & SR_TB)1783 if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
1775 *ofs = 0;1784 *ofs = 0;
1776 else1785 else
1777 *ofs = mtd->size - *len;1786 *ofs = mtd->size - *len;
@@ -1850,6 +1859,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) · 72 unmodified lines
1850 struct mtd_info *mtd = &nor->mtd;1859 struct mtd_info *mtd = &nor->mtd;
1851 int ret, status_old, status_new;1860 int ret, status_old, status_new;
1852 u8 mask = SR_BP2 | SR_BP1 | SR_BP0;1861 u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
1862 u8 tb_mask = SR_TB_BIT5;
1853 u8 shift = ffs(mask) - 1, pow, val;1863 u8 shift = ffs(mask) - 1, pow, val;
1854 loff_t lock_len;1864 loff_t lock_len;
1855 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;1865 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
@@ -1886,6 +1896,9 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) · 30 unmodified lines
1886 else1896 else
1887 lock_len = ofs + len;1897 lock_len = ofs + len;
1888 1898
1899 if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
1900 tb_mask = SR_TB_BIT6;
1901
1889 /*1902 /*
1890 * Need smallest pow such that:1903 * Need smallest pow such that:
1891 *1904 *
@@ -1903,13 +1916,13 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) · 11 unmodified lines
1903 if (!(val & mask))1916 if (!(val & mask))
1904 return -EINVAL;1917 return -EINVAL;
1905 1918
1906 status_new = (status_old & ~mask & ~SR_TB) | val;1919 status_new = (status_old & ~mask & ~tb_mask) | val;
1907 1920
1908 /* Disallow further writes if WP pin is asserted */1921 /* Disallow further writes if WP pin is asserted */
1909 status_new |= SR_SRWD;1922 status_new |= SR_SRWD;
1910 1923
1911 if (!use_top)1924 if (!use_top)
1912 status_new |= SR_TB;1925 status_new |= tb_mask;
1913 1926
1914 /* Don't bother if they're the same */1927 /* Don't bother if they're the same */
1915 if (status_new == status_old)1928 if (status_new == status_old)
@@ -1932,6 +1945,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) · 16 unmodified lines
1932 struct mtd_info *mtd = &nor->mtd;1945 struct mtd_info *mtd = &nor->mtd;
1933 int ret, status_old, status_new;1946 int ret, status_old, status_new;
1934 u8 mask = SR_BP2 | SR_BP1 | SR_BP0;1947 u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
1948 u8 tb_mask = SR_TB_BIT5;
1935 u8 shift = ffs(mask) - 1, pow, val;1949 u8 shift = ffs(mask) - 1, pow, val;
1936 loff_t lock_len;1950 loff_t lock_len;
1937 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;1951 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
@@ -1968,6 +1982,8 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) · 30 unmodified lines
1968 else1982 else
1969 lock_len = ofs;1983 lock_len = ofs;
1970 1984
1985 if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
1986 tb_mask = SR_TB_BIT6;
1971 /*1987 /*
1972 * Need largest pow such that:1988 * Need largest pow such that:
1973 *1989 *
@@ -1987,14 +2003,14 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) · 13 unmodified lines
1987 return -EINVAL;2003 return -EINVAL;
1988 }2004 }
1989 2005
1990 status_new = (status_old & ~mask & ~SR_TB) | val;2006 status_new = (status_old & ~mask & ~tb_mask) | val;
1991 2007
1992 /* Don't protect status register if we're fully unlocked */2008 /* Don't protect status register if we're fully unlocked */
1993 if (lock_len == 0)2009 if (lock_len == 0)
1994 status_new &= ~SR_SRWD;2010 status_new &= ~SR_SRWD;
1995 2011
1996 if (!use_top)2012 if (!use_top)
1997 status_new |= SR_TB;2013 status_new |= tb_mask;
1998 2014
1999 /* Don't bother if they're the same */2015 /* Don't bother if they're the same */
2000 if (status_new == status_old)2016 if (status_new == status_old)
@@ -2036,13 +2052,13 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 35 unmodified lines
2036 struct spi_nor *nor = mtd_to_spi_nor(mtd);2052 struct spi_nor *nor = mtd_to_spi_nor(mtd);
2037 int ret;2053 int ret;
2038 2054
2039 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK);2055 ret = spi_nor_lock_and_prep(nor);
2040 if (ret)2056 if (ret)
2041 return ret;2057 return ret;
2042 2058
2043 ret = nor->params.locking_ops->lock(nor, ofs, len);2059 ret = nor->params.locking_ops->lock(nor, ofs, len);
2044 2060
2045 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);2061 spi_nor_unlock_and_unprep(nor);
2046 return ret;2062 return ret;
2047}2063}
2048 2064
@@ -2051,13 +2067,13 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 2 unmodified lines
2051 struct spi_nor *nor = mtd_to_spi_nor(mtd);2067 struct spi_nor *nor = mtd_to_spi_nor(mtd);
2052 int ret;2068 int ret;
2053 2069
2054 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK);2070 ret = spi_nor_lock_and_prep(nor);
2055 if (ret)2071 if (ret)
2056 return ret;2072 return ret;
2057 2073
2058 ret = nor->params.locking_ops->unlock(nor, ofs, len);2074 ret = nor->params.locking_ops->unlock(nor, ofs, len);
2059 2075
2060 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);2076 spi_nor_unlock_and_unprep(nor);
2061 return ret;2077 return ret;
2062}2078}
2063 2079
@@ -2066,13 +2082,13 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 2 unmodified lines
2066 struct spi_nor *nor = mtd_to_spi_nor(mtd);2082 struct spi_nor *nor = mtd_to_spi_nor(mtd);
2067 int ret;2083 int ret;
2068 2084
2069 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK);2085 ret = spi_nor_lock_and_prep(nor);
2070 if (ret)2086 if (ret)
2071 return ret;2087 return ret;
2072 2088
2073 ret = nor->params.locking_ops->is_locked(nor, ofs, len);2089 ret = nor->params.locking_ops->is_locked(nor, ofs, len);
2074 2090
2075 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);2091 spi_nor_unlock_and_unprep(nor);
2076 return ret;2092 return ret;
2077}2093}
2078 2094
@@ -2309,6 +2325,9 @@ static const struct flash_info spi_nor_ids[] = { · 230 unmodified lines
2309 { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },2325 { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
2310 { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },2326 { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
2311 2327
2328 { "at25sl321", INFO(0x1f4216, 0, 64 * 1024, 64,
2329 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2330
2312 { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) },2331 { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) },
2313 { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },2332 { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
2314 { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },2333 { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
@@ -2373,6 +2392,11 @@ static const struct flash_info spi_nor_ids[] = { · 58 unmodified lines
2373 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |2392 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2374 SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)2393 SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
2375 },2394 },
2395 {
2396 "gd25lq128d", INFO(0xc86018, 0, 64 * 1024, 256,
2397 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2398 SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
2399 },
2376 {2400 {
2377 "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256,2401 "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256,
2378 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |2402 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
@@ -2381,7 +2405,8 @@ static const struct flash_info spi_nor_ids[] = { · 2 unmodified lines
2381 {2405 {
2382 "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,2406 "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
2383 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |2407 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2384 SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)2408 SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
2409 SPI_NOR_TB_SR_BIT6)
2385 .fixups = &gd25q256_fixups,2410 .fixups = &gd25q256_fixups,
2386 },2411 },
2387 2412
@@ -2436,6 +2461,8 @@ static const struct flash_info spi_nor_ids[] = { · 48 unmodified lines
2436 { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },2461 { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
2437 { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },2462 { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
2438 { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },2463 { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
2464 { "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64,
2465 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2439 { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256,2466 { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256,
2440 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },2467 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2441 { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,2468 { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,
@@ -2456,20 +2483,35 @@ static const struct flash_info spi_nor_ids[] = { · 14 unmodified lines
2456 { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) },2483 { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) },
2457 { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },2484 { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
2458 { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },2485 { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
2459 { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },2486 { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K |
2460 { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },2487 USE_FSR | SPI_NOR_QUAD_READ) },
2461 { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },2488 { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K |
2462 { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },2489 USE_FSR | SPI_NOR_QUAD_READ) },
2490 { "mt25ql256a", INFO6(0x20ba19, 0x104400, 64 * 1024, 512,
2491 SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
2492 SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
2493 { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K |
2494 USE_FSR | SPI_NOR_DUAL_READ |
2495 SPI_NOR_QUAD_READ) },
2496 { "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512,
2497 SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
2498 SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
2499 { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K |
2500 USE_FSR | SPI_NOR_QUAD_READ) },
2501 { "mt25ql512a", INFO6(0x20ba20, 0x104400, 64 * 1024, 1024,
2502 SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
2503 SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
2463 { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },2504 { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
2505 { "mt25qu512a", INFO6(0x20bb20, 0x104400, 64 * 1024, 1024,
2506 SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
2507 SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
2508 { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K |
2509 USE_FSR | SPI_NOR_QUAD_READ) },
2464 { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },2510 { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
2465 { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },2511 { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
2466 { "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096,2512 { "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096,
2467 SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |2513 SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
2468 NO_CHIP_ERASE) },2514 NO_CHIP_ERASE) },
2469 { "mt25qu512a (n25q512a)", INFO(0x20bb20, 0, 64 * 1024, 1024,
2470 SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
2471 SPI_NOR_QUAD_READ |
2472 SPI_NOR_4B_OPCODES) },
2473 { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },2515 { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
2474 2516
2475 /* Micron */2517 /* Micron */
@@ -2540,6 +2582,8 @@ static const struct flash_info spi_nor_ids[] = { · 64 unmodified lines
2540 { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },2582 { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
2541 { "sst26wf016b", INFO(0xbf2651, 0, 64 * 1024, 32, SECT_4K |2583 { "sst26wf016b", INFO(0xbf2651, 0, 64 * 1024, 32, SECT_4K |
2542 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },2584 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2585 { "sst26vf016b", INFO(0xbf2641, 0, 64 * 1024, 32, SECT_4K |
2586 SPI_NOR_DUAL_READ) },
2543 { "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },2587 { "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2544 2588
2545 /* ST Microelectronics -- newer production may have feature updates */2589 /* ST Microelectronics -- newer production may have feature updates */
@@ -2610,6 +2654,11 @@ static const struct flash_info spi_nor_ids[] = { · 64 unmodified lines
2610 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |2654 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2611 SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)2655 SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
2612 },2656 },
2657 {
2658 "w25q32jwm", INFO(0xef8016, 0, 64 * 1024, 64,
2659 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2660 SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
2661 },
2613 { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },2662 { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
2614 { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },2663 { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
2615 {2664 {
@@ -2630,7 +2679,9 @@ static const struct flash_info spi_nor_ids[] = { · 14 unmodified lines
2630 { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },2679 { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
2631 { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },2680 { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
2632 { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },2681 { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
2633 { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },2682 { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512,
2683 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2684 SPI_NOR_4B_OPCODES) },
2634 { "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512,2685 { "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512,
2635 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },2686 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2636 { "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512,2687 { "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512,
@@ -2701,7 +2752,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, · 64 unmodified lines
2701 2752
2702 dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);2753 dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
2703 2754
2704 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_READ);2755 ret = spi_nor_lock_and_prep(nor);
2705 if (ret)2756 if (ret)
2706 return ret;2757 return ret;
2707 2758
@@ -2728,7 +2779,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, · 20 unmodified lines
2728 ret = 0;2779 ret = 0;
2729 2780
2730read_err:2781read_err:
2731 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);2782 spi_nor_unlock_and_unprep(nor);
2732 return ret;2783 return ret;
2733}2784}
2734 2785
@@ -2741,7 +2792,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, · 6 unmodified lines
2741 2792
2742 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);2793 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
2743 2794
2744 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE);2795 ret = spi_nor_lock_and_prep(nor);
2745 if (ret)2796 if (ret)
2746 return ret;2797 return ret;
2747 2798
@@ -2814,7 +2865,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, · 66 unmodified lines
2814 }2865 }
2815out:2866out:
2816 *retlen += actual;2867 *retlen += actual;
2817 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);2868 spi_nor_unlock_and_unprep(nor);
2818 return ret;2869 return ret;
2819}2870}
2820 2871
@@ -2832,7 +2883,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, · 11 unmodified lines
2832 2883
2833 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);2884 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
2834 2885
2835 ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE);2886 ret = spi_nor_lock_and_prep(nor);
2836 if (ret)2887 if (ret)
2837 return ret;2888 return ret;
2838 2889
@@ -2878,7 +2929,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, · 39 unmodified lines
2878 }2929 }
2879 2930
2880write_err:2931write_err:
2881 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);2932 spi_nor_unlock_and_unprep(nor);
2882 return ret;2933 return ret;
2883}2934}
2884 2935
@@ -5143,8 +5194,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, · 2258 unmodified lines
5143 5194
5144 if (info->flags & USE_FSR)5195 if (info->flags & USE_FSR)
5145 nor->flags |= SNOR_F_USE_FSR;5196 nor->flags |= SNOR_F_USE_FSR;
5146 if (info->flags & SPI_NOR_HAS_TB)5197 if (info->flags & SPI_NOR_HAS_TB) {
5147 nor->flags |= SNOR_F_HAS_SR_TB;5198 nor->flags |= SNOR_F_HAS_SR_TB;
5199 if (info->flags & SPI_NOR_TB_SR_BIT6)
5200 nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
5201 }
5202
5148 if (info->flags & NO_CHIP_ERASE)5203 if (info->flags & NO_CHIP_ERASE)
5149 nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;5204 nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
5150 if (info->flags & USE_CLSR)5205 if (info->flags & USE_CLSR)
include/linux/mtd/spi-nor.h+5−11
@@ -128,7 +128,8 @@ · 127 unmodified lines
128#define SR_BP0 BIT(2) /* Block protect 0 */128#define SR_BP0 BIT(2) /* Block protect 0 */
129#define SR_BP1 BIT(3) /* Block protect 1 */129#define SR_BP1 BIT(3) /* Block protect 1 */
130#define SR_BP2 BIT(4) /* Block protect 2 */130#define SR_BP2 BIT(4) /* Block protect 2 */
131#define SR_TB BIT(5) /* Top/Bottom protect */131#define SR_TB_BIT5 BIT(5) /* Top/Bottom protect */
132#define SR_TB_BIT6 BIT(6) /* Top/Bottom protect */
132#define SR_SRWD BIT(7) /* SR write protect */133#define SR_SRWD BIT(7) /* SR write protect */
133/* Spansion/Cypress specific status bits */134/* Spansion/Cypress specific status bits */
134#define SR_E_ERR BIT(5)135#define SR_E_ERR BIT(5)
@@ -224,14 +225,6 @@ static inline u8 spi_nor_get_protocol_width(enum spi_nor_protocol proto) · 89 unmodified lines
224 return spi_nor_get_protocol_data_nbits(proto);225 return spi_nor_get_protocol_data_nbits(proto);
225}226}
226 227
227enum spi_nor_ops {
228 SPI_NOR_OPS_READ = 0,
229 SPI_NOR_OPS_WRITE,
230 SPI_NOR_OPS_ERASE,
231 SPI_NOR_OPS_LOCK,
232 SPI_NOR_OPS_UNLOCK,
233};
234
235enum spi_nor_option_flags {228enum spi_nor_option_flags {
236 SNOR_F_USE_FSR = BIT(0),229 SNOR_F_USE_FSR = BIT(0),
237 SNOR_F_HAS_SR_TB = BIT(1),230 SNOR_F_HAS_SR_TB = BIT(1),
@@ -244,6 +237,7 @@ enum spi_nor_option_flags { · 6 unmodified lines
244 SNOR_F_HAS_LOCK = BIT(8),237 SNOR_F_HAS_LOCK = BIT(8),
245 SNOR_F_HAS_16BIT_SR = BIT(9),238 SNOR_F_HAS_16BIT_SR = BIT(9),
246 SNOR_F_NO_READ_CR = BIT(10),239 SNOR_F_NO_READ_CR = BIT(10),
240 SNOR_F_HAS_SR_TB_BIT6 = BIT(11),
247 241
248};242};
249 243
@@ -483,8 +477,8 @@ struct spi_nor; · 233 unmodified lines
483 * opcode via write_reg().477 * opcode via write_reg().
484 */478 */
485struct spi_nor_controller_ops {479struct spi_nor_controller_ops {
486 int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);480 int (*prepare)(struct spi_nor *nor);
487 void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);481 void (*unprepare)(struct spi_nor *nor);
488 int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len);482 int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len);
489 int (*write_reg)(struct spi_nor *nor, u8 opcode, const u8 *buf,483 int (*write_reg)(struct spi_nor *nor, u8 opcode, const u8 *buf,
490 size_t len);484 size_t len);