mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-07 14:32:23 +00:00
In the raw NAND subsystem, the major fix prevents using cached reads
with devices not supporting it. There was two bug reports about this. Aside, 3 drivers (pl353, arasan and marvell) could sometimes hide page program failures due to their their own program page helper not being fully compliant with the specification (many drivers use the default helpers shared by the core). Adding a missing check prevents these situation. Finally, the Qualcomm driver had a broken error path. In the SPI-NAND subsystem one Micron device used a wrong bitmak reporting possibly corrupted ECC status. Finally, the physmap-core got stripped from its map_rom fallback by mistake, this feature is added back. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAmUyvxcACgkQJWrqGEe9 VoStmwf9HjOY3kNB37ip0NpG5viRWeLNC8hMxJOJaGZlyX6x9b/88xsBjVFc7z3s hoCBGfOnUSDXk4KfxNiYps5YqfMgb+yLeIGdsDsLhNht6Mh/YOEFzXgcD8+iudKH OpjjJnRzQHxNM3zA3Vauh1XD/j+6uvQ3BHlJpQfA+Ukv4+34Irin4/gKhZCoUedo IJNVU5hurJexCkjGk2yO+B34qD8ZXGKWeXzwsKKYB/FE55iO69GrHNdLBMnFfxu+ uU6GcV+YKroPLDs5mKH2oojKhyAhrh3gQyrNJFnCqh/sVnNCAbD75N+YC6enHeBe ovlc82AWmLUJVktsih27OsU58RnCxA== =7Xq1 -----END PGP SIGNATURE----- Merge tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux Pull MTD fixes from Miquel Raynal: "In the raw NAND subsystem, the major fix prevents using cached reads with devices not supporting it. There was two bug reports about this. Apart from that, three drivers (pl353, arasan and marvell) could sometimes hide page program failures due to their their own program page helper not being fully compliant with the specification (many drivers use the default helpers shared by the core). Adding a missing check prevents these situation. Finally, the Qualcomm driver had a broken error path. In the SPI-NAND subsystem one Micron device used a wrong bitmak reporting possibly corrupted ECC status. Finally, the physmap-core got stripped from its map_rom fallback by mistake, this feature is added back" * tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: mtd: rawnand: Ensure the nand chip supports cached reads mtd: rawnand: qcom: Unmap the right resource upon probe failure mtd: rawnand: pl353: Ensure program page operations are successful mtd: rawnand: arasan: Ensure program page operations are successful mtd: spinand: micron: correct bitmask for ecc status mtd: physmap-core: Restore map_rom fallback mtd: rawnand: marvell: Ensure program page operations are successful
This commit is contained in:
commit
f617647154
@ -551,6 +551,17 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
if (info->probe_type) {
|
||||
info->mtds[i] = do_map_probe(info->probe_type,
|
||||
&info->maps[i]);
|
||||
|
||||
/* Fall back to mapping region as ROM */
|
||||
if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) &&
|
||||
strcmp(info->probe_type, "map_rom")) {
|
||||
dev_warn(&dev->dev,
|
||||
"map_probe() failed for type %s\n",
|
||||
info->probe_type);
|
||||
|
||||
info->mtds[i] = do_map_probe("map_rom",
|
||||
&info->maps[i]);
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
|
||||
|
@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
|
||||
struct mtd_info *mtd = nand_to_mtd(chip);
|
||||
unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
|
||||
dma_addr_t dma_addr;
|
||||
u8 status;
|
||||
int ret;
|
||||
struct anfc_op nfc_op = {
|
||||
.pkt_reg =
|
||||
@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
|
||||
}
|
||||
|
||||
/* Spare data is not protected */
|
||||
if (oob_required)
|
||||
if (oob_required) {
|
||||
ret = nand_write_oob_std(chip, page);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
|
||||
|
@ -1165,6 +1165,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
|
||||
.ndcb[2] = NDCB2_ADDR5_PAGE(page),
|
||||
};
|
||||
unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
|
||||
u8 status;
|
||||
int ret;
|
||||
|
||||
/* NFCv2 needs more information about the operation being executed */
|
||||
@ -1198,7 +1199,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
|
||||
|
||||
ret = marvell_nfc_wait_op(chip,
|
||||
PSEC_TO_MSEC(sdr->tPROG_max));
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip,
|
||||
@ -1627,6 +1639,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
|
||||
int data_len = lt->data_bytes;
|
||||
int spare_len = lt->spare_bytes;
|
||||
int chunk, ret;
|
||||
u8 status;
|
||||
|
||||
marvell_nfc_select_target(chip, chip->cur_cs);
|
||||
|
||||
@ -1663,6 +1676,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5110,6 +5110,9 @@ static void rawnand_check_cont_read_support(struct nand_chip *chip)
|
||||
{
|
||||
struct mtd_info *mtd = nand_to_mtd(chip);
|
||||
|
||||
if (!chip->parameters.supports_read_cache)
|
||||
return;
|
||||
|
||||
if (chip->read_retries)
|
||||
return;
|
||||
|
||||
|
@ -94,6 +94,9 @@ int nand_jedec_detect(struct nand_chip *chip)
|
||||
goto free_jedec_param_page;
|
||||
}
|
||||
|
||||
if (p->opt_cmd[0] & JEDEC_OPT_CMD_READ_CACHE)
|
||||
chip->parameters.supports_read_cache = true;
|
||||
|
||||
memorg->pagesize = le32_to_cpu(p->byte_per_page);
|
||||
mtd->writesize = memorg->pagesize;
|
||||
|
||||
|
@ -303,6 +303,9 @@ int nand_onfi_detect(struct nand_chip *chip)
|
||||
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
|
||||
}
|
||||
|
||||
if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_READ_CACHE)
|
||||
chip->parameters.supports_read_cache = true;
|
||||
|
||||
onfi = kzalloc(sizeof(*onfi), GFP_KERNEL);
|
||||
if (!onfi) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -511,6 +511,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
|
||||
u32 addr1 = 0, addr2 = 0, row;
|
||||
u32 cmd_addr;
|
||||
int i, ret;
|
||||
u8 status;
|
||||
|
||||
ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB);
|
||||
if (ret)
|
||||
@ -563,6 +564,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
|
||||
if (ret)
|
||||
goto disable_ecc_engine;
|
||||
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
goto disable_ecc_engine;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
ret = -EIO;
|
||||
|
||||
disable_ecc_engine:
|
||||
pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS);
|
||||
|
||||
|
@ -3444,7 +3444,7 @@ static int qcom_nandc_probe(struct platform_device *pdev)
|
||||
err_aon_clk:
|
||||
clk_disable_unprepare(nandc->core_clk);
|
||||
err_core_clk:
|
||||
dma_unmap_resource(dev, res->start, resource_size(res),
|
||||
dma_unmap_resource(dev, nandc->base_dma, resource_size(res),
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#define SPINAND_MFR_MICRON 0x2c
|
||||
|
||||
#define MICRON_STATUS_ECC_MASK GENMASK(7, 4)
|
||||
#define MICRON_STATUS_ECC_MASK GENMASK(6, 4)
|
||||
#define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||
#define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
|
||||
#define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
|
||||
|
@ -21,6 +21,9 @@ struct jedec_ecc_info {
|
||||
/* JEDEC features */
|
||||
#define JEDEC_FEATURE_16_BIT_BUS (1 << 0)
|
||||
|
||||
/* JEDEC Optional Commands */
|
||||
#define JEDEC_OPT_CMD_READ_CACHE BIT(1)
|
||||
|
||||
struct nand_jedec_params {
|
||||
/* rev info and features block */
|
||||
/* 'J' 'E' 'S' 'D' */
|
||||
|
@ -55,6 +55,7 @@
|
||||
#define ONFI_SUBFEATURE_PARAM_LEN 4
|
||||
|
||||
/* ONFI optional commands SET/GET FEATURES supported? */
|
||||
#define ONFI_OPT_CMD_READ_CACHE BIT(1)
|
||||
#define ONFI_OPT_CMD_SET_GET_FEATURES BIT(2)
|
||||
|
||||
struct nand_onfi_params {
|
||||
|
@ -225,6 +225,7 @@ struct gpio_desc;
|
||||
* struct nand_parameters - NAND generic parameters from the parameter page
|
||||
* @model: Model name
|
||||
* @supports_set_get_features: The NAND chip supports setting/getting features
|
||||
* @supports_read_cache: The NAND chip supports read cache operations
|
||||
* @set_feature_list: Bitmap of features that can be set
|
||||
* @get_feature_list: Bitmap of features that can be get
|
||||
* @onfi: ONFI specific parameters
|
||||
@ -233,6 +234,7 @@ struct nand_parameters {
|
||||
/* Generic parameters */
|
||||
const char *model;
|
||||
bool supports_set_get_features;
|
||||
bool supports_read_cache;
|
||||
DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER);
|
||||
DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user