Commit c8273a25 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull mtd fixes from Miquel Raynal:
 "Raw NAND fixes:
   - fsl_upm: Fix an off-by one test in fun_exec_op()
   - Rockchip:
       - Align hwecc vs. raw page helper layouts
       - Fix oobfree offset and description
   - Meson: Fix OOB available bytes for ECC
   - Omap ELM: Fix incorrect type in assignment

  SPI-NOR fix:
   - Avoid holes in struct spi_mem_op

  Hyperbus fix:
   - Add Tudor as reviewer in MAINTAINERS

  SPI-NAND fixes:
   - Winbond and Toshiba: Fix ecc_get_status"

* tag 'mtd/fixes-for-6.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux:
  mtd: rawnand: fsl_upm: Fix an off-by one test in fun_exec_op()
  mtd: spi-nor: avoid holes in struct spi_mem_op
  MAINTAINERS: Add myself as reviewer for HYPERBUS
  mtd: rawnand: rockchip: Align hwecc vs. raw page helper layouts
  mtd: rawnand: rockchip: fix oobfree offset and description
  mtd: rawnand: meson: fix OOB available bytes for ECC
  mtd: rawnand: omap_elm: Fix incorrect type in assignment
  mtd: spinand: winbond: Fix ecc_get_status
  mtd: spinand: toshiba: Fix ecc_get_status
