1
0
Fork 0

NAND fixes:

- Add a quirk for a bunch of broken Macronix chips
 - Fix nand_block_bad() when chip->ecc.read_oob() returns a positive
   value encoding the number of bitflips
 - Fix OOB handling in the MXC driver fo V2.1 controllers
 - Flag the ONFI_FEATURE_ON_DIE_ECC as supported in the Micron driver
 - Hardcode clk rate in the denali_dt driver to address a bad DT
   representation (the proper fix will be queued for 4.19)
 
 SPI NOR fixes:
 - Add an ULL constant to some ID definitions so that the ID is not
   truncated on 32-bit platforms
 
 MTD fixes:
 - Fix the sector unlocking logic in the CFI driver
 -----BEGIN PGP SIGNATURE-----
 
 iQI5BAABCAAjBQJbNJHjHBxib3Jpcy5icmV6aWxsb25AYm9vdGxpbi5jb20ACgkQ
 Ze02AX4ItwBEFBAAw65L3Su2REWkqWe0x2lfT/OB61CUd7NlLLifjjxWj6ysRrlO
 BiomFoeXITlDPNMWLMYygzm7e8Lf2+Nb59pM4aMS/V+Yech6HD6j8qld7IJrz7/U
 YBRUNTKTfkc1jI2KothXWWLcltAtS0XzADTs+Lxn5BZ0a4idFay/iqeB/wDIwZ/T
 dQi08OrlbZ/H3ggLN7PoCK+vRnamjpnLecYdkHSMNP/T0msKPT6UJxZaoTZURBlq
 qeI6rClcwFlfjYFV70UchgjeD++rhE1cy14jO38dodbpPl3qoRiqsFi3kFHjn+a1
 b+nJXIQWL5U1NzWiVNwxQHpoeRHU39Cpg1VxMcAjtkHJxnHKZ9C+dkYZXYAmchfv
 QYD0cd7KlmYgHNBjYKlUeBdS/X1qnTYx7su/69YavxgPzscaFuOHS8AgctvmJJhc
 dMxDJR29lgtKOOB+AsNo+8wRtZpEef3pE/s14QZmR7/71tIAxBVVlakWCH3ND3NJ
 7lTL8BT8bAp0v2EcEMghyc71ryT0gCZdSHMOvJ/bQadnB//LTT9aXkDW2IdRHfQ0
 DyBtnHlZxudYLZJ/uIB8zsoYY852rYYFaJ/H5gUafQdZ+8NWT7zYdlizXtzGxcEF
 Eq8CxDdbKmVSwpic/Nfl5i5T7zs9BOST3UkG/yiimx9X+GlSAGTRaKv7JIw=
 =BjBU
 -----END PGP SIGNATURE-----

Merge tag 'mtd/fixes-for-4.18-rc3' of git://git.infradead.org/linux-mtd

Pull mtd fixes from Boris Brezillon:
 "NAND fixes:

   - add a quirk for a bunch of broken Macronix chips

   - fix nand_block_bad() when chip->ecc.read_oob() returns a positive
     value encoding the number of bitflips

   - fix OOB handling in the MXC driver fo V2.1 controllers

   - flag the ONFI_FEATURE_ON_DIE_ECC as supported in the Micron driver

   - hardcode clk rate in the denali_dt driver to address a bad DT
     representation (the proper fix will be queued for 4.19)

  SPI NOR fixes:

   - add an ULL constant to some ID definitions so that the ID is not
     truncated on 32-bit platforms

  MTD fixes:

   - fix the sector unlocking logic in the CFI driver"

* tag 'mtd/fixes-for-4.18-rc3' of git://git.infradead.org/linux-mtd:
  mtd: rawnand: denali_dt: set clk_x_rate to 200 MHz unconditionally
  mtd: dataflash: Use ULL suffix for 64-bit constants
  mtd: cfi_cmdset_0002: Avoid walking all chips when unlocking.
  mtd: cfi_cmdset_0002: Fix unlocking requests crossing a chip boudary
  mtd: cfi_cmdset_0002: fix SEGV unlocking multiple chips
  mtd: cfi_cmdset_0002: Use right chip in do_ppb_xxlock()
  mtd: rawnand: All AC chips have a broken GET_FEATURES(TIMINGS).
  mtd: rawnand: fix return value check for bad block status
  mtd: rawnand: mxc: set spare area size register explicitly
  mtd: rawnand: micron: add ONFI_FEATURE_ON_DIE_ECC to supported features
This commit is contained in:
Linus Torvalds 2018-06-28 12:31:59 -07:00
commit c7e1d692ea
7 changed files with 61 additions and 25 deletions

View file

