The main load of changes is related to Uwe's work converting platform

remove callbacks to return void. Comes next (in number of changes) Kees'
 additional structures annotations to improve the sanitizers. The usual
 amount of cleanups apply.
 
 About the more substancial contribution, one main function of the
 partitions core could return an error which was not checked, this is now
 fixed. On the bindings side, fixed partitions can now have a compression
 property. Finally, an erroneous situation is now always avoided in the
 MAP RAM driver.
 
 * CFI
 
 A several years old byte swap has been fixed.
 
 * NAND
 
 The subsystem has, as usual, seen a bit of cleanup being done this
 cycle, typically return values of platform_get_irq() and
 devm_kasprintf(). There is also a better ECC check in the Arasan
 driver. This comes with smaller misc changes.
 
 In the SPI-NAND world there is now support for Foresee F35SQA002G,
 Winbond W25N and XTX XT26 chips.
 
 * SPI NOR
 
 For SPI NOR we cleaned the flash info entries in order to have
 them slimmer and self explanatory. In order to make the entries
 as slim as possible, we introduced sane default values so that
 the actual flash entries don't need to specify them. We now use
 a flexible macro to specify the flash ID instead of the previous
 INFOx() macros that had hardcoded ID lengths.
 
 Instead of:
 -       { "w25q512nwm", INFO(0xef8020, 0, 64 * 1024, 0)
 -               OTP_INFO(256, 3, 0x1000, 0x1000) },
 
 We now use:
 +               .id = SNOR_ID(0xef, 0x80, 0x20),
 +               .name = "w25q512nwm",
 +               .otp = SNOR_OTP(256, 3, 0x1000, 0x1000),
 
 We also removed some flash entries: the very old Catalyst
 SPI EEPROMs that were introduced once with the SPI-NOR subsystem,
 and a Fujitsu MRAM. Both should use the at25 EEPROM driver.
 The latter even has device tree bindings for the at25 driver.
 
 We made sure that the conversion didn't introduce any unwanted
 changes by comparing the .rodata segment before and after the
 conversion. The patches landed in linux-next immediately after
 v6.6-rc2, we haven't seen any regressions yet.
 
 Apart of the autumn cleaning we introduced a new flash entry,
 at25ff321a, and added block protection support for mt25qu512a.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAmVGJNgACgkQJWrqGEe9
 VoQ5ggf/flUHU7RI02T7HNwkHayq/NOgaGIUkUZEwdfEBd6/8nLzpDeh9UuQCBvO
 izOdRSiDDhcav6YsKs+7UKnonY0uZ5VwB3cjRcgWzsI/nyARs5CeV8VJxqxiGYqU
 25rZVVVoNr/4eV6kb9Sx0yUTLobidlNKtpv0w0hLFoVu+eb35RzE/MHaYmialM87
 W4W/aHxJH/Nsz9hi13FWE4CpbRYbg2hEBsQhaQV/Uvf4htxYZ+H0ItZGMm/Lsjk4
 31eCbgH4yOP2DaQi5KRtvZauKMptqWOo+3ymjDGDi7soQe2qRa5BFsH8cz9/2lDk
 hxLk/mGKB4jfnkAaOv5dc0CTcYsnuQ==
 =V+qH
 -----END PGP SIGNATURE-----

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

Pull mtd updates from Miquel Raynal:
 "The main set of changes is related to Uwe's work converting platform
  remove callbacks to return void. Comes next (in number of changes)
  Kees' additional structures annotations to improve the sanitizers. The
  usual amount of cleanups apply.

  About the more substancial contribution, one main function of the
  partitions core could return an error which was not checked, this is
  now fixed. On the bindings side, fixed partitions can now have a
  compression property. Finally, an erroneous situation is now always
  avoided in the MAP RAM driver.

  CFI:

   - A several years old byte swap has been fixed.

  NAND:

   - The subsystem has, as usual, seen a bit of cleanup being done this
     cycle, typically return values of platform_get_irq() and
     devm_kasprintf(). There is also a better ECC check in the Arasan
     driver. This comes with smaller misc changes.

   - In the SPI-NAND world there is now support for Foresee F35SQA002G,
     Winbond W25N and XTX XT26 chips.

  SPI NOR:

   - For SPI NOR we cleaned the flash info entries in order to have them
     slimmer and self explanatory. In order to make the entries as slim
     as possible, we introduced sane default values so that the actual
     flash entries don't need to specify them. We now use a flexible
     macro to specify the flash ID instead of the previous INFOx()
     macros that had hardcoded ID lengths.

     Instead of:

         { "w25q512nwm", INFO(0xef8020, 0, 64 * 1024, 0)
                 OTP_INFO(256, 3, 0x1000, 0x1000) },

     We now use:

         .id = SNOR_ID(0xef, 0x80, 0x20),
         .name = "w25q512nwm",
         .otp = SNOR_OTP(256, 3, 0x1000, 0x1000),

   - We also removed some flash entries: the very old Catalyst SPI
     EEPROMs that were introduced once with the SPI-NOR subsystem, and a
     Fujitsu MRAM. Both should use the at25 EEPROM driver. The latter
     even has device tree bindings for the at25 driver.

   - We made sure that the conversion didn't introduce any unwanted
     changes by comparing the .rodata segment before and after the
     conversion. The patches landed in linux-next immediately after
     v6.6-rc2, we haven't seen any regressions yet.

   - Apart of the autumn cleaning we introduced a new flash entry,
     at25ff321a, and added block protection support for mt25qu512a"

* tag 'mtd/for-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (91 commits)
  mtd: cfi_cmdset_0001: Byte swap OTP info
  mtd: rawnand: meson: check return value of devm_kasprintf()
  mtd: rawnand: intel: check return value of devm_kasprintf()
  mtd: rawnand: sh_flctl: Convert to module_platform_driver()
  mtd: spi-nor: micron-st: use SFDP table for mt25qu512a
  mtd: spi-nor: micron-st: enable lock/unlock for mt25qu512a
  mtd: rawnand: Remove unused of_gpio.h inclusion
  mtd: spinand: Add support for XTX XT26xxxDxxxxx
  mtd: spinand: winbond: add support for serial NAND flash
  mtd: rawnand: cadence: Annotate struct cdns_nand_chip with __counted_by
  mtd: rawnand: Annotate struct mtk_nfc_nand_chip with __counted_by
  mtd: spinand: add support for FORESEE F35SQA002G
  mtd: rawnand: rockchip: Use struct_size()
  mtd: rawnand: arasan: Include ECC syndrome along with in-band data while checking for ECC failure
  mtd: Use device_get_match_data()
  mtd: spi-nor: nxp-spifi: Convert to platform remove callback returning void
  mtd: spi-nor: hisi-sfc: Convert to platform remove callback returning void
  mtd: maps: sun_uflash: Convert to platform remove callback returning void
  mtd: maps: sa1100-flash: Convert to platform remove callback returning void
  mtd: maps: pxa2xx-flash: Convert to platform remove callback returning void
  ...
This commit is contained in:
Linus Torvalds 2023-11-04 11:04:30 -10:00
commit b1dfbda863
71 changed files with 1819 additions and 988 deletions

View File

@ -29,6 +29,24 @@ properties:
"#size-cells": true
compression:
$ref: /schemas/types.yaml#/definitions/string
description: |
Compression algorithm used to store the data in this partition, chosen
from a list of well-known algorithms.
The contents are compressed using this algorithm.
enum:
- none
- bzip2
- gzip
- lzop
- lz4
- lzma
- xz
- zstd
patternProperties:
"@[0-9a-f]+$":
$ref: partition.yaml#
@ -64,6 +82,7 @@ examples:
uimage@100000 {
reg = <0x0100000 0x200000>;
compress = "lzma";
};
};

View File

@ -422,9 +422,25 @@ read_pri_intelext(struct map_info *map, __u16 adr)
extra_size = 0;
/* Protection Register info */
if (extp->NumProtectionFields)
if (extp->NumProtectionFields) {
struct cfi_intelext_otpinfo *otp =
(struct cfi_intelext_otpinfo *)&extp->extra[0];
extra_size += (extp->NumProtectionFields - 1) *
sizeof(struct cfi_intelext_otpinfo);
sizeof(struct cfi_intelext_otpinfo);
if (extp_size >= sizeof(*extp) + extra_size) {
int i;
/* Do some byteswapping if necessary */
for (i = 0; i < extp->NumProtectionFields - 1; i++) {
otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr);
otp->FactGroups = le16_to_cpu(otp->FactGroups);
otp->UserGroups = le16_to_cpu(otp->UserGroups);
otp++;
}
}
}
}
if (extp->MinorVersion >= '1') {

View File

@ -70,12 +70,16 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->_read = mapram_read;
mtd->_write = mapram_write;
mtd->_panic_write = mapram_write;
mtd->_point = mapram_point;
mtd->_sync = mapram_nop;
mtd->_unpoint = mapram_unpoint;
mtd->flags = MTD_CAP_RAM;
mtd->writesize = 1;
/* Disable direct access when NO_XIP is set */
if (map->phys != NO_XIP) {
mtd->_point = mapram_point;
mtd->_unpoint = mapram_unpoint;
}
mtd->erasesize = PAGE_SIZE;
while(mtd->size & (mtd->erasesize - 1))
mtd->erasesize >>= 1;

View File

@ -357,19 +357,17 @@ static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
return 0;
}
static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
static void bcm47xxsflash_bcma_remove(struct platform_device *pdev)
{
struct bcm47xxsflash *b47s = platform_get_drvdata(pdev);
mtd_device_unregister(&b47s->mtd);
iounmap(b47s->window);
return 0;
}
static struct platform_driver bcma_sflash_driver = {
.probe = bcm47xxsflash_bcma_probe,
.remove = bcm47xxsflash_bcma_remove,
.remove_new = bcm47xxsflash_bcma_remove,
.driver = {
.name = "bcma_sflash",
},

View File

@ -2046,7 +2046,7 @@ err_probe:
*
* Returns 0
*/
static int docg3_release(struct platform_device *pdev)
static void docg3_release(struct platform_device *pdev)
{
struct docg3_cascade *cascade = platform_get_drvdata(pdev);
struct docg3 *docg3 = cascade->floors[0]->priv;
@ -2058,7 +2058,6 @@ static int docg3_release(struct platform_device *pdev)
doc_release_device(cascade->floors[floor]);
bch_free(docg3->cascade->bch);
return 0;
}
#ifdef CONFIG_OF
@ -2076,7 +2075,7 @@ static struct platform_driver g3_driver = {
},
.suspend = docg3_suspend,
.resume = docg3_resume,
.remove = docg3_release,
.remove_new = docg3_release,
};
module_platform_driver_probe(g3_driver, docg3_probe);

View File

@ -388,20 +388,18 @@ static int phram_probe(struct platform_device *pdev)
PAGE_SIZE);
}
static int phram_remove(struct platform_device *pdev)
static void phram_remove(struct platform_device *pdev)
{
struct phram_mtd_list *phram = platform_get_drvdata(pdev);
mtd_device_unregister(&phram->mtd);
phram_unmap(phram);
kfree(phram);
return 0;
}
static struct platform_driver phram_driver = {
.probe = phram_probe,
.remove = phram_remove,
.remove_new = phram_remove,
.driver = {
.name = "phram",
.of_match_table = of_match_ptr(phram_of_match),

View File

@ -265,14 +265,12 @@ static int powernv_flash_probe(struct platform_device *pdev)
*
* Returns 0
*/
static int powernv_flash_release(struct platform_device *pdev)
static void powernv_flash_release(struct platform_device *pdev)
{
struct powernv_flash *data = dev_get_drvdata(&(pdev->dev));
/* All resources should be freed automatically */
WARN_ON(mtd_device_unregister(&data->mtd));
return 0;
}
static const struct of_device_id powernv_flash_match[] = {
@ -285,7 +283,7 @@ static struct platform_driver powernv_flash_driver = {
.name = "powernv_flash",
.of_match_table = powernv_flash_match,
},
.remove = powernv_flash_release,
.remove_new = powernv_flash_release,
.probe = powernv_flash_probe,
};

View File

@ -1031,7 +1031,7 @@ err:
*
* free all allocations and delete the partitions.
*/
static int spear_smi_remove(struct platform_device *pdev)
static void spear_smi_remove(struct platform_device *pdev)
{
struct spear_smi *dev;
struct spear_snor_flash *flash;
@ -1048,8 +1048,6 @@ static int spear_smi_remove(struct platform_device *pdev)
/* clean up mtd stuff */
WARN_ON(mtd_device_unregister(&flash->mtd));
}
return 0;
}
#ifdef CONFIG_PM_SLEEP
@ -1095,7 +1093,7 @@ static struct platform_driver spear_smi_driver = {
.pm = &spear_smi_pm_ops,
},
.probe = spear_smi_probe,
.remove = spear_smi_remove,
.remove_new = spear_smi_remove,
};
module_platform_driver(spear_smi_driver);

View File

@ -2097,13 +2097,11 @@ static int stfsm_probe(struct platform_device *pdev)
return mtd_device_register(&fsm->mtd, NULL, 0);
}
static int stfsm_remove(struct platform_device *pdev)
static void stfsm_remove(struct platform_device *pdev)
{
struct stfsm *fsm = platform_get_drvdata(pdev);
WARN_ON(mtd_device_unregister(&fsm->mtd));
return 0;
}
#ifdef CONFIG_PM_SLEEP
@ -2134,7 +2132,7 @@ MODULE_DEVICE_TABLE(of, stfsm_match);
static struct platform_driver stfsm_driver = {
.probe = stfsm_probe,
.remove = stfsm_remove,
.remove_new = stfsm_remove,
.driver = {
.name = "st-spi-fsm",
.of_match_table = stfsm_match,

View File

@ -229,7 +229,7 @@ disable_mux:
return ret;
}
static int am654_hbmc_remove(struct platform_device *pdev)
static void am654_hbmc_remove(struct platform_device *pdev)
{
struct am654_hbmc_priv *priv = platform_get_drvdata(pdev);
struct am654_hbmc_device_priv *dev_priv = priv->hbdev.priv;
@ -241,8 +241,6 @@ static int am654_hbmc_remove(struct platform_device *pdev)
if (dev_priv->rx_chan)
dma_release_channel(dev_priv->rx_chan);
return 0;
}
static const struct of_device_id am654_hbmc_dt_ids[] = {
@ -256,7 +254,7 @@ MODULE_DEVICE_TABLE(of, am654_hbmc_dt_ids);
static struct platform_driver am654_hbmc_platform_driver = {
.probe = am654_hbmc_probe,
.remove = am654_hbmc_remove,
.remove_new = am654_hbmc_remove,
.driver = {
.name = "hbmc-am654",
.of_match_table = am654_hbmc_dt_ids,

View File

@ -154,20 +154,18 @@ out_disable_rpm:
return error;
}
static int rpcif_hb_remove(struct platform_device *pdev)
static void rpcif_hb_remove(struct platform_device *pdev)
{
struct rpcif_hyperbus *hyperbus = platform_get_drvdata(pdev);
hyperbus_unregister_device(&hyperbus->hbdev);
pm_runtime_disable(hyperbus->rpc.dev);
return 0;
}
static struct platform_driver rpcif_platform_driver = {
.probe = rpcif_hb_probe,
.remove = rpcif_hb_remove,
.remove_new = rpcif_hb_remove,
.driver = {
.name = "rpc-if-hyperflash",
},

View File

@ -476,11 +476,9 @@ static int lpddr2_nvm_probe(struct platform_device *pdev)
/*
* lpddr2_nvm driver remove method
*/
static int lpddr2_nvm_remove(struct platform_device *pdev)
static void lpddr2_nvm_remove(struct platform_device *pdev)
{
WARN_ON(mtd_device_unregister(dev_get_drvdata(&pdev->dev)));
return 0;
}
/* Initialize platform_driver data structure for lpddr2_nvm */
@ -489,7 +487,7 @@ static struct platform_driver lpddr2_nvm_drv = {
.name = "lpddr2_nvm",
},
.probe = lpddr2_nvm_probe,
.remove = lpddr2_nvm_remove,
.remove_new = lpddr2_nvm_remove,
};
module_platform_driver(lpddr2_nvm_drv);

View File

@ -61,7 +61,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
mtd->_point = lpddr_point;
mtd->_unpoint = lpddr_unpoint;
}
mtd->size = 1 << lpddr->qinfo->DevSizeShift;
mtd->size = 1ULL << lpddr->qinfo->DevSizeShift;
mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift;
mtd->writesize = 1 << lpddr->qinfo->BufSizeShift;

View File

@ -166,8 +166,7 @@ err_destroy:
return err;
}
static int
ltq_mtd_remove(struct platform_device *pdev)
static void ltq_mtd_remove(struct platform_device *pdev)
{
struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
@ -175,7 +174,6 @@ ltq_mtd_remove(struct platform_device *pdev)
mtd_device_unregister(ltq_mtd->mtd);
map_destroy(ltq_mtd->mtd);
}
return 0;
}
static const struct of_device_id ltq_mtd_match[] = {
@ -186,7 +184,7 @@ MODULE_DEVICE_TABLE(of, ltq_mtd_match);
static struct platform_driver ltq_mtd_driver = {
.probe = ltq_mtd_probe,
.remove = ltq_mtd_remove,
.remove_new = ltq_mtd_remove,
.driver = {
.name = "ltq-nor",
.of_match_table = ltq_mtd_match,

View File

@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
@ -37,7 +38,7 @@
#include <linux/mtd/concat.h>
#include <linux/mtd/cfi_endian.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/gpio/consumer.h>
@ -62,7 +63,7 @@ struct physmap_flash_info {
unsigned int win_order;
};
static int physmap_flash_remove(struct platform_device *dev)
static void physmap_flash_remove(struct platform_device *dev)
{
struct physmap_flash_info *info;
struct physmap_flash_data *physmap_data;
@ -88,7 +89,6 @@ static int physmap_flash_remove(struct platform_device *dev)
pm_runtime_put(&dev->dev);
pm_runtime_disable(&dev->dev);
return 0;
}
static void physmap_set_vpp(struct map_info *map, int state)
@ -296,14 +296,9 @@ static const char * const *of_get_part_probes(struct platform_device *dev)
static const char *of_select_probe_type(struct platform_device *dev)
{
struct device_node *dp = dev->dev.of_node;
const struct of_device_id *match;
const char *probe_type;
match = of_match_device(of_flash_match, &dev->dev);
if (!match)
return NULL;
probe_type = match->data;
probe_type = device_get_match_data(&dev->dev);
if (probe_type)
return probe_type;
@ -626,7 +621,7 @@ static void physmap_flash_shutdown(struct platform_device *dev)
static struct platform_driver physmap_flash_driver = {
.probe = physmap_flash_probe,
.remove = physmap_flash_remove,
.remove_new = physmap_flash_remove,
.shutdown = physmap_flash_shutdown,
.driver = {
.name = "physmap-flash",

View File

@ -65,14 +65,14 @@ static inline void platram_setrw(struct platram_info *info, int to)
* called to remove the device from the driver's control
*/
static int platram_remove(struct platform_device *pdev)
static void platram_remove(struct platform_device *pdev)
{
struct platram_info *info = to_platram_info(pdev);
dev_dbg(&pdev->dev, "removing device\n");
if (info == NULL)
return 0;
return;
if (info->mtd) {
mtd_device_unregister(info->mtd);
@ -84,8 +84,6 @@ static int platram_remove(struct platform_device *pdev)
platram_setrw(info, PLATRAM_RO);
kfree(info);
return 0;
}
/* platram_probe
@ -207,7 +205,7 @@ MODULE_ALIAS("platform:mtd-ram");
static struct platform_driver platram_driver = {
.probe = platram_probe,
.remove = platram_remove,
.remove_new = platram_remove,
.driver = {
.name = "mtd-ram",
},

View File

@ -98,7 +98,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
return 0;
}
static int pxa2xx_flash_remove(struct platform_device *dev)
static void pxa2xx_flash_remove(struct platform_device *dev)
{
struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
@ -109,7 +109,6 @@ static int pxa2xx_flash_remove(struct platform_device *dev)
if (info->map.cached)
iounmap(info->map.cached);
kfree(info);
return 0;
}
#ifdef CONFIG_PM
@ -129,7 +128,7 @@ static struct platform_driver pxa2xx_flash_driver = {
.name = "pxa2xx-flash",
},
.probe = pxa2xx_flash_probe,
.remove = pxa2xx_flash_remove,
.remove_new = pxa2xx_flash_remove,
.shutdown = pxa2xx_flash_shutdown,
};

View File

@ -285,19 +285,17 @@ static int sa1100_mtd_probe(struct platform_device *pdev)
return err;
}
static int sa1100_mtd_remove(struct platform_device *pdev)
static void sa1100_mtd_remove(struct platform_device *pdev)
{
struct sa_info *info = platform_get_drvdata(pdev);
struct flash_platform_data *plat = dev_get_platdata(&pdev->dev);
sa1100_destroy(info, plat);
return 0;
}
static struct platform_driver sa1100_mtd_driver = {
.probe = sa1100_mtd_probe,
.remove = sa1100_mtd_remove,
.remove_new = sa1100_mtd_remove,
.driver = {
.name = "sa1100-mtd",
},

View File

@ -118,7 +118,7 @@ static int uflash_probe(struct platform_device *op)
return uflash_devinit(op, dp);
}
static int uflash_remove(struct platform_device *op)
static void uflash_remove(struct platform_device *op)
{
struct uflash_dev *up = dev_get_drvdata(&op->dev);
@ -132,8 +132,6 @@ static int uflash_remove(struct platform_device *op)
}
kfree(up);
return 0;
}
static const struct of_device_id uflash_match[] = {
@ -151,7 +149,7 @@ static struct platform_driver uflash_driver = {
.of_match_table = uflash_match,
},
.probe = uflash_probe,
.remove = uflash_remove,
.remove_new = uflash_remove,
};
module_platform_driver(uflash_driver);

View File

@ -1506,6 +1506,8 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
ret = mtd_read_oob(mtd, from, &ops);
*retlen = ops.retlen;
WARN_ON_ONCE(*retlen != len && mtd_is_bitflip_or_eccerr(ret));
return ret;
}
EXPORT_SYMBOL_GPL(mtd_read);

View File

@ -426,7 +426,11 @@ int add_mtd_partitions(struct mtd_info *parent,
mtd_add_partition_attrs(child);
/* Look for subpartitions */
parse_mtd_partitions(child, parts[i].types, NULL);
ret = parse_mtd_partitions(child, parts[i].types, NULL);
if (ret < 0) {
pr_err("Failed to parse subpartitions: %d\n", ret);
goto err_del_partitions;
}
cur_offset = child->part.offset + child->part.size;
}

View File

@ -481,7 +481,7 @@ static int anfc_read_page_hw_ecc(struct nand_chip *chip, u8 *buf,
}
bf = nand_check_erased_ecc_chunk(raw_buf, chip->ecc.size,
NULL, 0, NULL, 0,
anand->hw_ecc, chip->ecc.bytes, NULL, 0,
chip->ecc.strength);
if (bf > 0) {
mtd->ecc_stats.corrected += bf;

View File

@ -165,7 +165,7 @@ struct atmel_nand {
struct atmel_pmecc_user *pmecc;
struct gpio_desc *cdgpio;
int numcs;
struct atmel_nand_cs cs[];
struct atmel_nand_cs cs[] __counted_by(numcs);
};
static inline struct atmel_nand *to_atmel_nand(struct nand_chip *chip)

View File

@ -15,8 +15,10 @@
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/of_device.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
/*
@ -526,7 +528,7 @@ struct cdns_nand_chip {
/* ECC strength index. */
u8 corr_str_idx;
u8 cs[];
u8 cs[] __counted_by(nsels);
};
struct ecc_info {
@ -2995,15 +2997,11 @@ static int cadence_nand_dt_probe(struct platform_device *ofdev)
struct cadence_nand_dt *dt;
struct cdns_nand_ctrl *cdns_ctrl;
int ret;
const struct of_device_id *of_id;
const struct cadence_nand_dt_devdata *devdata;
u32 val;
of_id = of_match_device(cadence_nand_dt_ids, &ofdev->dev);
if (of_id) {
ofdev->id_entry = of_id->data;
devdata = of_id->data;
} else {
devdata = device_get_match_data(&ofdev->dev);
if (!devdata) {
pr_err("Failed to find the right device id.\n");
return -ENOMEM;
}

View File

@ -328,7 +328,7 @@ struct denali_chip {
struct nand_chip chip;
struct list_head node;
unsigned int nsels;
struct denali_chip_sel sels[];
struct denali_chip_sel sels[] __counted_by(nsels);
};
/**

View File

@ -46,7 +46,7 @@ struct ingenic_nfc {
struct nand_controller controller;
unsigned int num_banks;
struct list_head chips;
struct ingenic_nand_cs cs[];
struct ingenic_nand_cs cs[] __counted_by(num_banks);
};
struct ingenic_nand {

View File

@ -619,6 +619,11 @@ static int ebu_nand_probe(struct platform_device *pdev)
ebu_host->cs_num = cs;
resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
if (!resname) {
ret = -ENOMEM;
goto err_of_node_put;
}
ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
resname);
if (IS_ERR(ebu_host->cs[cs].chipaddr)) {
@ -649,6 +654,11 @@ static int ebu_nand_probe(struct platform_device *pdev)
}
resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs);
if (!resname) {
ret = -ENOMEM;
goto err_cleanup_dma;
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
if (!res) {
ret = -EINVAL;

View File

@ -106,7 +106,6 @@ int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf,
int oob_required, int page);
int nand_write_page_raw_notsupp(struct nand_chip *chip, const u8 *buf,
int oob_required, int page);
int nand_exit_status_op(struct nand_chip *chip);
int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
unsigned int len);
void nand_decode_ext_id(struct nand_chip *chip);

View File

@ -348,7 +348,7 @@ struct marvell_nand_chip {
int addr_cyc;
int selected_die;
unsigned int nsels;
struct marvell_nand_chip_sel sels[];
struct marvell_nand_chip_sel sels[] __counted_by(nsels);
};
static inline struct marvell_nand_chip *to_marvell_nand(struct nand_chip *chip)

View File

@ -128,7 +128,7 @@ struct meson_nfc_nand_chip {
u8 *data_buf;
__le64 *info_buf;
u32 nsels;
u8 sels[];
u8 sels[] __counted_by(nsels);
};
struct meson_nand_ecc {
@ -1134,6 +1134,9 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
init.name = devm_kasprintf(nfc->dev,
GFP_KERNEL, "%s#div",
dev_name(nfc->dev));
if (!init.name)
return -ENOMEM;
init.ops = &clk_divider_ops;
nfc_divider_parent_data[0].fw_name = "device";
init.parent_data = nfc_divider_parent_data;

View File

@ -130,7 +130,7 @@ struct mtk_nfc_nand_chip {
u32 spare_per_sector;
int nsels;
u8 sels[];
u8 sels[] __counted_by(nsels);
/* nothing after this field */
};

View File

@ -42,7 +42,6 @@
#include <linux/io.h>
#include <linux/mtd/partitions.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include "internals.h"

View File

@ -1881,8 +1881,8 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
case NAND_OMAP_PREFETCH_IRQ:
info->gpmc_irq_fifo = platform_get_irq(info->pdev, 0);
if (info->gpmc_irq_fifo <= 0)
return -ENODEV;
if (info->gpmc_irq_fifo < 0)
return info->gpmc_irq_fifo;
err = devm_request_irq(dev, info->gpmc_irq_fifo,
omap_nand_irq, IRQF_SHARED,
"gpmc-nand-fifo", info);
@ -1894,8 +1894,8 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
}
info->gpmc_irq_count = platform_get_irq(info->pdev, 1);
if (info->gpmc_irq_count <= 0)
return -ENODEV;
if (info->gpmc_irq_count < 0)
return info->gpmc_irq_count;
err = devm_request_irq(dev, info->gpmc_irq_count,
omap_nand_irq, IRQF_SHARED,
"gpmc-nand-count", info);

View File

@ -210,7 +210,7 @@ struct rnand_chip {
u32 tim_gen_seq1;
u32 tim_gen_seq2;
u32 tim_gen_seq3;
struct rnand_chip_sel sels[];
struct rnand_chip_sel sels[] __counted_by(nsels);
};
struct rnandc {

View File

@ -158,8 +158,7 @@ struct rk_nfc_nand_chip {
u32 timing;
u8 nsels;
u8 sels[];
/* Nothing after this field. */
u8 sels[] __counted_by(nsels);
};
struct rk_nfc {
@ -1119,7 +1118,7 @@ static int rk_nfc_nand_chip_init(struct device *dev, struct rk_nfc *nfc,
return -EINVAL;
}
rknand = devm_kzalloc(dev, sizeof(*rknand) + nsels * sizeof(u8),
rknand = devm_kzalloc(dev, struct_size(rknand, sels, nsels),
GFP_KERNEL);
if (!rknand)
return -ENOMEM;

View File

@ -1215,6 +1215,7 @@ static void flctl_remove(struct platform_device *pdev)
}
static struct platform_driver flctl_driver = {
.probe = flctl_probe,
.remove_new = flctl_remove,
.driver = {
.name = "sh_flctl",
@ -1222,7 +1223,7 @@ static struct platform_driver flctl_driver = {
},
};
module_platform_driver_probe(flctl_driver, flctl_probe);
module_platform_driver(flctl_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Yoshihiro Shimoda");

View File

@ -197,7 +197,7 @@ struct sunxi_nand_chip {
u32 timing_cfg;
u32 timing_ctl;
int nsels;
struct sunxi_nand_chip_sel sels[];
struct sunxi_nand_chip_sel sels[] __counted_by(nsels);
};
static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)

View File

@ -1197,6 +1197,10 @@ static int tegra_nand_probe(struct platform_device *pdev)
init_completion(&ctrl->dma_complete);
ctrl->irq = platform_get_irq(pdev, 0);
if (ctrl->irq < 0) {
err = ctrl->irq;
goto err_put_pm;
}
err = devm_request_irq(&pdev->dev, ctrl->irq, tegra_nand_irq, 0,
dev_name(&pdev->dev), ctrl);
if (err) {

View File

@ -29,8 +29,9 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/swab.h>
@ -810,7 +811,6 @@ static int vf610_nfc_probe(struct platform_device *pdev)
struct mtd_info *mtd;
struct nand_chip *chip;
struct device_node *child;
const struct of_device_id *of_id;
int err;
int irq;
@ -840,12 +840,10 @@ static int vf610_nfc_probe(struct platform_device *pdev)
return PTR_ERR(nfc->clk);
}
of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev);
if (!of_id)
nfc->variant = (enum vf610_nfc_variant)device_get_match_data(&pdev->dev);
if (!nfc->variant)
return -ENODEV;
nfc->variant = (uintptr_t)of_id->data;
for_each_available_child_of_node(nfc->dev->of_node, child) {
if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) {

View File

@ -6,7 +6,6 @@
*/
#include <linux/mtd/rawnand.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/platform_device.h>

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
spinand-objs := core.o alliancememory.o ato.o esmt.o gigadevice.o macronix.o
spinand-objs := core.o alliancememory.o ato.o esmt.o foresee.o gigadevice.o macronix.o
spinand-objs += micron.o paragon.o toshiba.o winbond.o xtx.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o

View File

@ -940,6 +940,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = {
&alliancememory_spinand_manufacturer,
&ato_spinand_manufacturer,
&esmt_c8_spinand_manufacturer,
&foresee_spinand_manufacturer,
&gigadevice_spinand_manufacturer,
&macronix_spinand_manufacturer,
&micron_spinand_manufacturer,

View File

@ -0,0 +1,95 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023, SberDevices. All Rights Reserved.
*
* Author: Martin Kurbanov <mmkurbanov@salutedevices.com>
*/
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mtd/spinand.h>
#define SPINAND_MFR_FORESEE 0xCD
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
SPINAND_PROG_LOAD(true, 0, NULL, 0));
static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
SPINAND_PROG_LOAD(false, 0, NULL, 0));
static int f35sqa002g_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
return -ERANGE;
}
static int f35sqa002g_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
/* Reserve 2 bytes for the BBM. */
region->offset = 2;
region->length = 62;
return 0;
}
static const struct mtd_ooblayout_ops f35sqa002g_ooblayout = {
.ecc = f35sqa002g_ooblayout_ecc,
.free = f35sqa002g_ooblayout_free,
};
static int f35sqa002g_ecc_get_status(struct spinand_device *spinand, u8 status)
{
struct nand_device *nand = spinand_to_nand(spinand);
switch (status & STATUS_ECC_MASK) {
case STATUS_ECC_NO_BITFLIPS:
return 0;
case STATUS_ECC_HAS_BITFLIPS:
return nanddev_get_ecc_conf(nand)->strength;
default:
break;
}
/* More than 1-bit error was detected in one or more sectors and
* cannot be corrected.
*/
return -EBADMSG;
}
static const struct spinand_info foresee_spinand_table[] = {
SPINAND_INFO("F35SQA002G",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x72, 0x72),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&f35sqa002g_ooblayout,
f35sqa002g_ecc_get_status)),
};
static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = {
};
const struct spinand_manufacturer foresee_spinand_manufacturer = {
.id = SPINAND_MFR_FORESEE,
.name = "FORESEE",
.chips = foresee_spinand_table,
.nchips = ARRAY_SIZE(foresee_spinand_table),
.ops = &foresee_spinand_manuf_ops,
};

View File

@ -169,6 +169,51 @@ static const struct spinand_info winbond_spinand_table[] = {
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
SPINAND_INFO("W25N01JW",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
SPINAND_INFO("W25N02JWZEIF",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
SPINAND_INFO("W25N512GW",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x20),
NAND_MEMORG(1, 2048, 64, 64, 512, 10, 1, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
SPINAND_INFO("W25N02KWZEIR",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
SPINAND_INFO("W25N01GWZEIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
};
static int winbond_spinand_init(struct spinand_device *spinand)

View File

@ -4,6 +4,7 @@
* Felix Matouschek <felix@matouschek.org>
*/
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mtd/spinand.h>
@ -15,6 +16,12 @@
#define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
#define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4)
#define XT26XXXD_STATUS_ECC3_ECC2_MASK GENMASK(7, 6)
#define XT26XXXD_STATUS_ECC_NO_DETECTED (0)
#define XT26XXXD_STATUS_ECC_1_7_CORRECTED (1)
#define XT26XXXD_STATUS_ECC_8_CORRECTED (3)
#define XT26XXXD_STATUS_ECC_UNCOR_ERROR (2)
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
@ -84,6 +91,53 @@ static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
return status >> 2;
}
static int xt26xxxd_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
region->offset = mtd->oobsize / 2;
region->length = mtd->oobsize / 2;
return 0;
}
static int xt26xxxd_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
region->offset = 2;
region->length = mtd->oobsize / 2 - 2;
return 0;
}
static const struct mtd_ooblayout_ops xt26xxxd_ooblayout = {
.ecc = xt26xxxd_ooblayout_ecc,
.free = xt26xxxd_ooblayout_free,
};
static int xt26xxxd_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
switch (FIELD_GET(STATUS_ECC_MASK, status)) {
case XT26XXXD_STATUS_ECC_NO_DETECTED:
return 0;
case XT26XXXD_STATUS_ECC_UNCOR_ERROR:
return -EBADMSG;
case XT26XXXD_STATUS_ECC_1_7_CORRECTED:
return 4 + FIELD_GET(XT26XXXD_STATUS_ECC3_ECC2_MASK, status);
case XT26XXXD_STATUS_ECC_8_CORRECTED:
return 8;
default:
break;
}
return -EINVAL;
}
static const struct spinand_info xtx_spinand_table[] = {
SPINAND_INFO("XT26G01A",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
@ -115,6 +169,86 @@ static const struct spinand_info xtx_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&xt26g0xa_ooblayout,
xt26g0xa_ecc_get_status)),
SPINAND_INFO("XT26G01D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x31),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26G11D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x34),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26Q01D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26G02D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x32),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26G12D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x35),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26Q02D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26G04D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x33),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
SPINAND_INFO("XT26Q04D",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x53),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
SPINAND_ECCINFO(&xt26xxxd_ooblayout,
xt26xxxd_ecc_get_status)),
};
static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {

View File

@ -2,11 +2,9 @@
spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o
spi-nor-objs += atmel.o
spi-nor-objs += catalyst.o
spi-nor-objs += eon.o
spi-nor-objs += esmt.o
spi-nor-objs += everspin.o
spi-nor-objs += fujitsu.o
spi-nor-objs += gigadevice.o
spi-nor-objs += intel.o
spi-nor-objs += issi.o

View File

@ -163,49 +163,84 @@ static const struct spi_nor_fixups atmel_nor_global_protection_fixups = {
};
static const struct flash_info atmel_nor_parts[] = {
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
{ "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &at25fs_nor_fixups },
{ "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &at25fs_nor_fixups },
{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at25sl321", INFO(0x1f4216, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K) },
{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
.fixups = &atmel_nor_global_protection_fixups },
{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K) },
{
.id = SNOR_ID(0x1f, 0x04, 0x00),
.name = "at26f004",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x1f, 0x25, 0x00),
.name = "at45db081d",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x1f, 0x42, 0x16),
.name = "at25sl321",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x1f, 0x44, 0x01),
.name = "at25df041a",
.size = SZ_512K,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.fixups = &atmel_nor_global_protection_fixups,
}, {
.id = SNOR_ID(0x1f, 0x45, 0x01),
.name = "at26df081a",
.size = SZ_1M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.fixups = &atmel_nor_global_protection_fixups
}, {
.id = SNOR_ID(0x1f, 0x46, 0x01),
.name = "at26df161a",
.size = SZ_2M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.fixups = &atmel_nor_global_protection_fixups
}, {
.id = SNOR_ID(0x1f, 0x47, 0x00),
.name = "at25df321",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.fixups = &atmel_nor_global_protection_fixups
}, {
.id = SNOR_ID(0x1f, 0x47, 0x01),
.name = "at25df321a",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.fixups = &atmel_nor_global_protection_fixups
}, {
.id = SNOR_ID(0x1f, 0x47, 0x08),
.name = "at25ff321a",
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.fixups = &atmel_nor_global_protection_fixups
}, {
.id = SNOR_ID(0x1f, 0x48, 0x00),
.name = "at25df641",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.fixups = &atmel_nor_global_protection_fixups
}, {
.id = SNOR_ID(0x1f, 0x66, 0x01),
.name = "at25fs010",
.sector_size = SZ_32K,
.size = SZ_128K,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SECT_4K,
.fixups = &at25fs_nor_fixups
}, {
.id = SNOR_ID(0x1f, 0x66, 0x04),
.name = "at25fs040",
.size = SZ_512K,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SECT_4K,
.fixups = &at25fs_nor_fixups
},
};
const struct spi_nor_manufacturer spi_nor_atmel = {

View File

@ -1,24 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2005, Intec Automation Inc.
* Copyright (C) 2014, Freescale Semiconductor, Inc.
*/
#include <linux/mtd/spi-nor.h>
#include "core.h"
static const struct flash_info catalyst_nor_parts[] = {
/* Catalyst / On Semiconductor -- non-JEDEC */
{ "cat25c11", CAT25_INFO(16, 8, 16, 1) },
{ "cat25c03", CAT25_INFO(32, 8, 16, 2) },
{ "cat25c09", CAT25_INFO(128, 8, 32, 2) },
{ "cat25c17", CAT25_INFO(256, 8, 32, 2) },
{ "cat25128", CAT25_INFO(2048, 8, 64, 2) },
};
const struct spi_nor_manufacturer spi_nor_catalyst = {
.name = "catalyst",
.parts = catalyst_nor_parts,
.nparts = ARRAY_SIZE(catalyst_nor_parts),
};

View File

@ -468,13 +468,12 @@ static int hisi_spi_nor_probe(struct platform_device *pdev)
return ret;
}
static int hisi_spi_nor_remove(struct platform_device *pdev)
static void hisi_spi_nor_remove(struct platform_device *pdev)
{
struct hifmc_host *host = platform_get_drvdata(pdev);
hisi_spi_nor_unregister_all(host);
mutex_destroy(&host->lock);
return 0;
}
static const struct of_device_id hisi_spi_nor_dt_ids[] = {
@ -489,7 +488,7 @@ static struct platform_driver hisi_spi_nor_driver = {
.of_match_table = hisi_spi_nor_dt_ids,
},
.probe = hisi_spi_nor_probe,
.remove = hisi_spi_nor_remove,
.remove_new = hisi_spi_nor_remove,
};
module_platform_driver(hisi_spi_nor_driver);

View File

@ -431,13 +431,11 @@ static int nxp_spifi_probe(struct platform_device *pdev)
return 0;
}
static int nxp_spifi_remove(struct platform_device *pdev)
static void nxp_spifi_remove(struct platform_device *pdev)
{
struct nxp_spifi *spifi = platform_get_drvdata(pdev);
mtd_device_unregister(&spifi->nor.mtd);
return 0;
}
static const struct of_device_id nxp_spifi_match[] = {
@ -448,7 +446,7 @@ MODULE_DEVICE_TABLE(of, nxp_spifi_match);
static struct platform_driver nxp_spifi_driver = {
.probe = nxp_spifi_probe,
.remove = nxp_spifi_remove,
.remove_new = nxp_spifi_remove,
.driver = {
.name = "nxp-spifi",
.of_match_table = nxp_spifi_match,

View File

@ -1999,11 +1999,9 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
static const struct spi_nor_manufacturer *manufacturers[] = {
&spi_nor_atmel,
&spi_nor_catalyst,
&spi_nor_eon,
&spi_nor_esmt,
&spi_nor_everspin,
&spi_nor_fujitsu,
&spi_nor_gigadevice,
&spi_nor_intel,
&spi_nor_issi,
@ -2019,13 +2017,6 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
static const struct flash_info spi_nor_generic_flash = {
.name = "spi-nor-generic",
.n_banks = 1,
/*
* JESD216 rev A doesn't specify the page size, therefore we need a
* sane default.
*/
.page_size = 256,
.parse_sfdp = true,
};
static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
@ -2037,8 +2028,8 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
for (j = 0; j < manufacturers[i]->nparts; j++) {
part = &manufacturers[i]->parts[j];
if (part->id_len &&
!memcmp(part->id, id, part->id_len)) {
if (part->id &&
!memcmp(part->id->bytes, id, part->id->len)) {
nor->manufacturer = manufacturers[i];
return part;
}
@ -2520,13 +2511,6 @@ static int spi_nor_select_pp(struct spi_nor *nor,
/**
* spi_nor_select_uniform_erase() - select optimum uniform erase type
* @map: the erase map of the SPI NOR
* @wanted_size: the erase type size to search for. Contains the value of
* info->sector_size, the "small sector" size in case
* CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if
* there is no information about the sector size. The
* latter is the case if the flash parameters are parsed
* solely by SFDP, then the largest supported erase type
* is selected.
*
* Once the optimum uniform sector erase command is found, disable all the
* other.
@ -2534,13 +2518,16 @@ static int spi_nor_select_pp(struct spi_nor *nor,
* Return: pointer to erase type on success, NULL otherwise.
*/
static const struct spi_nor_erase_type *
spi_nor_select_uniform_erase(struct spi_nor_erase_map *map,
const u32 wanted_size)
spi_nor_select_uniform_erase(struct spi_nor_erase_map *map)
{
const struct spi_nor_erase_type *tested_erase, *erase = NULL;
int i;
u8 uniform_erase_type = map->uniform_erase_type;
/*
* Search for the biggest erase size, except for when compiled
* to use 4k erases.
*/
for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
if (!(uniform_erase_type & BIT(i)))
continue;
@ -2552,10 +2539,11 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map,
continue;
/*
* If the current erase size is the one, stop here:
* If the current erase size is the 4k one, stop here,
* we have found the right uniform Sector Erase command.
*/
if (tested_erase->size == wanted_size) {
if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS) &&
tested_erase->size == SZ_4K) {
erase = tested_erase;
break;
}
@ -2583,7 +2571,6 @@ static int spi_nor_select_erase(struct spi_nor *nor)
struct spi_nor_erase_map *map = &nor->params->erase_map;
const struct spi_nor_erase_type *erase = NULL;
struct mtd_info *mtd = &nor->mtd;
u32 wanted_size = nor->info->sector_size;
int i;
/*
@ -2594,13 +2581,8 @@ static int spi_nor_select_erase(struct spi_nor *nor)
* manage the SPI flash memory as uniform with a single erase sector
* size, when possible.
*/
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */
wanted_size = 4096u;
#endif
if (spi_nor_has_uniform_erase(nor)) {
erase = spi_nor_select_uniform_erase(map, wanted_size);
erase = spi_nor_select_uniform_erase(map);
if (!erase)
return -EINVAL;
nor->erase_opcode = erase->opcode;
@ -2773,7 +2755,8 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
{
struct spi_nor_flash_parameter *params = nor->params;
struct spi_nor_erase_map *map = &params->erase_map;
const u8 no_sfdp_flags = nor->info->no_sfdp_flags;
const struct flash_info *info = nor->info;
const u8 no_sfdp_flags = info->no_sfdp_flags;
u8 i, erase_mask;
if (no_sfdp_flags & SPI_NOR_DUAL_READ) {
@ -2827,7 +2810,8 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
i++;
}
erase_mask |= BIT(i);
spi_nor_set_erase_type(&map->erase_type[i], nor->info->sector_size,
spi_nor_set_erase_type(&map->erase_type[i],
info->sector_size ?: SPI_NOR_DEFAULT_SECTOR_SIZE,
SPINOR_OP_SE);
spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
}
@ -2869,7 +2853,7 @@ static void spi_nor_init_flags(struct spi_nor *nor)
if (flags & NO_CHIP_ERASE)
nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
if (flags & SPI_NOR_RWW && nor->info->n_banks > 1 &&
if (flags & SPI_NOR_RWW && nor->params->n_banks > 1 &&
!nor->controller_ops)
nor->flags |= SNOR_F_RWW;
}
@ -2933,8 +2917,8 @@ static int spi_nor_late_init_params(struct spi_nor *nor)
if (nor->flags & SNOR_F_HAS_LOCK && !nor->params->locking_ops)
spi_nor_init_default_locking_ops(nor);
if (nor->info->n_banks > 1)
params->bank_size = div64_u64(params->size, nor->info->n_banks);
if (params->n_banks > 1)
params->bank_size = div64_u64(params->size, params->n_banks);
return 0;
}
@ -2994,16 +2978,17 @@ static void spi_nor_init_default_params(struct spi_nor *nor)
struct device_node *np = spi_nor_get_flash_node(nor);
params->quad_enable = spi_nor_sr2_bit1_quad_enable;
params->otp.org = &info->otp_org;
params->otp.org = info->otp;
/* Default to 16-bit Write Status (01h) Command */
nor->flags |= SNOR_F_HAS_16BIT_SR;
/* Set SPI NOR sizes. */
params->writesize = 1;
params->size = (u64)info->sector_size * info->n_sectors;
params->size = info->size;
params->bank_size = params->size;
params->page_size = info->page_size;
params->page_size = info->page_size ?: SPI_NOR_DEFAULT_PAGE_SIZE;
params->n_banks = info->n_banks ?: SPI_NOR_DEFAULT_N_BANKS;
if (!(info->flags & SPI_NOR_NO_FR)) {
/* Default to Fast Read for DT and non-DT platform devices. */
@ -3083,7 +3068,7 @@ static int spi_nor_init_params(struct spi_nor *nor)
spi_nor_init_default_params(nor);
if (nor->info->parse_sfdp) {
if (spi_nor_needs_sfdp(nor)) {
ret = spi_nor_parse_sfdp(nor);
if (ret) {
dev_err(nor->dev, "BFPT parsing failed. Please consider using SPI_NOR_SKIP_SFDP when declaring the flash\n");
@ -3385,7 +3370,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
* If caller has specified name of flash model that can normally be
* detected using JEDEC, let's verify it.
*/
if (name && info->id_len) {
if (name && info->id) {
const struct flash_info *jinfo;
jinfo = spi_nor_detect(nor);

View File

@ -10,6 +10,13 @@
#include "sfdp.h"
#define SPI_NOR_MAX_ID_LEN 6
/*
* 256 bytes is a sane default for most older flashes. Newer flashes will
* have the page size defined within their SFDP tables.
*/
#define SPI_NOR_DEFAULT_PAGE_SIZE 256
#define SPI_NOR_DEFAULT_N_BANKS 1
#define SPI_NOR_DEFAULT_SECTOR_SIZE SZ_64K
/* Standard SPI NOR flash operations. */
#define SPI_NOR_READID_OP(naddr, ndummy, buf, len) \
@ -353,6 +360,7 @@ struct spi_nor_otp {
* in octal DTR mode.
* @rdsr_addr_nbytes: dummy address bytes needed for Read Status Register
* command in octal DTR mode.
* @n_banks: number of banks.
* @n_dice: number of dice in the flash memory.
* @vreg_offset: volatile register offset for each die.
* @hwcaps: describes the read and page program hardware
@ -389,6 +397,7 @@ struct spi_nor_flash_parameter {
u8 addr_mode_nbytes;
u8 rdsr_dummy;
u8 rdsr_addr_nbytes;
u8 n_banks;
u8 n_dice;
u32 *vreg_offset;
@ -437,22 +446,32 @@ struct spi_nor_fixups {
int (*late_init)(struct spi_nor *nor);
};
/**
* struct spi_nor_id - SPI NOR flash ID.
*
* @bytes: the bytes returned by the flash when issuing command 9F. Typically,
* the first byte is the manufacturer ID code (see JEP106) and the next
* two bytes are a flash part specific ID.
* @len: the number of bytes of ID.
*/
struct spi_nor_id {
const u8 *bytes;
u8 len;
};
/**
* struct flash_info - SPI NOR flash_info entry.
* @id: pointer to struct spi_nor_id or NULL, which means "no ID" (mostly
* older chips).
* @name: the name of the flash.
* @id: the flash's ID bytes. The first three bytes are the
* JEDIC ID. JEDEC ID zero means "no ID" (mostly older chips).
* @id_len: the number of bytes of ID.
* @sector_size: the size listed here is what works with SPINOR_OP_SE, which
* isn't necessarily called a "sector" by the vendor.
* @n_sectors: the number of sectors.
* @n_banks: the number of banks.
* @page_size: the flash's page size.
* @size: the size of the flash in bytes.
* @sector_size: (optional) the size listed here is what works with
* SPINOR_OP_SE, which isn't necessarily called a "sector" by
* the vendor. Defaults to 64k.
* @n_banks: (optional) the number of banks. Defaults to 1.
* @page_size: (optional) the flash's page size. Defaults to 256.
* @addr_nbytes: number of address bytes to send.
*
* @parse_sfdp: true when flash supports SFDP tables. The false value has no
* meaning. If one wants to skip the SFDP tables, one should
* instead use the SPI_NOR_SKIP_SFDP sfdp_flag.
* @flags: flags that indicate support that is not defined by the
* JESD216 standard in its SFDP tables. Flag meanings:
* SPI_NOR_HAS_LOCK: flash supports lock/unlock via SR
@ -503,15 +522,13 @@ struct spi_nor_fixups {
*/
struct flash_info {
char *name;
u8 id[SPI_NOR_MAX_ID_LEN];
u8 id_len;
const struct spi_nor_id *id;
size_t size;
unsigned sector_size;
u16 n_sectors;
u16 page_size;
u8 n_banks;
u8 addr_nbytes;
bool parse_sfdp;
u16 flags;
#define SPI_NOR_HAS_LOCK BIT(0)
#define SPI_NOR_HAS_TB BIT(1)
@ -540,70 +557,23 @@ struct flash_info {
u8 mfr_flags;
const struct spi_nor_otp_organization otp_org;
const struct spi_nor_otp_organization *otp;
const struct spi_nor_fixups *fixups;
};
#define SPI_NOR_ID_2ITEMS(_id) ((_id) >> 8) & 0xff, (_id) & 0xff
#define SPI_NOR_ID_3ITEMS(_id) ((_id) >> 16) & 0xff, SPI_NOR_ID_2ITEMS(_id)
#define SNOR_ID(...) \
(&(const struct spi_nor_id){ \
.bytes = (const u8[]){ __VA_ARGS__ }, \
.len = sizeof((u8[]){ __VA_ARGS__ }), \
})
#define SPI_NOR_ID(_jedec_id, _ext_id) \
.id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_2ITEMS(_ext_id) }, \
.id_len = !(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))
#define SPI_NOR_ID6(_jedec_id, _ext_id) \
.id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_3ITEMS(_ext_id) }, \
.id_len = 6
#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors, _n_banks) \
.sector_size = (_sector_size), \
.n_sectors = (_n_sectors), \
.page_size = 256, \
.n_banks = (_n_banks)
/* Used when the "_ext_id" is two bytes at most */
#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors) \
SPI_NOR_ID((_jedec_id), (_ext_id)), \
SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
#define INFOB(_jedec_id, _ext_id, _sector_size, _n_sectors, _n_banks) \
SPI_NOR_ID((_jedec_id), (_ext_id)), \
SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), (_n_banks)),
#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors) \
SPI_NOR_ID6((_jedec_id), (_ext_id)), \
SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_nbytes) \
.sector_size = (_sector_size), \
.n_sectors = (_n_sectors), \
.page_size = (_page_size), \
.n_banks = 1, \
.addr_nbytes = (_addr_nbytes), \
.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR, \
#define OTP_INFO(_len, _n_regions, _base, _offset) \
.otp_org = { \
.len = (_len), \
.base = (_base), \
.offset = (_offset), \
.n_regions = (_n_regions), \
},
#define PARSE_SFDP \
.parse_sfdp = true, \
#define FLAGS(_flags) \
.flags = (_flags), \
#define NO_SFDP_FLAGS(_no_sfdp_flags) \
.no_sfdp_flags = (_no_sfdp_flags), \
#define FIXUP_FLAGS(_fixup_flags) \
.fixup_flags = (_fixup_flags), \
#define MFR_FLAGS(_mfr_flags) \
.mfr_flags = (_mfr_flags), \
#define SNOR_OTP(_len, _n_regions, _base, _offset) \
(&(const struct spi_nor_otp_organization){ \
.len = (_len), \
.base = (_base), \
.offset = (_offset), \
.n_regions = (_n_regions), \
})
/**
* struct spi_nor_manufacturer - SPI NOR manufacturer object
@ -631,11 +601,9 @@ struct sfdp {
/* Manufacturer drivers. */
extern const struct spi_nor_manufacturer spi_nor_atmel;
extern const struct spi_nor_manufacturer spi_nor_catalyst;
extern const struct spi_nor_manufacturer spi_nor_eon;
extern const struct spi_nor_manufacturer spi_nor_esmt;
extern const struct spi_nor_manufacturer spi_nor_everspin;
extern const struct spi_nor_manufacturer spi_nor_fujitsu;
extern const struct spi_nor_manufacturer spi_nor_gigadevice;
extern const struct spi_nor_manufacturer spi_nor_intel;
extern const struct spi_nor_manufacturer spi_nor_issi;
@ -734,6 +702,22 @@ static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
return container_of(mtd, struct spi_nor, mtd);
}
/**
* spi_nor_needs_sfdp() - returns true if SFDP parsing is used for this flash.
*
* Return: true if SFDP parsing is needed
*/
static inline bool spi_nor_needs_sfdp(const struct spi_nor *nor)
{
/*
* The flash size is one property parsed by the SFDP. We use it as an
* indicator whether we need SFDP parsing for a particular flash. I.e.
* non-legacy flash entries in flash_info will have a size of zero iff
* SFDP should be used.
*/
return !nor->info->size;
}
#ifdef CONFIG_DEBUG_FS
void spi_nor_debugfs_register(struct spi_nor *nor);
void spi_nor_debugfs_shutdown(void);

View File

@ -9,26 +9,60 @@
#include "core.h"
static const struct flash_info eon_nor_parts[] = {
/* EON -- en25xxx */
{ "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64) },
{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128) },
{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{ "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64) },
{ "en25qh64", INFO(0x1c7017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256) },
{ "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512)
PARSE_SFDP },
{ "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{
.id = SNOR_ID(0x1c, 0x20, 0x16),
.name = "en25p32",
.size = SZ_4M,
}, {
.id = SNOR_ID(0x1c, 0x20, 0x17),
.name = "en25p64",
.size = SZ_8M,
}, {
.id = SNOR_ID(0x1c, 0x30, 0x14),
.name = "en25q80a",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x1c, 0x30, 0x16),
.name = "en25q32b",
.size = SZ_4M,
}, {
.id = SNOR_ID(0x1c, 0x30, 0x17),
.name = "en25q64",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x1c, 0x31, 0x16),
.name = "en25f32",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.name = "en25s64",
.id = SNOR_ID(0x1c, 0x38, 0x17),
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x1c, 0x70, 0x15),
.name = "en25qh16",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x1c, 0x70, 0x16),
.name = "en25qh32",
.size = SZ_4M,
}, {
.id = SNOR_ID(0x1c, 0x70, 0x17),
.name = "en25qh64",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x1c, 0x70, 0x18),
.name = "en25qh128",
.size = SZ_16M,
}, {
.id = SNOR_ID(0x1c, 0x70, 0x19),
.name = "en25qh256",
},
};
const struct spi_nor_manufacturer spi_nor_eon = {

View File

@ -9,16 +9,25 @@
#include "core.h"
static const struct flash_info esmt_nor_parts[] = {
/* ESMT */
{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K) },
{ "f25l32qa-2s", INFO(0x8c4116, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K) },
{ "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K) },
{
.id = SNOR_ID(0x8c, 0x20, 0x16),
.name = "f25l32pa",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x8c, 0x41, 0x16),
.name = "f25l32qa-2s",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x8c, 0x41, 0x17),
.name = "f25l64qa",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SECT_4K,
}
};
const struct spi_nor_manufacturer spi_nor_esmt = {

View File

@ -9,11 +9,29 @@
#include "core.h"
static const struct flash_info everspin_nor_parts[] = {
/* Everspin */
{ "mr25h128", CAT25_INFO(16 * 1024, 1, 256, 2) },
{ "mr25h256", CAT25_INFO(32 * 1024, 1, 256, 2) },
{ "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3) },
{ "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3) },
{
.name = "mr25h128",
.size = SZ_16K,
.sector_size = SZ_16K,
.addr_nbytes = 2,
.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR,
}, {
.name = "mr25h256",
.size = SZ_32K,
.sector_size = SZ_32K,
.addr_nbytes = 2,
.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR,
}, {
.name = "mr25h10",
.size = SZ_128K,
.sector_size = SZ_128K,
.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR,
}, {
.name = "mr25h40",
.size = SZ_512K,
.sector_size = SZ_512K,
.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR,
}
};
const struct spi_nor_manufacturer spi_nor_everspin = {

View File

@ -1,21 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2005, Intec Automation Inc.
* Copyright (C) 2014, Freescale Semiconductor, Inc.
*/
#include <linux/mtd/spi-nor.h>
#include "core.h"
static const struct flash_info fujitsu_nor_parts[] = {
/* Fujitsu */
{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1)
FLAGS(SPI_NOR_NO_ERASE) },
};
const struct spi_nor_manufacturer spi_nor_fujitsu = {
.name = "fujitsu",
.parts = fujitsu_nor_parts,
.nparts = ARRAY_SIZE(fujitsu_nor_parts),
};

View File

@ -34,39 +34,55 @@ static const struct spi_nor_fixups gd25q256_fixups = {
};
static const struct flash_info gigadevice_nor_parts[] = {
{ "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25lq32", INFO(0xc86016, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25lq128d", INFO(0xc86018, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512)
PARSE_SFDP
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
.fixups = &gd25q256_fixups },
{
.id = SNOR_ID(0xc8, 0x40, 0x15),
.name = "gd25q16",
.size = SZ_2M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc8, 0x40, 0x16),
.name = "gd25q32",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc8, 0x40, 0x17),
.name = "gd25q64",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc8, 0x40, 0x18),
.name = "gd25q128",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc8, 0x40, 0x19),
.name = "gd25q256",
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6,
.fixups = &gd25q256_fixups,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc8, 0x60, 0x16),
.name = "gd25lq32",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc8, 0x60, 0x17),
.name = "gd25lq64c",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc8, 0x60, 0x18),
.name = "gd25lq128d",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
},
};
const struct spi_nor_manufacturer spi_nor_gigadevice = {

View File

@ -9,13 +9,22 @@
#include "core.h"
static const struct flash_info intel_nor_parts[] = {
/* Intel/Numonyx -- xxxs33b */
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) },
{ "320s33b", INFO(0x898912, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) },
{ "640s33b", INFO(0x898913, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) },
{
.id = SNOR_ID(0x89, 0x89, 0x11),
.name = "160s33b",
.size = SZ_2M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
}, {
.id = SNOR_ID(0x89, 0x89, 0x12),
.name = "320s33b",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
}, {
.id = SNOR_ID(0x89, 0x89, 0x13),
.name = "640s33b",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
}
};
const struct spi_nor_manufacturer spi_nor_intel = {

View File

@ -47,48 +47,86 @@ static const struct spi_nor_fixups pm25lv_nor_fixups = {
};
static const struct flash_info issi_nor_parts[] = {
/* ISSI */
{ "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2)
NO_SFDP_FLAGS(SECT_4K) },
{ "is25lq040b", INFO(0x9d4013, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25lp016d", INFO(0x9d6015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25lp080d", INFO(0x9d6014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25lp032", INFO(0x9d6016, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "is25lp064", INFO(0x9d6017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "is25lp128", INFO(0x9d6018, 0, 64 * 1024, 256)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "is25lp256", INFO(0x9d6019, 0, 64 * 1024, 512)
PARSE_SFDP
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
.fixups = &is25lp256_fixups },
{ "is25wp032", INFO(0x9d7016, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25wp064", INFO(0x9d7017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25wp256", INFO(0x9d7019, 0, 0, 0)
PARSE_SFDP
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
FLAGS(SPI_NOR_QUAD_PP)
.fixups = &is25lp256_fixups },
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2)
NO_SFDP_FLAGS(SECT_4K)
{
.name = "pm25lv512",
.sector_size = SZ_32K,
.size = SZ_64K,
.no_sfdp_flags = SECT_4K,
.fixups = &pm25lv_nor_fixups
},
{ "pm25lv010", INFO(0, 0, 32 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K)
}, {
.name = "pm25lv010",
.sector_size = SZ_32K,
.size = SZ_128K,
.no_sfdp_flags = SECT_4K,
.fixups = &pm25lv_nor_fixups
},
{ "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
}, {
.id = SNOR_ID(0x7f, 0x9d, 0x20),
.name = "is25cd512",
.sector_size = SZ_32K,
.size = SZ_64K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x7f, 0x9d, 0x46),
.name = "pm25lq032",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x9d, 0x40, 0x13),
.name = "is25lq040b",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x9d, 0x60, 0x14),
.name = "is25lp080d",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x9d, 0x60, 0x15),
.name = "is25lp016d",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x9d, 0x60, 0x16),
.name = "is25lp032",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x9d, 0x60, 0x17),
.name = "is25lp064",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x9d, 0x60, 0x18),
.name = "is25lp128",
.size = SZ_16M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x9d, 0x60, 0x19),
.name = "is25lp256",
.fixups = &is25lp256_fixups,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x9d, 0x70, 0x16),
.name = "is25wp032",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x9d, 0x70, 0x17),
.size = SZ_8M,
.name = "is25wp064",
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x9d, 0x70, 0x18),
.name = "is25wp128",
.size = SZ_16M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x9d, 0x70, 0x19),
.name = "is25wp256",
.flags = SPI_NOR_QUAD_PP,
.fixups = &is25lp256_fixups,
.fixup_flags = SPI_NOR_4B_OPCODES,
}
};
static void issi_nor_default_init(struct spi_nor *nor)