parents 4142fc67 c6abce60
...@@ -9660,6 +9660,7 @@ F: tools/hv/ ...@@ -9660,6 +9660,7 @@ F: tools/hv/
HYPERBUS SUPPORT HYPERBUS SUPPORT
M: Vignesh Raghavendra <vigneshr@ti.com> M: Vignesh Raghavendra <vigneshr@ti.com>
R: Tudor Ambarus <tudor.ambarus@linaro.org>
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
S: Supported S: Supported
Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
......
...@@ -135,7 +135,7 @@ static int fun_exec_op(struct nand_chip *chip, const struct nand_operation *op, ...@@ -135,7 +135,7 @@ static int fun_exec_op(struct nand_chip *chip, const struct nand_operation *op,
unsigned int i; unsigned int i;
int ret; int ret;
if (op->cs > NAND_MAX_CHIPS) if (op->cs >= NAND_MAX_CHIPS)
return -EINVAL; return -EINVAL;
if (check_only) if (check_only)
......
...@@ -1278,7 +1278,6 @@ static int meson_nand_attach_chip(struct nand_chip *nand) ...@@ -1278,7 +1278,6 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
struct meson_nfc *nfc = nand_get_controller_data(nand); struct meson_nfc *nfc = nand_get_controller_data(nand);
struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
struct mtd_info *mtd = nand_to_mtd(nand); struct mtd_info *mtd = nand_to_mtd(nand);
int nsectors = mtd->writesize / 1024;
int raw_writesize; int raw_writesize;
int ret; int ret;
...@@ -1304,7 +1303,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand) ...@@ -1304,7 +1303,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
nand->options |= NAND_NO_SUBPAGE_WRITE; nand->options |= NAND_NO_SUBPAGE_WRITE;
ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps,
mtd->oobsize - 2 * nsectors); mtd->oobsize - 2);
if (ret) { if (ret) {
dev_err(nfc->dev, "failed to ECC init\n"); dev_err(nfc->dev, "failed to ECC init\n");
return -EINVAL; return -EINVAL;
......
...@@ -177,17 +177,17 @@ static void elm_load_syndrome(struct elm_info *info, ...@@ -177,17 +177,17 @@ static void elm_load_syndrome(struct elm_info *info,
switch (info->bch_type) { switch (info->bch_type) {
case BCH8_ECC: case BCH8_ECC:
/* syndrome fragment 0 = ecc[9-12B] */ /* syndrome fragment 0 = ecc[9-12B] */
val = cpu_to_be32(*(u32 *) &ecc[9]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 1 = ecc[5-8B] */ /* syndrome fragment 1 = ecc[5-8B] */
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[5]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 2 = ecc[1-4B] */ /* syndrome fragment 2 = ecc[1-4B] */
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[1]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 3 = ecc[0B] */ /* syndrome fragment 3 = ecc[0B] */
...@@ -197,35 +197,35 @@ static void elm_load_syndrome(struct elm_info *info, ...@@ -197,35 +197,35 @@ static void elm_load_syndrome(struct elm_info *info,
break; break;
case BCH4_ECC: case BCH4_ECC:
/* syndrome fragment 0 = ecc[20-52b] bits */ /* syndrome fragment 0 = ecc[20-52b] bits */
val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) |
((ecc[2] & 0xf) << 28); ((ecc[2] & 0xf) << 28);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 1 = ecc[0-20b] bits */ /* syndrome fragment 1 = ecc[0-20b] bits */
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12;
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
break; break;
case BCH16_ECC: case BCH16_ECC:
val = cpu_to_be32(*(u32 *) &ecc[22]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[18]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[14]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[10]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[6]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[2]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16;
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
break; break;
default: default:
......
...@@ -562,9 +562,10 @@ static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, ...@@ -562,9 +562,10 @@ static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf,
* BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3
* *
* The rk_nfc_ooblayout_free() function already has reserved * The rk_nfc_ooblayout_free() function already has reserved
* these 4 bytes with: * these 4 bytes together with 2 bytes for BBM
* by reducing it's length:
* *
* oob_region->offset = NFC_SYS_DATA_SIZE + 2; * oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2;
*/ */
if (!i) if (!i)
memcpy(rk_nfc_oob_ptr(chip, i), memcpy(rk_nfc_oob_ptr(chip, i),
...@@ -597,7 +598,7 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, ...@@ -597,7 +598,7 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
int pages_per_blk = mtd->erasesize / mtd->writesize; int pages_per_blk = mtd->erasesize / mtd->writesize;
int ret = 0, i, boot_rom_mode = 0; int ret = 0, i, boot_rom_mode = 0;
dma_addr_t dma_data, dma_oob; dma_addr_t dma_data, dma_oob;
u32 reg; u32 tmp;
u8 *oob; u8 *oob;
nand_prog_page_begin_op(chip, page, 0, NULL, 0); nand_prog_page_begin_op(chip, page, 0, NULL, 0);
...@@ -624,6 +625,13 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, ...@@ -624,6 +625,13 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
* *
* 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
* *
* The code here just swaps the first 4 bytes with the last
* 4 bytes without losing any data.
*
* The chip->oob_poi data layout:
*
* BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3
*
* Configure the ECC algorithm supported by the boot ROM. * Configure the ECC algorithm supported by the boot ROM.
*/ */
if ((page < (pages_per_blk * rknand->boot_blks)) && if ((page < (pages_per_blk * rknand->boot_blks)) &&
...@@ -634,21 +642,17 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, ...@@ -634,21 +642,17 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
} }
for (i = 0; i < ecc->steps; i++) { for (i = 0; i < ecc->steps; i++) {
if (!i) { if (!i)
reg = 0xFFFFFFFF; oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE;
} else { else
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
reg = oob[0] | oob[1] << 8 | oob[2] << 16 |
oob[3] << 24;
}
if (!i && boot_rom_mode) tmp = oob[0] | oob[1] << 8 | oob[2] << 16 | oob[3] << 24;
reg = (page & (pages_per_blk - 1)) * 4;
if (nfc->cfg->type == NFC_V9) if (nfc->cfg->type == NFC_V9)
nfc->oob_buf[i] = reg; nfc->oob_buf[i] = tmp;
else else
nfc->oob_buf[i * (oob_step / 4)] = reg; nfc->oob_buf[i * (oob_step / 4)] = tmp;
} }
dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf,
...@@ -811,12 +815,17 @@ static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on, ...@@ -811,12 +815,17 @@ static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on,
goto timeout_err; goto timeout_err;
} }
for (i = 1; i < ecc->steps; i++) { for (i = 0; i < ecc->steps; i++) {
if (!i)
oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE;
else
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
if (nfc->cfg->type == NFC_V9) if (nfc->cfg->type == NFC_V9)
tmp = nfc->oob_buf[i]; tmp = nfc->oob_buf[i];
else else
tmp = nfc->oob_buf[i * (oob_step / 4)]; tmp = nfc->oob_buf[i * (oob_step / 4)];
*oob++ = (u8)tmp; *oob++ = (u8)tmp;
*oob++ = (u8)(tmp >> 8); *oob++ = (u8)(tmp >> 8);
*oob++ = (u8)(tmp >> 16); *oob++ = (u8)(tmp >> 16);
...@@ -933,12 +942,8 @@ static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section, ...@@ -933,12 +942,8 @@ static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section,
if (section) if (section)
return -ERANGE; return -ERANGE;
/*
* The beginning of the OOB area stores the reserved data for the NFC,
* the size of the reserved data is NFC_SYS_DATA_SIZE bytes.
*/
oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2;
oob_region->offset = NFC_SYS_DATA_SIZE + 2; oob_region->offset = 2;
return 0; return 0;
} }
......
...@@ -73,7 +73,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, ...@@ -73,7 +73,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
{ {
struct nand_device *nand = spinand_to_nand(spinand); struct nand_device *nand = spinand_to_nand(spinand);
u8 mbf = 0; u8 mbf = 0;
struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf);
switch (status & STATUS_ECC_MASK) { switch (status & STATUS_ECC_MASK) {
case STATUS_ECC_NO_BITFLIPS: case STATUS_ECC_NO_BITFLIPS:
...@@ -92,7 +92,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, ...@@ -92,7 +92,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
if (spi_mem_exec_op(spinand->spimem, &op)) if (spi_mem_exec_op(spinand->spimem, &op))
return nanddev_get_ecc_conf(nand)->strength; return nanddev_get_ecc_conf(nand)->strength;
mbf >>= 4; mbf = *(spinand->scratchbuf) >> 4;
if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
return nanddev_get_ecc_conf(nand)->strength; return nanddev_get_ecc_conf(nand)->strength;
......
...@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand, ...@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
{ {
struct nand_device *nand = spinand_to_nand(spinand); struct nand_device *nand = spinand_to_nand(spinand);
u8 mbf = 0; u8 mbf = 0;
struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf);
switch (status & STATUS_ECC_MASK) { switch (status & STATUS_ECC_MASK) {
case STATUS_ECC_NO_BITFLIPS: case STATUS_ECC_NO_BITFLIPS:
...@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand, ...@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
if (spi_mem_exec_op(spinand->spimem, &op)) if (spi_mem_exec_op(spinand->spimem, &op))
return nanddev_get_ecc_conf(nand)->strength; return nanddev_get_ecc_conf(nand)->strength;
mbf >>= 4; mbf = *(spinand->scratchbuf) >> 4;
if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
return nanddev_get_ecc_conf(nand)->strength; return nanddev_get_ecc_conf(nand)->strength;
......
...@@ -361,7 +361,7 @@ static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor, ...@@ -361,7 +361,7 @@ static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
*/ */
static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor) static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
{ {
struct spi_mem_op op = {}; struct spi_mem_op op;
u8 addr_mode; u8 addr_mode;
int ret; int ret;
...@@ -492,7 +492,7 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor, ...@@ -492,7 +492,7 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
const struct sfdp_parameter_header *bfpt_header, const struct sfdp_parameter_header *bfpt_header,
const struct sfdp_bfpt *bfpt) const struct sfdp_bfpt *bfpt)
{ {
struct spi_mem_op op = {}; struct spi_mem_op op;
int ret; int ret;
ret = cypress_nor_set_addr_mode_nbytes(nor); ret = cypress_nor_set_addr_mode_nbytes(nor);
......
...@@ -101,6 +101,7 @@ struct spi_mem_op { ...@@ -101,6 +101,7 @@ struct spi_mem_op {
u8 nbytes; u8 nbytes;
u8 buswidth; u8 buswidth;
u8 dtr : 1; u8 dtr : 1;
u8 __pad : 7;
u16 opcode; u16 opcode;
} cmd; } cmd;
...@@ -108,6 +109,7 @@ struct spi_mem_op { ...@@ -108,6 +109,7 @@ struct spi_mem_op {
u8 nbytes; u8 nbytes;
u8 buswidth; u8 buswidth;
u8 dtr : 1; u8 dtr : 1;
u8 __pad : 7;
u64 val; u64 val;
} addr; } addr;
...@@ -115,12 +117,14 @@ struct spi_mem_op { ...@@ -115,12 +117,14 @@ struct spi_mem_op {
u8 nbytes; u8 nbytes;
u8 buswidth; u8 buswidth;
u8 dtr : 1; u8 dtr : 1;
u8 __pad : 7;
} dummy; } dummy;
struct { struct {
u8 buswidth; u8 buswidth;
u8 dtr : 1; u8 dtr : 1;
u8 ecc : 1; u8 ecc : 1;
u8 __pad : 6;
enum spi_mem_data_dir dir; enum spi_mem_data_dir dir;
unsigned int nbytes; unsigned int nbytes;
union { union {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment