mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
SPI-NAND changes:
A load of fixes to Winbond manufacturer driver have been done, plus a structure constification. Raw NAND changes: The GPMI driver has been improved on the power management side. The Davinci driver has been cleaned up. A leak in the Atmel driver plus some typos in the core have been fixed. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAmc8is0ACgkQJWrqGEe9 VoRXDwf+IqUGLRVdCh9wQFsjEKXBX9lmLF+McG+aumLnpmxq+9iDs0FzPg39gi9W iSZiYRnVNdOPskEMpJcAnalFcAT56SFjM7IUluxvMG4TKsaWqV7ZCP+fwV+43tyl 57ohTlQCpJnTAqUdARIMVPjIlBaXTsmzyt74nb3hOUGFa5NKwF7PxBP0e504akUP TohLFHWOO4BeooqkDroz8H3Po+uO3YDVf3l0DsGANptAmA0azDjj+ZUEKOtsNEQw ZmeZ8sGZGYswrcjYqJAGKXeXBOBmfFSTlEy72cKKqs8KBGqGCRTyoDjVpIBNK+vl vyMY8AoViWX5nb83Qu85QckJbQlEqw== =GEHJ -----END PGP SIGNATURE----- Merge tag 'nand/for-6.13' into mtd/next SPI-NAND changes: A load of fixes to Winbond manufacturer driver have been done, plus a structure constification. Raw NAND changes: The GPMI driver has been improved on the power management side. The Davinci driver has been cleaned up. A leak in the Atmel driver plus some typos in the core have been fixed.
This commit is contained in:
commit
944477516b
@ -9028,6 +9028,7 @@ F: drivers/net/ethernet/freescale/gianfar*
|
||||
|
||||
FREESCALE GPMI NAND DRIVER
|
||||
M: Han Xu <han.xu@nxp.com>
|
||||
L: imx@lists.linux.dev
|
||||
L: linux-mtd@lists.infradead.org
|
||||
S: Maintained
|
||||
F: drivers/mtd/nand/raw/gpmi-nand/*
|
||||
|
@ -723,21 +723,21 @@ static int mxic_ecc_finish_io_req_pipelined(struct nand_device *nand,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct nand_ecc_engine_ops mxic_ecc_engine_external_ops = {
|
||||
static const struct nand_ecc_engine_ops mxic_ecc_engine_external_ops = {
|
||||
.init_ctx = mxic_ecc_init_ctx_external,
|
||||
.cleanup_ctx = mxic_ecc_cleanup_ctx,
|
||||
.prepare_io_req = mxic_ecc_prepare_io_req_external,
|
||||
.finish_io_req = mxic_ecc_finish_io_req_external,
|
||||
};
|
||||
|
||||
static struct nand_ecc_engine_ops mxic_ecc_engine_pipelined_ops = {
|
||||
static const struct nand_ecc_engine_ops mxic_ecc_engine_pipelined_ops = {
|
||||
.init_ctx = mxic_ecc_init_ctx_pipelined,
|
||||
.cleanup_ctx = mxic_ecc_cleanup_ctx,
|
||||
.prepare_io_req = mxic_ecc_prepare_io_req_pipelined,
|
||||
.finish_io_req = mxic_ecc_finish_io_req_pipelined,
|
||||
};
|
||||
|
||||
struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void)
|
||||
const struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void)
|
||||
{
|
||||
return &mxic_ecc_engine_pipelined_ops;
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ static int nand_ecc_sw_bch_finish_io_req(struct nand_device *nand,
|
||||
return max_bitflips;
|
||||
}
|
||||
|
||||
static struct nand_ecc_engine_ops nand_ecc_sw_bch_engine_ops = {
|
||||
static const struct nand_ecc_engine_ops nand_ecc_sw_bch_engine_ops = {
|
||||
.init_ctx = nand_ecc_sw_bch_init_ctx,
|
||||
.cleanup_ctx = nand_ecc_sw_bch_cleanup_ctx,
|
||||
.prepare_io_req = nand_ecc_sw_bch_prepare_io_req,
|
||||
|
@ -638,7 +638,7 @@ static int nand_ecc_sw_hamming_finish_io_req(struct nand_device *nand,
|
||||
return max_bitflips;
|
||||
}
|
||||
|
||||
static struct nand_ecc_engine_ops nand_ecc_sw_hamming_engine_ops = {
|
||||
static const struct nand_ecc_engine_ops nand_ecc_sw_hamming_engine_ops = {
|
||||
.init_ctx = nand_ecc_sw_hamming_init_ctx,
|
||||
.cleanup_ctx = nand_ecc_sw_hamming_cleanup_ctx,
|
||||
.prepare_io_req = nand_ecc_sw_hamming_prepare_io_req,
|
||||
|
@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
size = ALIGN(size, sizeof(s32));
|
||||
size += (req->ecc.strength + 1) * sizeof(s32) * 3;
|
||||
|
||||
user = kzalloc(size, GFP_KERNEL);
|
||||
user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL);
|
||||
if (!user)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_pmecc_create_user);
|
||||
|
||||
void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user)
|
||||
{
|
||||
kfree(user);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user);
|
||||
|
||||
static int get_strength(struct atmel_pmecc_user *user)
|
||||
{
|
||||
const int *strengths = user->pmecc->caps->strengths;
|
||||
|
@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);
|
||||
struct atmel_pmecc_user *
|
||||
atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
struct atmel_pmecc_user_req *req);
|
||||
void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
|
||||
|
||||
void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
|
||||
int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
|
||||
void atmel_pmecc_disable(struct atmel_pmecc_user *user);
|
||||
|
@ -1561,7 +1561,7 @@ static int write_oob_to_regs(struct brcmnand_controller *ctrl, int i,
|
||||
(oob[j + 2] << 8) |
|
||||
(oob[j + 3] << 0));
|
||||
|
||||
/* handle the remaing bytes */
|
||||
/* handle the remaining bytes */
|
||||
while (j < tbytes)
|
||||
plast[k++] = oob[j++];
|
||||
|
||||
|
@ -1891,7 +1891,7 @@ static int cadence_nand_read_buf(struct cdns_nand_ctrl *cdns_ctrl,
|
||||
|
||||
int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3;
|
||||
|
||||
/* read alingment data */
|
||||
/* read alignment data */
|
||||
if (data_dma_width == 4)
|
||||
ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words);
|
||||
#ifdef CONFIG_64BIT
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define NR_CS553X_CONTROLLERS 4
|
||||
|
||||
#define MSR_DIVIL_GLD_CAP 0x51400000 /* DIVIL capabilitiies */
|
||||
#define MSR_DIVIL_GLD_CAP 0x51400000 /* DIVIL capabilities */
|
||||
#define CAP_CS5535 0x2df000ULL
|
||||
#define CAP_CS5536 0x5df500ULL
|
||||
|
||||
|
@ -10,15 +10,15 @@
|
||||
* Dirk Behme <Dirk.Behme@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/mtd/rawnand.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/rawnand.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define NRCSR_OFFSET 0x00
|
||||
#define NANDFCR_OFFSET 0x60
|
||||
@ -487,10 +487,10 @@ static const struct of_device_id davinci_nand_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, davinci_nand_of_match);
|
||||
|
||||
static struct davinci_nand_pdata
|
||||
*nand_davinci_get_pdata(struct platform_device *pdev)
|
||||
static struct davinci_nand_pdata *
|
||||
nand_davinci_get_pdata(struct platform_device *pdev)
|
||||
{
|
||||
if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) {
|
||||
if (!dev_get_platdata(&pdev->dev)) {
|
||||
struct davinci_nand_pdata *pdata;
|
||||
const char *mode;
|
||||
u32 prop;
|
||||
@ -501,23 +501,24 @@ static struct davinci_nand_pdata
|
||||
pdev->dev.platform_data = pdata;
|
||||
if (!pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (!of_property_read_u32(pdev->dev.of_node,
|
||||
"ti,davinci-chipselect", &prop))
|
||||
if (!device_property_read_u32(&pdev->dev,
|
||||
"ti,davinci-chipselect", &prop))
|
||||
pdata->core_chipsel = prop;
|
||||
else
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!of_property_read_u32(pdev->dev.of_node,
|
||||
"ti,davinci-mask-ale", &prop))
|
||||
if (!device_property_read_u32(&pdev->dev,
|
||||
"ti,davinci-mask-ale", &prop))
|
||||
pdata->mask_ale = prop;
|
||||
if (!of_property_read_u32(pdev->dev.of_node,
|
||||
"ti,davinci-mask-cle", &prop))
|
||||
if (!device_property_read_u32(&pdev->dev,
|
||||
"ti,davinci-mask-cle", &prop))
|
||||
pdata->mask_cle = prop;
|
||||
if (!of_property_read_u32(pdev->dev.of_node,
|
||||
"ti,davinci-mask-chipsel", &prop))
|
||||
if (!device_property_read_u32(&pdev->dev,
|
||||
"ti,davinci-mask-chipsel", &prop))
|
||||
pdata->mask_chipsel = prop;
|
||||
if (!of_property_read_string(pdev->dev.of_node,
|
||||
"ti,davinci-ecc-mode", &mode)) {
|
||||
if (!device_property_read_string(&pdev->dev,
|
||||
"ti,davinci-ecc-mode",
|
||||
&mode)) {
|
||||
if (!strncmp("none", mode, 4))
|
||||
pdata->engine_type = NAND_ECC_ENGINE_TYPE_NONE;
|
||||
if (!strncmp("soft", mode, 4))
|
||||
@ -525,16 +526,17 @@ static struct davinci_nand_pdata
|
||||
if (!strncmp("hw", mode, 2))
|
||||
pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
|
||||
}
|
||||
if (!of_property_read_u32(pdev->dev.of_node,
|
||||
"ti,davinci-ecc-bits", &prop))
|
||||
if (!device_property_read_u32(&pdev->dev,
|
||||
"ti,davinci-ecc-bits", &prop))
|
||||
pdata->ecc_bits = prop;
|
||||
|
||||
if (!of_property_read_u32(pdev->dev.of_node,
|
||||
"ti,davinci-nand-buswidth", &prop) && prop == 16)
|
||||
if (!device_property_read_u32(&pdev->dev,
|
||||
"ti,davinci-nand-buswidth",
|
||||
&prop) && prop == 16)
|
||||
pdata->options |= NAND_BUSWIDTH_16;
|
||||
|
||||
if (of_property_read_bool(pdev->dev.of_node,
|
||||
"ti,davinci-nand-use-bbt"))
|
||||
if (device_property_read_bool(&pdev->dev,
|
||||
"ti,davinci-nand-use-bbt"))
|
||||
pdata->bbt_options = NAND_BBT_USE_FLASH;
|
||||
|
||||
/*
|
||||
@ -548,17 +550,15 @@ static struct davinci_nand_pdata
|
||||
* then use "ti,davinci-nand" as the compatible in your
|
||||
* device-tree file.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"ti,keystone-nand")) {
|
||||
if (device_is_compatible(&pdev->dev, "ti,keystone-nand"))
|
||||
pdata->options |= NAND_NO_SUBPAGE_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
return dev_get_platdata(&pdev->dev);
|
||||
}
|
||||
#else
|
||||
static struct davinci_nand_pdata
|
||||
*nand_davinci_get_pdata(struct platform_device *pdev)
|
||||
static struct davinci_nand_pdata *
|
||||
nand_davinci_get_pdata(struct platform_device *pdev)
|
||||
{
|
||||
return dev_get_platdata(&pdev->dev);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/dma/mxs-dma.h>
|
||||
#include "gpmi-nand.h"
|
||||
#include "gpmi-regs.h"
|
||||
@ -737,9 +738,8 @@ static int bch_set_geometry(struct gpmi_nand_data *this)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_get_sync(this->dev);
|
||||
ret = pm_runtime_resume_and_get(this->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_autosuspend(this->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2761,15 +2761,9 @@ static int gpmi_nand_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto exit_acquire_resources;
|
||||
|
||||
ret = __gpmi_enable_clk(this, true);
|
||||
if (ret)
|
||||
goto exit_acquire_resources;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
ret = gpmi_init(this);
|
||||
if (ret)
|
||||
@ -2779,15 +2773,12 @@ static int gpmi_nand_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto exit_nfc_init;
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
dev_info(this->dev, "driver registered.\n");
|
||||
|
||||
return 0;
|
||||
|
||||
exit_nfc_init:
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
release_resources(this);
|
||||
exit_acquire_resources:
|
||||
@ -2801,23 +2792,23 @@ static void gpmi_nand_remove(struct platform_device *pdev)
|
||||
struct nand_chip *chip = &this->nand;
|
||||
int ret;
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
ret = mtd_device_unregister(nand_to_mtd(chip));
|
||||
WARN_ON(ret);
|
||||
nand_cleanup(chip);
|
||||
gpmi_free_dma_buffer(this);
|
||||
release_resources(this);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int gpmi_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct gpmi_nand_data *this = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
release_dma_channels(this);
|
||||
return 0;
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
ret = pm_runtime_force_suspend(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpmi_pm_resume(struct device *dev)
|
||||
@ -2825,9 +2816,13 @@ static int gpmi_pm_resume(struct device *dev)
|
||||
struct gpmi_nand_data *this = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = acquire_dma_channels(this);
|
||||
if (ret < 0)
|
||||
ret = pm_runtime_force_resume(dev);
|
||||
if (ret) {
|
||||
dev_err(this->dev, "Error in resume %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pinctrl_pm_select_default_state(dev);
|
||||
|
||||
/* re-init the GPMI registers */
|
||||
ret = gpmi_init(this);
|
||||
@ -2849,31 +2844,41 @@ static int gpmi_pm_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static int __maybe_unused gpmi_runtime_suspend(struct device *dev)
|
||||
#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
|
||||
#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
|
||||
|
||||
static int gpmi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct gpmi_nand_data *this = dev_get_drvdata(dev);
|
||||
|
||||
return __gpmi_enable_clk(this, false);
|
||||
gpmi_disable_clk(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused gpmi_runtime_resume(struct device *dev)
|
||||
static int gpmi_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct gpmi_nand_data *this = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = gpmi_enable_clk(this);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
return __gpmi_enable_clk(this, true);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops gpmi_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(gpmi_pm_suspend, gpmi_pm_resume)
|
||||
SET_RUNTIME_PM_OPS(gpmi_runtime_suspend, gpmi_runtime_resume, NULL)
|
||||
SYSTEM_SLEEP_PM_OPS(gpmi_pm_suspend, gpmi_pm_resume)
|
||||
RUNTIME_PM_OPS(gpmi_runtime_suspend, gpmi_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver gpmi_nand_driver = {
|
||||
.driver = {
|
||||
.name = "gpmi-nand",
|
||||
.pm = &gpmi_pm_ops,
|
||||
.pm = pm_ptr(&gpmi_pm_ops),
|
||||
.of_match_table = gpmi_nand_id_table,
|
||||
},
|
||||
.probe = gpmi_nand_probe,
|
||||
|
@ -113,7 +113,7 @@ static void macronix_nand_onfi_init(struct nand_chip *chip)
|
||||
rand_otp = of_property_read_bool(dn, "mxic,enable-randomizer-otp");
|
||||
|
||||
mxic = (struct nand_onfi_vendor_macronix *)p->onfi->vendor;
|
||||
/* Subpage write is prohibited in randomizer operatoin */
|
||||
/* Subpage write is prohibited in randomizer operation */
|
||||
if (rand_otp && chip->options & NAND_NO_SUBPAGE_WRITE &&
|
||||
mxic->reliability_func & MACRONIX_RANDOMIZER_BIT) {
|
||||
if (p->supports_set_get_features) {
|
||||
|
@ -187,7 +187,7 @@ static const struct mtd_ooblayout_ops pl35x_ecc_ooblayout16_ops = {
|
||||
.free = pl35x_ecc_ooblayout16_free,
|
||||
};
|
||||
|
||||
/* Generic flash bbt decriptors */
|
||||
/* Generic flash bbt descriptors */
|
||||
static u8 bbt_pattern[] = { 'B', 'b', 't', '0' };
|
||||
static u8 mirror_pattern[] = { '1', 't', 'b', 'B' };
|
||||
|
||||
|
@ -335,7 +335,7 @@ static void r852_cmdctl(struct nand_chip *chip, int dat, unsigned int ctrl)
|
||||
else
|
||||
dev->ctlreg &= ~R852_CTL_WRITE;
|
||||
|
||||
/* when write is stareted, enable write access */
|
||||
/* when write is started, enable write access */
|
||||
if (dat == NAND_CMD_ERASE1)
|
||||
dev->ctlreg |= R852_CTL_WRITE;
|
||||
|
||||
@ -372,7 +372,7 @@ static int r852_wait(struct nand_chip *chip)
|
||||
|
||||
nand_status_op(chip, &status);
|
||||
|
||||
/* Unfortunelly, no way to send detailed error status... */
|
||||
/* Unfortunately, no way to send detailed error status... */
|
||||
if (dev->dma_error) {
|
||||
status |= NAND_STATUS_FAIL;
|
||||
dev->dma_error = 0;
|
||||
|
@ -52,8 +52,8 @@ static const struct mtd_ooblayout_ops oob_sm_ops = {
|
||||
.free = oob_sm_ooblayout_free,
|
||||
};
|
||||
|
||||
/* NOTE: This layout is not compatabable with SmartMedia, */
|
||||
/* because the 256 byte devices have page depenent oob layout */
|
||||
/* NOTE: This layout is not compatible with SmartMedia, */
|
||||
/* because the 256 byte devices have page dependent oob layout */
|
||||
/* However it does preserve the bad block markers */
|
||||
/* If you use smftl, it will bypass this and work correctly */
|
||||
/* If you not, then you break SmartMedia compliance anyway */
|
||||
|
@ -337,7 +337,7 @@ static int spinand_ondie_ecc_finish_io_req(struct nand_device *nand,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct nand_ecc_engine_ops spinand_ondie_ecc_engine_ops = {
|
||||
static const struct nand_ecc_engine_ops spinand_ondie_ecc_engine_ops = {
|
||||
.init_ctx = spinand_ondie_ecc_init_ctx,
|
||||
.cleanup_ctx = spinand_ondie_ecc_cleanup_ctx,
|
||||
.prepare_io_req = spinand_ondie_ecc_prepare_io_req,
|
||||
|
@ -161,7 +161,55 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
|
||||
}
|
||||
|
||||
static const struct spinand_info winbond_spinand_table[] = {
|
||||
SPINAND_INFO("W25M02GV",
|
||||
/* 512M-bit densities */
|
||||
SPINAND_INFO("W25N512GW", /* 1.8V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x20),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 512, 10, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
||||
/* 1G-bit densities */
|
||||
SPINAND_INFO("W25N01GV", /* 3.3V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
||||
SPINAND_INFO("W25N01GW", /* 1.8V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
||||
SPINAND_INFO("W25N01JW", /* high-speed 1.8V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
||||
SPINAND_INFO("W25N01KV", /* 3.3V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
|
||||
NAND_MEMORG(1, 2048, 96, 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(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
|
||||
/* 2G-bit densities */
|
||||
SPINAND_INFO("W25M02GV", /* 2x1G-bit 3.3V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
|
||||
NAND_ECCREQ(1, 512),
|
||||
@ -171,25 +219,16 @@ static const struct spinand_info winbond_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
|
||||
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
|
||||
SPINAND_INFO("W25N01GV",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
SPINAND_INFO("W25N02JW", /* high-speed 1.8V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
||||
SPINAND_INFO("W25N01KV",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
|
||||
NAND_MEMORG(1, 2048, 96, 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(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
|
||||
SPINAND_INFO("W25N02KV",
|
||||
SPINAND_INFO("W25N02KV", /* 3.3V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@ -198,34 +237,7 @@ 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_INFO("W25N02KW", /* 1.8V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@ -234,18 +246,19 @@ static const struct spinand_info winbond_spinand_table[] = {
|
||||
&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),
|
||||
/* 4G-bit densities */
|
||||
SPINAND_INFO("W25N04KV", /* 3.3V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1),
|
||||
NAND_ECCREQ(8, 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("W25N04KV",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1),
|
||||
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
|
||||
SPINAND_INFO("W25N04KW", /* 1.8V */
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x23),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
|
@ -776,7 +776,7 @@ static int mtk_snand_ecc_finish_io_req(struct nand_device *nand,
|
||||
return snf->ecc_stats.failed ? -EBADMSG : snf->ecc_stats.bitflips;
|
||||
}
|
||||
|
||||
static struct nand_ecc_engine_ops mtk_snfi_ecc_engine_ops = {
|
||||
static const struct nand_ecc_engine_ops mtk_snfi_ecc_engine_ops = {
|
||||
.init_ctx = mtk_snand_ecc_init_ctx,
|
||||
.cleanup_ctx = mtk_snand_ecc_cleanup_ctx,
|
||||
.prepare_io_req = mtk_snand_ecc_prepare_io_req,
|
||||
|
@ -649,7 +649,7 @@ static int mxic_spi_transfer_one(struct spi_controller *host,
|
||||
/* ECC wrapper */
|
||||
static int mxic_spi_mem_ecc_init_ctx(struct nand_device *nand)
|
||||
{
|
||||
struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
const struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
struct mxic_spi *mxic = nand->ecc.engine->priv;
|
||||
|
||||
mxic->ecc.use_pipelined_conf = true;
|
||||
@ -659,7 +659,7 @@ static int mxic_spi_mem_ecc_init_ctx(struct nand_device *nand)
|
||||
|
||||
static void mxic_spi_mem_ecc_cleanup_ctx(struct nand_device *nand)
|
||||
{
|
||||
struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
const struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
struct mxic_spi *mxic = nand->ecc.engine->priv;
|
||||
|
||||
mxic->ecc.use_pipelined_conf = false;
|
||||
@ -670,7 +670,7 @@ static void mxic_spi_mem_ecc_cleanup_ctx(struct nand_device *nand)
|
||||
static int mxic_spi_mem_ecc_prepare_io_req(struct nand_device *nand,
|
||||
struct nand_page_io_req *req)
|
||||
{
|
||||
struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
const struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
|
||||
return ops->prepare_io_req(nand, req);
|
||||
}
|
||||
@ -678,12 +678,12 @@ static int mxic_spi_mem_ecc_prepare_io_req(struct nand_device *nand,
|
||||
static int mxic_spi_mem_ecc_finish_io_req(struct nand_device *nand,
|
||||
struct nand_page_io_req *req)
|
||||
{
|
||||
struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
const struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops();
|
||||
|
||||
return ops->finish_io_req(nand, req);
|
||||
}
|
||||
|
||||
static struct nand_ecc_engine_ops mxic_spi_mem_ecc_engine_pipelined_ops = {
|
||||
static const struct nand_ecc_engine_ops mxic_spi_mem_ecc_engine_pipelined_ops = {
|
||||
.init_ctx = mxic_spi_mem_ecc_init_ctx,
|
||||
.cleanup_ctx = mxic_spi_mem_ecc_cleanup_ctx,
|
||||
.prepare_io_req = mxic_spi_mem_ecc_prepare_io_req,
|
||||
|
@ -16,7 +16,7 @@ struct mxic_ecc_engine;
|
||||
|
||||
#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MXIC) && IS_REACHABLE(CONFIG_MTD_NAND_CORE)
|
||||
|
||||
struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void);
|
||||
const struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void);
|
||||
struct nand_ecc_engine *mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev);
|
||||
void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng);
|
||||
int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng,
|
||||
@ -24,7 +24,7 @@ int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng,
|
||||
|
||||
#else /* !CONFIG_MTD_NAND_ECC_MXIC */
|
||||
|
||||
static inline struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void)
|
||||
static inline const struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ enum nand_ecc_engine_integration {
|
||||
struct nand_ecc_engine {
|
||||
struct device *dev;
|
||||
struct list_head node;
|
||||
struct nand_ecc_engine_ops *ops;
|
||||
const struct nand_ecc_engine_ops *ops;
|
||||
enum nand_ecc_engine_integration integration;
|
||||
void *priv;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user