View File

@ -33,76 +33,156 @@ static const struct spi_nor_fixups mx25l25635_fixups = {
};
static const struct flash_info macronix_nor_parts[] = {
/* Macronix */
{ "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16) },
{ "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP)
NO_SFDP_FLAGS(SECT_4K) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256) },
{ "mx25r1635f", INFO(0xc22815, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
.fixups = &mx25l25635_fixups },
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "mx25uw51245g", INFOB(0xc2813a, 0, 0, 0, 4)
PARSE_SFDP
FLAGS(SPI_NOR_RWW) },
{ "mx25v8035f", INFO(0xc22314, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512) },
{ "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "mx66l1g45g", INFO(0xc2201b, 0, 64 * 1024, 2048)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048)
NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) },
{ "mx66u2g45g", INFO(0xc2253c, 0, 64 * 1024, 4096)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{
.id = SNOR_ID(0xc2, 0x20, 0x10),
.name = "mx25l512e",
.size = SZ_64K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x12),
.name = "mx25l2005a",
.size = SZ_256K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x13),
.name = "mx25l4005a",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x14),
.name = "mx25l8005",
.size = SZ_1M,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x15),
.name = "mx25l1606e",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x16),
.name = "mx25l3205d",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x17),
.name = "mx25l6405d",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x18),
.name = "mx25l12805d",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x19),
.name = "mx25l25635e",
.size = SZ_32M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixups = &mx25l25635_fixups
}, {
.id = SNOR_ID(0xc2, 0x20, 0x1a),
.name = "mx66l51235f",
.size = SZ_64M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc2, 0x20, 0x1b),
.name = "mx66l1g45g",
.size = SZ_128M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x23, 0x14),
.name = "mx25v8035f",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x32),
.name = "mx25u2033e",
.size = SZ_256K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x33),
.name = "mx25u4035",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x34),
.name = "mx25u8035",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x36),
.name = "mx25u3235f",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x37),
.name = "mx25u6435f",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x38),
.name = "mx25u12835f",
.size = SZ_16M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x39),
.name = "mx25u25635f",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x3a),
.name = "mx25u51245g",
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x3a),
.name = "mx66u51235f",
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc2, 0x25, 0x3c),
.name = "mx66u2g45g",
.size = SZ_256M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc2, 0x26, 0x18),
.name = "mx25l12855e",
.size = SZ_16M,
}, {
.id = SNOR_ID(0xc2, 0x26, 0x19),
.name = "mx25l25655e",
.size = SZ_32M,
}, {
.id = SNOR_ID(0xc2, 0x26, 0x1b),
.name = "mx66l1g55g",
.size = SZ_128M,
.no_sfdp_flags = SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x28, 0x15),
.name = "mx25r1635f",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x28, 0x16),
.name = "mx25r3235f",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xc2, 0x81, 0x3a),
.name = "mx25uw51245g",
.n_banks = 4,
.flags = SPI_NOR_RWW,
}, {
.id = SNOR_ID(0xc2, 0x9e, 0x16),
.name = "mx25l3255e",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}
};
static void macronix_nor_default_init(struct spi_nor *nor)