@ -2526,7 +2526,7 @@ static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
struct ppb_lock {
struct flchip *chip;
loff_t offset;
unsigned long adr;
int locked;
};
@ -2544,8 +2544,9 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
unsigned long timeo;
int ret;
adr += chip->start;
mutex_lock(&chip->mutex);
ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
ret = get_chip(map, chip, adr, FL_LOCKING);
if (ret) {
mutex_unlock(&chip->mutex);
return ret;
@ -2563,8 +2564,8 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
chip->state = FL_LOCKING;
map_write(map, CMD(0xA0), chip->start + adr);
map_write(map, CMD(0x00), chip->start + adr);
map_write(map, CMD(0xA0), adr);
map_write(map, CMD(0x00), adr);
} else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) {
/*
* Unlocking of one specific sector is not supported, so we
@ -2602,7 +2603,7 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
map_write(map, CMD(0x00), chip->start);
chip->state = FL_READY;
put_chip(map, chip, adr + chip->start);
put_chip(map, chip, adr);
mutex_unlock(&chip->mutex);
return ret;
@ -2659,9 +2660,9 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
* sectors shall be unlocked, so lets keep their locking
* status at "unlocked" (locked=0) for the final re-locking.
*/
if ((adr < ofs) || (adr >= (ofs + len))) {
if ((offset < ofs) || (offset >= (ofs + len))) {
sect[sectors].chip = &cfi->chips[chipnum];
sect[sectors].offset = offset;
sect[sectors].adr = adr;
sect[sectors].locked = do_ppb_xxlock(
map, &cfi->chips[chipnum], adr, 0,
DO_XXLOCK_ONEBLOCK_GETLOCK);
@ -2675,6 +2676,8 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
i++;
if (adr >> cfi->chipshift) {
if (offset >= (ofs + len))
break;
adr = 0;
chipnum++;
@ -2705,7 +2708,7 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
*/
for (i = 0; i < sectors; i++) {
if (sect[i].locked)
do_ppb_xxlock(map, sect[i].chip, sect[i].offset, 0,
do_ppb_xxlock(map, sect[i].chip, sect[i].adr, 0,
DO_XXLOCK_ONEBLOCK_LOCK);
}

View file

@ -733,8 +733,8 @@ static struct flash_info dataflash_data[] = {
{ "AT45DB642x", 0x1f2800, 8192, 1056, 11, SUP_POW2PS},
{ "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
{ "AT45DB641E", 0x1f28000100, 32768, 264, 9, SUP_EXTID | SUP_POW2PS},
{ "at45db641e", 0x1f28000100, 32768, 256, 8, SUP_EXTID | SUP_POW2PS | IS_POW2PS},
{ "AT45DB641E", 0x1f28000100ULL, 32768, 264, 9, SUP_EXTID | SUP_POW2PS},
{ "at45db641e", 0x1f28000100ULL, 32768, 256, 8, SUP_EXTID | SUP_POW2PS | IS_POW2PS},
};
static struct flash_info *jedec_lookup(struct spi_device *spi,

View file

@ -123,7 +123,11 @@ static int denali_dt_probe(struct platform_device *pdev)
if (ret)
return ret;
denali->clk_x_rate = clk_get_rate(dt->clk);
/*
* Hardcode the clock rate for the backward compatibility.
* This works for both SOCFPGA and UniPhier.
*/
denali->clk_x_rate = 200000000;
ret = denali_init(denali);
if (ret)

View file

@ -48,7 +48,7 @@
#define NFC_V1_V2_CONFIG (host->regs + 0x0a)
#define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
#define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10)
#define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10)
#define NFC_V1_V2_WRPROT (host->regs + 0x12)
#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
@ -1274,6 +1274,9 @@ static void preset_v2(struct mtd_info *mtd)
writew(config1, NFC_V1_V2_CONFIG1);
/* preset operation */
/* spare area size in 16-bit half-words */
writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA);
/* Unlock the internal RAM Buffer */
writew(0x2, NFC_V1_V2_CONFIG);

View file

@ -440,7 +440,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)
for (; page < page_end; page++) {
res = chip->ecc.read_oob(mtd, chip, page);
if (res)
if (res < 0)
return res;
bad = chip->oob_poi[chip->badblockpos];

View file

@ -17,23 +17,47 @@
#include <linux/mtd/rawnand.h>
/*
* Macronix AC series does not support using SET/GET_FEATURES to change
* the timings unlike what is declared in the parameter page. Unflag
* this feature to avoid unnecessary downturns.
*/
static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
{
unsigned int i;
static const char * const broken_get_timings[] = {
"MX30LF1G18AC",
"MX30LF1G28AC",
"MX30LF2G18AC",
"MX30LF2G28AC",
"MX30LF4G18AC",
"MX30LF4G28AC",
"MX60LF8G18AC",
};
if (!chip->parameters.supports_set_get_features)
return;
for (i = 0; i < ARRAY_SIZE(broken_get_timings); i++) {
if (!strcmp(broken_get_timings[i], chip->parameters.model))
break;
}
if (i == ARRAY_SIZE(broken_get_timings))
return;
bitmap_clear(chip->parameters.get_feature_list,
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
bitmap_clear(chip->parameters.set_feature_list,
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
}
static int macronix_nand_init(struct nand_chip *chip)
{
if (nand_is_slc(chip))
chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
/*
* MX30LF2G18AC chip does not support using SET/GET_FEATURES to change
* the timings unlike what is declared in the parameter page. Unflag
* this feature to avoid unnecessary downturns.
*/
if (chip->parameters.supports_set_get_features &&
!strcmp("MX30LF2G18AC", chip->parameters.model)) {
bitmap_clear(chip->parameters.get_feature_list,
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
bitmap_clear(chip->parameters.set_feature_list,
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
}
macronix_nand_fix_broken_get_timings(chip);
return 0;
}

View file

@ -66,7 +66,9 @@ static int micron_nand_onfi_init(struct nand_chip *chip)
if (p->supports_set_get_features) {
set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->set_feature_list);
set_bit(ONFI_FEATURE_ON_DIE_ECC, p->set_feature_list);
set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->get_feature_list);
set_bit(ONFI_FEATURE_ON_DIE_ECC, p->get_feature_list);
}
return 0;