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 ...
Unified · Split
| @@ -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 | ||
| 17 | Optional properties: | ||
| 18 | - resets: may contain phandles to the controller core reset, the register | ||
| 19 | reset | ||
| 20 | - reset-names: may contain "nand", "reg" | ||
| 21 | |||
| 17 | Sub-nodes: | 22 | Sub-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 { |
| @@ -44,7 +44,7 @@ struct block2mtd_dev { · 43 unmodified lines | |||
| 44 | static LIST_HEAD(blkmtd_device_list); | 44 | static LIST_HEAD(blkmtd_device_list); |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | static struct page *page_read(struct address_space *mapping, int index) | 47 | static 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 index | 57 | 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 index | 140 | pgoff_t index = to >> PAGE_SHIFT; // page index |
| 141 | int offset = to & ~PAGE_MASK; // page offset | 141 | int offset = to & ~PAGE_MASK; // page offset |
| 142 | int cpylen; | 142 | int cpylen; |
| 143 | 143 | ||
| @@ -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 | ||
| 297 | static DEFINE_SPINLOCK(pcmcia_vpp_lock); | 297 | static DEFINE_MUTEX(pcmcia_vpp_lock); |
| 298 | static int pcmcia_vpp_refcnt; | 298 | static int pcmcia_vpp_refcnt; |
| 299 | static void pcmciamtd_set_vpp(struct map_info *map, int on) | 299 | static 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 | ||
| @@ -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; | 92 | out: |
| 93 | pm_runtime_put(&dev->dev); | ||
| 94 | pm_runtime_disable(&dev->dev); | ||
| 95 | return err; | ||
| 92 | } | 96 | } |
| 93 | 97 | ||
| 94 | static void physmap_set_vpp(struct map_info *map, int state) | 98 | static 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 | else | 496 | 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; |
| @@ -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 | |||
| 848 | void mtd_concat_destroy(struct mtd_info *mtd) | 845 | void mtd_concat_destroy(struct mtd_info *mtd) |
| 849 | { | 846 | { |
| 850 | struct mtd_concat *concat = CONCAT(mtd); | 847 | struct mtd_concat *concat = CONCAT(mtd); |
| @@ -25,7 +25,7 @@ config MTD_ONENAND_GENERIC · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | config MTD_ONENAND_OMAP2 | 26 | config MTD_ONENAND_OMAP2 |
| 27 | tristate "OneNAND on OMAP2/OMAP3 support" | 27 | tristate "OneNAND on OMAP2/OMAP3 support" |
| 28 | depends on ARCH_OMAP2 || ARCH_OMAP3 | 28 | depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && ARM) |
| 29 | depends on OF || COMPILE_TEST | 29 | depends on OF || COMPILE_TEST |
| 30 | help | 30 | help |
| 31 | Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC | 31 | 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 | ||
| 35 | config MTD_ONENAND_SAMSUNG | 35 | config 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_EXYNOS4 | 37 | depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS4 || COMPILE_TEST |
| 38 | help | 38 | 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 | ||
| 43 | config MTD_ONENAND_OTP | 43 | config MTD_ONENAND_OTP |
| 44 | bool "OneNAND OTP Support" | 44 | bool "OneNAND OTP Support" |
| @@ -8,7 +8,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | # Board specific. | 9 | # Board specific. |
| 10 | obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o | 10 | obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o |
| 11 | obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o | 11 | obj-$(CONFIG_MTD_ONENAND_OMAP2) += onenand_omap2.o |
| 12 | obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += samsung_mtd.o | 12 | obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += onenand_samsung.o |
| 13 | 13 | ||
| 14 | onenand-objs = onenand_base.o onenand_bbt.o | 14 | onenand-objs = onenand_base.o onenand_bbt.o |
| @@ -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 DDP | 1275 | * Chip boundary handling in DDP |
| 1276 | * Now we issued chip 1 read and pointed chip 1 | 1276 | * 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 | } else | 1283 | } 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 -EBADMSG | 1324 | * Return success, if no ECC failures, else -EBADMSG |
File renamed without changes.
| @@ -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); |
| @@ -452,7 +452,7 @@ config MTD_NAND_PLATFORM · 451 unmodified lines | |||
| 452 | 452 | ||
| 453 | config MTD_NAND_CADENCE | 453 | config MTD_NAND_CADENCE |
| 454 | tristate "Support Cadence NAND (HPNFC) controller" | 454 | tristate "Support Cadence NAND (HPNFC) controller" |
| 455 | depends on OF || COMPILE_TEST | 455 | depends on (OF || COMPILE_TEST) && HAS_IOMEM |
| 456 | help | 456 | help |
| 457 | Enable the driver for NAND flash on platforms using a Cadence NAND | 457 | Enable the driver for NAND flash on platforms using a Cadence NAND |
| 458 | controller. | 458 | controller. |
| @@ -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", |
| @@ -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); |
| @@ -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 0x00 | 26 | #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); |
| @@ -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 | ||
| 27 | struct denali_dt_data { | 31 | struct 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); |
| 35 | static const struct denali_dt_data denali_socfpga_data = { | 40 | static 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 | |||
| 42 | static const struct denali_dt_data denali_uniphier_v5a_data = { | 48 | static 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 | ||
| 185 | out_remove_denali: | 223 | out_remove_denali: |
| 186 | denali_remove(denali); | 224 | denali_remove(denali); |
| 225 | out_assert_rst: | ||
| 226 | reset_control_assert(dt->rst); | ||
| 227 | out_assert_rst_reg: | ||
| 228 | reset_control_assert(dt->rst_reg); | ||
| 187 | out_disable_clk_ecc: | 229 | out_disable_clk_ecc: |
| 188 | clk_disable_unprepare(dt->clk_ecc); | 230 | clk_disable_unprepare(dt->clk_ecc); |
| 189 | out_disable_clk_x: | 231 | out_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); |
| @@ -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 */ |
| @@ -59,7 +59,7 @@ static void macronix_nand_onfi_init(struct nand_chip *chip) · 58 unmodified lines | |||
| 59 | */ | 59 | */ |
| 60 | static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) | 60 | static 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, |
| @@ -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), |
| @@ -165,10 +165,10 @@ static int sharpsl_nand_get_logical_num(u8 *oob) · 164 unmodified lines | |||
| 165 | 165 | ||
| 166 | static int sharpsl_nand_init_ftl(struct mtd_info *mtd, struct sharpsl_ftl *ftl) | 166 | static 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) |
| @@ -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 | ||
| 48 | config SPI_HISI_SFC | 48 | config 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_TEST | 50 | depends on ARCH_HISI || COMPILE_TEST |
| 51 | depends on HAS_IOMEM | 51 | depends on HAS_IOMEM |
| 52 | help | 52 | help |
| 53 | This enables support for hisilicon SPI-NOR flash controller. | 53 | This enables support for HiSilicon FMC SPI-NOR flash controller. |
| 54 | 54 | ||
| 55 | config SPI_MTK_QUADSPI | 55 | config SPI_MTK_QUADSPI |
| 56 | tristate "MediaTek Quad SPI controller" | 56 | tristate "MediaTek Quad SPI controller" |
| @@ -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 | ||
| 308 | static int aspeed_smc_prep(struct spi_nor *nor, enum spi_nor_ops ops) | 308 | static 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 | ||
| 316 | static void aspeed_smc_unprep(struct spi_nor *nor, enum spi_nor_ops ops) | 316 | static 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 | ||
| @@ -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 | ||
| 1065 | static int cqspi_prep(struct spi_nor *nor, enum spi_nor_ops ops) | 1065 | static 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 | ||
| 1075 | static void cqspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops) | 1075 | static 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; |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | /* | 2 | /* |
| 3 | * HiSilicon SPI Nor Flash Controller Driver | 3 | * 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 | ||
| 147 | static int hisi_spi_nor_prep(struct spi_nor *nor, enum spi_nor_ops ops) | 147 | static 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 | ||
| 170 | static void hisi_spi_nor_unprep(struct spi_nor *nor, enum spi_nor_ops ops) | 170 | static 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; |
| @@ -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 | }; |
| 79 | MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids); | 81 | MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids); |
| @@ -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 16 | 86 | #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 9 | 89 | #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 | ||
| 1310 | static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) | 1315 | static 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 | ||
| 1326 | static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) | 1331 | static 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 | ||
| 1753 | erase_err: | 1758 | erase_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 | else | 1785 | 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 | else | 1896 | 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 | else | 1982 | 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 | ||
| 2730 | read_err: | 2781 | read_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 | } |
| 2815 | out: | 2866 | out: |
| 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 | ||
| 2880 | write_err: | 2931 | write_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) |
| @@ -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 | ||
| 227 | enum 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 | |||
| 235 | enum spi_nor_option_flags { | 228 | enum 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 | */ |
| 485 | struct spi_nor_controller_ops { | 479 | struct 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); |