View File

@ -78,7 +78,7 @@ static int micron_st_nor_octal_dtr_en(struct spi_nor *nor)
return ret;
}
if (memcmp(buf, nor->info->id, nor->info->id_len))
if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
return -EINVAL;
return 0;
@ -114,7 +114,7 @@ static int micron_st_nor_octal_dtr_dis(struct spi_nor *nor)
return ret;
}
if (memcmp(buf, nor->info->id, nor->info->id_len))
if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
return -EINVAL;
return 0;
@ -159,148 +159,291 @@ static const struct spi_nor_fixups mt35xu512aba_fixups = {
};
static const struct flash_info micron_nor_parts[] = {
{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ |
SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE)
MFR_FLAGS(USE_FSR)
.fixups = &mt35xu512aba_fixups
},
{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
MFR_FLAGS(USE_FSR)
{
.id = SNOR_ID(0x2c, 0x5b, 0x1a),
.name = "mt35xu512aba",
.sector_size = SZ_128K,
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ |
SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP,
.mfr_flags = USE_FSR,
.fixup_flags = SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE,
.fixups = &mt35xu512aba_fixups,
}, {
.id = SNOR_ID(0x2c, 0x5b, 0x1c),
.name = "mt35xu02g",
.sector_size = SZ_128K,
.size = SZ_256M,
.no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ,
.mfr_flags = USE_FSR,
.fixup_flags = SPI_NOR_4B_OPCODES,
},
};
static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor,
const struct sfdp_parameter_header *bfpt_header,
const struct sfdp_bfpt *bfpt)
{
nor->flags &= ~SNOR_F_HAS_16BIT_SR;
return 0;
}
static struct spi_nor_fixups mt25qu512a_fixups = {
.post_bfpt = mt25qu512a_post_bfpt_fixup,
};
static const struct flash_info st_nor_parts[] = {
{ "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) },
{ "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) },
{ "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "mt25ql256a", INFO6(0x20ba19, 0x104400, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
MFR_FLAGS(USE_FSR)
},
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
MFR_FLAGS(USE_FSR)
},
{ "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "mt25ql512a", INFO6(0x20ba20, 0x104400, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
MFR_FLAGS(USE_FSR)
},
{ "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "mt25qu512a", INFO6(0x20bb20, 0x104400, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
MFR_FLAGS(USE_FSR)
},
{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048)
FLAGS(NO_CHIP_ERASE)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096)
FLAGS(NO_CHIP_ERASE)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096)
FLAGS(NO_CHIP_ERASE)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_FSR)
},
{ "m25p05", INFO(0x202010, 0, 32 * 1024, 2) },
{ "m25p10", INFO(0x202011, 0, 32 * 1024, 4) },
{ "m25p20", INFO(0x202012, 0, 64 * 1024, 4) },
{ "m25p40", INFO(0x202013, 0, 64 * 1024, 8) },
{ "m25p80", INFO(0x202014, 0, 64 * 1024, 16) },
{ "m25p16", INFO(0x202015, 0, 64 * 1024, 32) },
{ "m25p32", INFO(0x202016, 0, 64 * 1024, 64) },
{ "m25p64", INFO(0x202017, 0, 64 * 1024, 128) },
{ "m25p128", INFO(0x202018, 0, 256 * 1024, 64) },
{ "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2) },
{ "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4) },
{ "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4) },
{ "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8) },
{ "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16) },
{ "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32) },
{ "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64) },
{ "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128) },
{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64) },
{ "m45pe10", INFO(0x204011, 0, 64 * 1024, 2) },
{ "m45pe80", INFO(0x204014, 0, 64 * 1024, 16) },
{ "m45pe16", INFO(0x204015, 0, 64 * 1024, 32) },
{ "m25pe20", INFO(0x208012, 0, 64 * 1024, 4) },
{ "m25pe80", INFO(0x208014, 0, 64 * 1024, 16) },
{ "m25pe16", INFO(0x208015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K) },
{ "m25px16", INFO(0x207115, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K) },
{ "m25px32", INFO(0x207116, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "m25px64", INFO(0x207117, 0, 64 * 1024, 128) },
{ "m25px80", INFO(0x207114, 0, 64 * 1024, 16) },
{
.name = "m25p05-nonjedec",
.sector_size = SZ_32K,
.size = SZ_64K,
}, {
.name = "m25p10-nonjedec",
.sector_size = SZ_32K,
.size = SZ_128K,
}, {
.name = "m25p20-nonjedec",
.size = SZ_256K,
}, {
.name = "m25p40-nonjedec",
.size = SZ_512K,
}, {
.name = "m25p80-nonjedec",
.size = SZ_1M,
}, {
.name = "m25p16-nonjedec",
.size = SZ_2M,
}, {
.name = "m25p32-nonjedec",
.size = SZ_4M,
}, {
.name = "m25p64-nonjedec",
.size = SZ_8M,
}, {
.name = "m25p128-nonjedec",
.sector_size = SZ_256K,
.size = SZ_16M,
}, {
.id = SNOR_ID(0x20, 0x20, 0x10),
.name = "m25p05",
.sector_size = SZ_32K,
.size = SZ_64K,
}, {
.id = SNOR_ID(0x20, 0x20, 0x11),
.name = "m25p10",
.sector_size = SZ_32K,
.size = SZ_128K,
}, {
.id = SNOR_ID(0x20, 0x20, 0x12),
.name = "m25p20",
.size = SZ_256K,
}, {
.id = SNOR_ID(0x20, 0x20, 0x13),
.name = "m25p40",
.size = SZ_512K,
}, {
.id = SNOR_ID(0x20, 0x20, 0x14),
.name = "m25p80",
.size = SZ_1M,
}, {
.id = SNOR_ID(0x20, 0x20, 0x15),
.name = "m25p16",
.size = SZ_2M,
}, {
.id = SNOR_ID(0x20, 0x20, 0x16),
.name = "m25p32",
.size = SZ_4M,
}, {
.id = SNOR_ID(0x20, 0x20, 0x17),
.name = "m25p64",
.size = SZ_8M,
}, {
.id = SNOR_ID(0x20, 0x20, 0x18),
.name = "m25p128",
.sector_size = SZ_256K,
.size = SZ_16M,
}, {
.id = SNOR_ID(0x20, 0x40, 0x11),
.name = "m45pe10",
.size = SZ_128K,
}, {
.id = SNOR_ID(0x20, 0x40, 0x14),
.name = "m45pe80",
.size = SZ_1M,
}, {
.id = SNOR_ID(0x20, 0x40, 0x15),
.name = "m45pe16",
.size = SZ_2M,
}, {
.id = SNOR_ID(0x20, 0x63, 0x16),
.name = "m25px32-s1",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x20, 0x71, 0x14),
.name = "m25px80",
.size = SZ_1M,
}, {
.id = SNOR_ID(0x20, 0x71, 0x15),
.name = "m25px16",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x20, 0x71, 0x16),
.name = "m25px32",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x20, 0x71, 0x17),
.name = "m25px64",
.size = SZ_8M,
}, {
.id = SNOR_ID(0x20, 0x73, 0x16),
.name = "m25px32-s0",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x20, 0x80, 0x12),
.name = "m25pe20",
.size = SZ_256K,
}, {
.id = SNOR_ID(0x20, 0x80, 0x14),
.name = "m25pe80",
.size = SZ_1M,
}, {
.id = SNOR_ID(0x20, 0x80, 0x15),
.name = "m25pe16",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x20, 0xba, 0x16),
.name = "n25q032",
.size = SZ_4M,
.no_sfdp_flags = SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x20, 0xba, 0x17),
.name = "n25q064",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x20, 0xba, 0x18),
.name = "n25q128a13",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x19, 0x10, 0x44, 0x00),
.name = "mt25ql256a",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x19),
.name = "n25q256a",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x20, 0x10, 0x44, 0x00),
.name = "mt25ql512a",
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x20),
.name = "n25q512ax3",
.size = SZ_64M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x21),
.name = "n25q00",
.size = SZ_128M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x22),
.name = "mt25ql02g",
.size = SZ_256M,
.flags = NO_CHIP_ERASE,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x15),
.name = "n25q016a",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x16),
.name = "n25q032a",
.size = SZ_4M,
.no_sfdp_flags = SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x17),
.name = "n25q064a",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x18),
.name = "n25q128a11",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x19, 0x10, 0x44, 0x00),
.name = "mt25qu256a",
.size = SZ_32M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x19),
.name = "n25q256ax1",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x20, 0x10, 0x44, 0x00),
.name = "mt25qu512a",
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.mfr_flags = USE_FSR,
.fixups = &mt25qu512a_fixups,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x20),
.name = "n25q512a",
.size = SZ_64M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x21),
.name = "n25q00a",
.size = SZ_128M,
.flags = NO_CHIP_ERASE,
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x22),
.name = "mt25qu02g",
.size = SZ_256M,
.flags = NO_CHIP_ERASE,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_FSR,
}
};
/**

View File

@ -228,7 +228,7 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
return ret;
}
if (memcmp(buf, nor->info->id, nor->info->id_len))
if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
return -EINVAL;
return 0;
@ -272,7 +272,7 @@ static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
return ret;
}
if (memcmp(buf, nor->info->id, nor->info->id_len))
if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
return -EINVAL;
return 0;
@ -756,155 +756,252 @@ static const struct spi_nor_fixups s25fs_s_nor_fixups = {
};
static const struct flash_info spansion_nor_parts[] = {
/* Spansion/Cypress -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
{ "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128)
NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
.fixups = &s25fs_s_nor_fixups, },
{ "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
.fixups = &s25fs_s_nor_fixups, },
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) },
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) },
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256)
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
MFR_FLAGS(USE_CLSR)
},
{ "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8) },
{ "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16) },
{ "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32) },
{ "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64) },
{ "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128) },
{ "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{ "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
{ "s25fs256t", INFO6(0x342b19, 0x0f0890, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
.fixups = &s25fs256t_fixups },
{ "s25hl512t", INFO6(0x342a1a, 0x0f0390, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
.fixups = &s25hx_t_fixups },
{ "s25hl01gt", INFO6(0x342a1b, 0x0f0390, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
.fixups = &s25hx_t_fixups },
{ "s25hl02gt", INFO6(0x342a1c, 0x0f0090, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
FLAGS(NO_CHIP_ERASE)
.fixups = &s25hx_t_fixups },
{ "s25hs512t", INFO6(0x342b1a, 0x0f0390, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
.fixups = &s25hx_t_fixups },
{ "s25hs01gt", INFO6(0x342b1b, 0x0f0390, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
.fixups = &s25hx_t_fixups },
{ "s25hs02gt", INFO6(0x342b1c, 0x0f0090, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
FLAGS(NO_CHIP_ERASE)
.fixups = &s25hx_t_fixups },
{ "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1)
FLAGS(SPI_NOR_NO_ERASE) },
{ "s28hl512t", INFO(0x345a1a, 0, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
{
.id = SNOR_ID(0x01, 0x02, 0x12),
.name = "s25sl004a",
.size = SZ_512K,
}, {
.id = SNOR_ID(0x01, 0x02, 0x13),
.name = "s25sl008a",
.size = SZ_1M,
}, {
.id = SNOR_ID(0x01, 0x02, 0x14),
.name = "s25sl016a",
.size = SZ_2M,
}, {
.id = SNOR_ID(0x01, 0x02, 0x15, 0x4d, 0x00),
.name = "s25sl032p",
.size = SZ_4M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x01, 0x02, 0x15),
.name = "s25sl032a",
.size = SZ_4M,
}, {
.id = SNOR_ID(0x01, 0x02, 0x16, 0x4d, 0x00),
.name = "s25sl064p",
.size = SZ_8M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x01, 0x02, 0x16),
.name = "s25sl064a",
.size = SZ_8M,
}, {
.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x80),
.name = "s25fl256s0",
.size = SZ_32M,
.sector_size = SZ_256K,
.no_sfdp_flags = SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x81),
.name = "s25fs256s0",
.size = SZ_32M,
.sector_size = SZ_256K,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x80),
.name = "s25fl256s1",
.size = SZ_32M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x81),
.name = "s25fs256s1",
.size = SZ_32M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x80),
.name = "s25fl512s",
.size = SZ_64M,
.sector_size = SZ_256K,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x81),
.name = "s25fs512s",
.size = SZ_64M,
.sector_size = SZ_256K,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
.fixups = &s25fs_s_nor_fixups,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x00),
.name = "s25sl12800",
.size = SZ_16M,
.sector_size = SZ_256K,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x01),
.name = "s25sl12801",
.size = SZ_16M,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00, 0x80),
.name = "s25fl128s0",
.size = SZ_16M,
.sector_size = SZ_256K,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00),
.name = "s25fl129p0",
.size = SZ_16M,
.sector_size = SZ_256K,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x80),
.name = "s25fl128s1",
.size = SZ_16M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x81),
.name = "s25fs128s1",
.size = SZ_16M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
.fixups = &s25fs_s_nor_fixups,
}, {
.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01),
.name = "s25fl129p1",
.size = SZ_16M,
.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.mfr_flags = USE_CLSR,
}, {
.id = SNOR_ID(0x01, 0x40, 0x13),
.name = "s25fl204k",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x01, 0x40, 0x14),
.name = "s25fl208k",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0x01, 0x40, 0x15),
.name = "s25fl116k",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x01, 0x40, 0x16),
.name = "s25fl132k",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x01, 0x40, 0x17),
.name = "s25fl164k",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x01, 0x60, 0x17),
.name = "s25fl064l",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x01, 0x60, 0x18),
.name = "s25fl128l",
.size = SZ_16M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x01, 0x60, 0x19),
.name = "s25fl256l",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x04, 0x2c, 0xc2, 0x7f, 0x7f, 0x7f),
.name = "cy15x104q",
.size = SZ_512K,
.sector_size = SZ_512K,
.flags = SPI_NOR_NO_ERASE,
}, {
.id = SNOR_ID(0x34, 0x2a, 0x1a, 0x0f, 0x03, 0x90),
.name = "s25hl512t",
.mfr_flags = USE_CLPEF,
.fixups = &s25hx_t_fixups
}, {
.id = SNOR_ID(0x34, 0x2a, 0x1b, 0x0f, 0x03, 0x90),
.name = "s25hl01gt",
.mfr_flags = USE_CLPEF,
.fixups = &s25hx_t_fixups
}, {
.id = SNOR_ID(0x34, 0x2a, 0x1c, 0x0f, 0x00, 0x90),
.name = "s25hl02gt",
.mfr_flags = USE_CLPEF,
.flags = NO_CHIP_ERASE,
.fixups = &s25hx_t_fixups
}, {
.id = SNOR_ID(0x34, 0x2b, 0x19, 0x0f, 0x08, 0x90),
.name = "s25fs256t",
.mfr_flags = USE_CLPEF,
.fixups = &s25fs256t_fixups
}, {
.id = SNOR_ID(0x34, 0x2b, 0x1a, 0x0f, 0x03, 0x90),
.name = "s25hs512t",
.mfr_flags = USE_CLPEF,
.fixups = &s25hx_t_fixups
}, {
.id = SNOR_ID(0x34, 0x2b, 0x1b, 0x0f, 0x03, 0x90),
.name = "s25hs01gt",
.mfr_flags = USE_CLPEF,
.fixups = &s25hx_t_fixups
}, {
.id = SNOR_ID(0x34, 0x2b, 0x1c, 0x0f, 0x00, 0x90),
.name = "s25hs02gt",
.mfr_flags = USE_CLPEF,
.flags = NO_CHIP_ERASE,
.fixups = &s25hx_t_fixups
}, {
.id = SNOR_ID(0x34, 0x5a, 0x1a),
.name = "s28hl512t",
.mfr_flags = USE_CLPEF,
.fixups = &s28hx_t_fixups,
},
{ "s28hl01gt", INFO(0x345a1b, 0, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
}, {
.id = SNOR_ID(0x34, 0x5a, 0x1b),
.name = "s28hl01gt",
.mfr_flags = USE_CLPEF,
.fixups = &s28hx_t_fixups,
},
{ "s28hs512t", INFO(0x345b1a, 0, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
}, {
.id = SNOR_ID(0x34, 0x5b, 0x1a),
.name = "s28hs512t",
.mfr_flags = USE_CLPEF,
.fixups = &s28hx_t_fixups,
},
{ "s28hs01gt", INFO(0x345b1b, 0, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
}, {
.id = SNOR_ID(0x34, 0x5b, 0x1b),
.name = "s28hs01gt",
.mfr_flags = USE_CLPEF,
.fixups = &s28hx_t_fixups,
},
{ "s28hs02gt", INFO(0x345b1c, 0, 0, 0)
PARSE_SFDP
MFR_FLAGS(USE_CLPEF)
}, {
.id = SNOR_ID(0x34, 0x5b, 0x1c),
.name = "s28hs02gt",
.mfr_flags = USE_CLPEF,
.fixups = &s28hx_t_fixups,
},
}, {
.id = SNOR_ID(0xef, 0x40, 0x13),
.name = "s25fl004k",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x40, 0x14),
.name = "s25fl008k",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x40, 0x15),
.name = "s25fl016k",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x40, 0x17),
.name = "s25fl064k",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}
};
/**
@ -956,7 +1053,8 @@ static int spansion_nor_late_init(struct spi_nor *nor)
nor->flags |= SNOR_F_4B_OPCODES;
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
nor->mtd.erasesize = nor->info->sector_size;
nor->mtd.erasesize = nor->info->sector_size ?:
SPI_NOR_DEFAULT_SECTOR_SIZE;
}
if (mfr_flags & (USE_CLSR | USE_CLPEF)) {

View File

@ -61,66 +61,110 @@ static const struct spi_nor_fixups sst26vf_nor_fixups = {
};
static const struct flash_info sst_nor_parts[] = {
/* SST -- large erase sizes are "overlays", "sectors" are 4K */
{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP |
SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K) },
{ "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K) },
{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K) },
{ "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
MFR_FLAGS(SST_WRITE) },
{ "sst26wf016b", INFO(0xbf2651, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "sst26vf016b", INFO(0xbf2641, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
{ "sst26vf032b", INFO(0xbf2642, 0, 0, 0)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
PARSE_SFDP
.fixups = &sst26vf_nor_fixups },
{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
.fixups = &sst26vf_nor_fixups },
{
.id = SNOR_ID(0x62, 0x16, 0x12),
.name = "sst25wf020a",
.size = SZ_256K,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0x62, 0x16, 0x13),
.name = "sst25wf040b",
.size = SZ_512K,
.flags = SPI_NOR_HAS_LOCK,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x01),
.name = "sst25wf512",
.size = SZ_64K,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x02),
.name = "sst25wf010",
.size = SZ_128K,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x03),
.name = "sst25wf020",
.size = SZ_256K,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x04),
.name = "sst25wf040",
.size = SZ_512K,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x05),
.name = "sst25wf080",
.size = SZ_1M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x41),
.name = "sst25vf016b",
.size = SZ_2M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x4a),
.name = "sst25vf032b",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x4b),
.name = "sst25vf064c",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x8d),
.name = "sst25vf040b",
.size = SZ_512K,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x25, 0x8e),
.name = "sst25vf080b",
.size = SZ_1M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K,
.mfr_flags = SST_WRITE,
}, {
.id = SNOR_ID(0xbf, 0x26, 0x41),
.name = "sst26vf016b",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
}, {
.id = SNOR_ID(0xbf, 0x26, 0x42),
.name = "sst26vf032b",
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.fixups = &sst26vf_nor_fixups,
}, {
.id = SNOR_ID(0xbf, 0x26, 0x43),
.name = "sst26vf064b",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixups = &sst26vf_nor_fixups,
}, {
.id = SNOR_ID(0xbf, 0x26, 0x51),
.name = "sst26wf016b",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}
};
static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,

View File

@ -34,17 +34,22 @@ static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor)
static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
{
unsigned int bp_slots, bp_slots_needed;
/*
* sector_size will eventually be replaced with the max erase size of
* the flash. For now, we need to have that ugly default.
*/
unsigned int sector_size = nor->info->sector_size ?: SPI_NOR_DEFAULT_SECTOR_SIZE;
u64 n_sectors = div_u64(nor->params->size, sector_size);
u8 mask = spi_nor_get_sr_bp_mask(nor);
/* Reserved one for "protect none" and one for "protect all". */
bp_slots = (1 << hweight8(mask)) - 2;
bp_slots_needed = ilog2(nor->info->n_sectors);
bp_slots_needed = ilog2(n_sectors);
if (bp_slots_needed > bp_slots)
return nor->info->sector_size <<
(bp_slots_needed - bp_slots);
return sector_size << (bp_slots_needed - bp_slots);
else
return nor->info->sector_size;
return sector_size;
}
static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,

View File

@ -35,8 +35,8 @@ static ssize_t jedec_id_show(struct device *dev,
struct spi_device *spi = to_spi_device(dev);
struct spi_mem *spimem = spi_get_drvdata(spi);
struct spi_nor *nor = spi_mem_get_drvdata(spimem);
const u8 *id = nor->info->id_len ? nor->info->id : nor->id;
u8 id_len = nor->info->id_len ?: SPI_NOR_MAX_ID_LEN;
const u8 *id = nor->info->id ? nor->info->id->bytes : nor->id;
u8 id_len = nor->info->id ? nor->info->id->len : SPI_NOR_MAX_ID_LEN;
return sysfs_emit(buf, "%*phN\n", id_len, id);
}
@ -78,7 +78,7 @@ static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj,
if (attr == &dev_attr_manufacturer.attr && !nor->manufacturer)
return 0;
if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len && !nor->id)
if (attr == &dev_attr_jedec_id.attr && !nor->info->id && !nor->id)
return 0;
return 0444;

View File

@ -42,107 +42,191 @@ static const struct spi_nor_fixups w25q256_fixups = {
};
static const struct flash_info winbond_nor_parts[] = {
/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
{ "w25x05", INFO(0xef3010, 0, 64 * 1024, 1)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25x10", INFO(0xef3011, 0, 64 * 1024, 2)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25x20", INFO(0xef3012, 0, 64 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25x40", INFO(0xef3013, 0, 64 * 1024, 8)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q16dw", INFO(0xef6015, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q16jv-im/jm", INFO(0xef7015, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q20cl", INFO(0xef4012, 0, 64 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q20bw", INFO(0xef5012, 0, 64 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q20ew", INFO(0xef6012, 0, 64 * 1024, 4)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
OTP_INFO(256, 3, 0x1000, 0x1000) },
{ "w25q32jv", INFO(0xef7016, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q32jwm", INFO(0xef8016, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
OTP_INFO(256, 3, 0x1000, 0x1000) },
{ "w25q64jwm", INFO(0xef8017, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q128jwm", INFO(0xef8018, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q256jwm", INFO(0xef8019, 0, 64 * 1024, 512)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q64jvm", INFO(0xef7017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q128jv", INFO(0xef7018, 0, 64 * 1024, 256)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K) },
{ "w25q128", INFO(0xef4018, 0, 0, 0)
PARSE_SFDP
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
.fixups = &w25q256_fixups },
{ "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512)
PARSE_SFDP },
{ "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ |
SPI_NOR_DUAL_READ) },
{ "w25q512nwq", INFO(0xef6020, 0, 0, 0)
PARSE_SFDP
OTP_INFO(256, 3, 0x1000, 0x1000) },
{ "w25q512nwm", INFO(0xef8020, 0, 64 * 1024, 1024)
PARSE_SFDP
OTP_INFO(256, 3, 0x1000, 0x1000) },
{ "w25q512jvq", INFO(0xef4020, 0, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{
.id = SNOR_ID(0xef, 0x30, 0x10),
.name = "w25x05",
.size = SZ_64K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x11),
.name = "w25x10",
.size = SZ_128K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x12),
.name = "w25x20",
.size = SZ_256K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x13),
.name = "w25x40",
.size = SZ_512K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x14),
.name = "w25x80",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x15),
.name = "w25x16",
.size = SZ_2M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x16),
.name = "w25x32",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x30, 0x17),
.name = "w25x64",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x40, 0x12),
.name = "w25q20cl",
.size = SZ_256K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x40, 0x14),
.name = "w25q80bl",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x40, 0x16),
.name = "w25q32",
.size = SZ_4M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x40, 0x17),
.name = "w25q64",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x40, 0x18),
.name = "w25q128",
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
}, {
.id = SNOR_ID(0xef, 0x40, 0x19),
.name = "w25q256",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.fixups = &w25q256_fixups,
}, {
.id = SNOR_ID(0xef, 0x40, 0x20),
.name = "w25q512jvq",
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x50, 0x12),
.name = "w25q20bw",
.size = SZ_256K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x50, 0x14),
.name = "w25q80",
.size = SZ_1M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x60, 0x12),
.name = "w25q20ew",
.size = SZ_256K,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x60, 0x15),
.name = "w25q16dw",
.size = SZ_2M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x60, 0x16),
.name = "w25q32dw",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.otp = SNOR_OTP(256, 3, 0x1000, 0x1000),
}, {
.id = SNOR_ID(0xef, 0x60, 0x17),
.name = "w25q64dw",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x60, 0x18),
.name = "w25q128fw",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x60, 0x19),
.name = "w25q256jw",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x60, 0x20),
.name = "w25q512nwq",
.otp = SNOR_OTP(256, 3, 0x1000, 0x1000),
}, {
.id = SNOR_ID(0xef, 0x70, 0x15),
.name = "w25q16jv-im/jm",
.size = SZ_2M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x70, 0x16),
.name = "w25q32jv",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x70, 0x17),
.name = "w25q64jvm",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x70, 0x18),
.name = "w25q128jv",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x70, 0x19),
.name = "w25q256jvm",
}, {
.id = SNOR_ID(0xef, 0x71, 0x19),
.name = "w25m512jv",
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x80, 0x16),
.name = "w25q32jwm",
.size = SZ_4M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
.otp = SNOR_OTP(256, 3, 0x1000, 0x1000),
}, {
.id = SNOR_ID(0xef, 0x80, 0x17),
.name = "w25q64jwm",
.size = SZ_8M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x80, 0x18),
.name = "w25q128jwm",
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x80, 0x19),
.name = "w25q256jwm",
.size = SZ_32M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x80, 0x20),
.name = "w25q512nwm",
.otp = SNOR_OTP(256, 3, 0x1000, 0x1000),
},
};
/**
@ -221,7 +305,7 @@ static int winbond_nor_late_init(struct spi_nor *nor)
{
struct spi_nor_flash_parameter *params = nor->params;
if (params->otp.org->n_regions)
if (params->otp.org)
params->otp.ops = &winbond_nor_otp_ops;
/*

View File

@ -21,28 +21,22 @@
SPI_MEM_OP_NO_DUMMY, \
SPI_MEM_OP_DATA_IN(1, buf, 0))
#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \
.id = { \
((_jedec_id) >> 16) & 0xff, \
((_jedec_id) >> 8) & 0xff, \
(_jedec_id) & 0xff \
}, \
.id_len = 3, \
.sector_size = (8 * (_page_size)), \
.n_sectors = (_n_sectors), \
.page_size = (_page_size), \
.n_banks = 1, \
.addr_nbytes = 3, \
.flags = SPI_NOR_NO_FR
#define S3AN_FLASH(_id, _name, _n_sectors, _page_size) \
.id = _id, \
.name = _name, \
.size = 8 * (_page_size) * (_n_sectors), \
.sector_size = (8 * (_page_size)), \
.page_size = (_page_size), \
.flags = SPI_NOR_NO_FR
/* Xilinx S3AN share MFR with Atmel SPI NOR */
static const struct flash_info xilinx_nor_parts[] = {
/* Xilinx S3AN Internal Flash */
{ "3S50AN", S3AN_INFO(0x1f2200, 64, 264) },
{ "3S200AN", S3AN_INFO(0x1f2400, 256, 264) },
{ "3S400AN", S3AN_INFO(0x1f2400, 256, 264) },
{ "3S700AN", S3AN_INFO(0x1f2500, 512, 264) },
{ "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) },
{ S3AN_FLASH(SNOR_ID(0x1f, 0x22, 0x00), "3S50AN", 64, 264) },
{ S3AN_FLASH(SNOR_ID(0x1f, 0x24, 0x00), "3S200AN", 256, 264) },
{ S3AN_FLASH(SNOR_ID(0x1f, 0x24, 0x00), "3S400AN", 256, 264) },
{ S3AN_FLASH(SNOR_ID(0x1f, 0x25, 0x00), "3S700AN", 512, 264) },
{ S3AN_FLASH(SNOR_ID(0x1f, 0x26, 0x00), "3S1400AN", 512, 528) },
};
/*
@ -144,7 +138,7 @@ static int xilinx_nor_setup(struct spi_nor *nor,
page_size = (nor->params->page_size == 264) ? 256 : 512;
nor->params->page_size = page_size;
nor->mtd.writebufsize = page_size;
nor->params->size = 8 * page_size * nor->info->n_sectors;
nor->params->size = nor->info->size;
nor->mtd.erasesize = 8 * page_size;
} else {
/* Flash in Default addressing mode */

View File

@ -9,15 +9,20 @@
#include "core.h"
static const struct flash_info xmc_nor_parts[] = {
/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
{ "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{
.id = SNOR_ID(0x20, 0x70, 0x17),
.name = "XM25QH64A",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0x20, 0x70, 0x18),
.name = "XM25QH128A",
.size = SZ_16M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
},
};
/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
const struct spi_nor_manufacturer spi_nor_xmc = {
.name = "xmc",
.parts = xmc_nor_parts,

View File

@ -287,7 +287,7 @@ struct cfi_private {
unsigned long chipshift; /* Because they're of the same type */
const char *im_name; /* inter_module name for cmdset_setup */
unsigned long quirks;
struct flchip chips[]; /* per-chip data structure for each chip */
struct flchip chips[] __counted_by(numchips); /* per-chip data structure for each chip */
};
uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,

View File

@ -24,7 +24,7 @@ struct lpddr_private {
struct qinfo_chip *qinfo;
int numchips;
unsigned long chipshift;
struct flchip chips[];
struct flchip chips[] __counted_by(numchips);
};
/* qinfo_query_info structure contains request information for

View File

@ -263,6 +263,7 @@ struct spinand_manufacturer {
extern const struct spinand_manufacturer alliancememory_spinand_manufacturer;
extern const struct spinand_manufacturer ato_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
extern const struct spinand_manufacturer foresee_spinand_manufacturer;
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;