Skip to content

Commit cbbf0a7

Browse files
committed
Merge tag 'mtd/for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull mtd updates from Miquel Raynal: "MTD changes: - Apart from a binding conversion to yaml, only minor changes/small fixes have been merged. Raw NAND changes: - Minor fixes for various controller drivers like DMA mapping checks, better timing derivations or bitflip statistics. - some Hynix NAND flashes were not supporting read-retries, so don't even try to do it SPI NAND changes: - In order to support high-speed modes, certain chips need extra configuration like adding more dummy cycles. This is now possible, especially on Winbond chips. - Aside from that, Gigadevice gets support for a new chip (GD5F1GM9). SPI NOR changes: - A notable changes is the fix for exiting 4-byte addressing on Infineon SEMPER flashes. These flashes do not support the standard EX4B opcode (E9h), and use a vendor-specific opcode (B8h) instead. - There is also a fix for unlocking flashes that are write-protected at power-on. This was caused by using an uninitialized mtd_info in spi_nor_try_unlock_all()" * tag 'mtd/for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (26 commits) mtd: spinand: winbond: Add comment about the maximum frequency mtd: spinand: winbond: Enable high-speed modes on w35n0xjw mtd: spinand: winbond: Enable high-speed modes on w25n0xjw mtd: spinand: Add a ->configure_chip() hook mtd: spinand: Add a frequency field to all READ_FROM_CACHE variants mtd: spinand: Fix macro alignment spi: spi-mem: Take into account the actual maximum frequency spi: spi-mem: Use picoseconds for calculating the op durations mtd: rawnand: atmel: set pmecc data setup time mtd: spinand: propagate spinand_wait() errors from spinand_write_page() mtd: rawnand: fsmc: Add missing check after DMA map mtd: rawnand: rockchip: Add missing check after DMA map mtd: rawnand: hynix: don't try read-retry on SLC NANDs mtd: rawnand: atmel: Fix dma_mapping_error() address mtd: nand: brcmnand: fix mtd corrected bits stat mtd: rawnand: renesas: Add missing check after DMA map mtd: spinand: gigadevice: Add support for GD5F1GM9 chips mtd: nand: brcmnand: replace manual string choices with standard helpers mtd: map: Don't use "proxy" headers mtd: spi-nor: Fix spi_nor_try_unlock_all() ...
2 parents 2d945dd + 9cf9db8 commit cbbf0a7

32 files changed

+556
-258
lines changed

Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ properties:
2020
- pattern: "^((((micron|spansion|st),)?\
2121
(m25p(40|80|16|32|64|128)|\
2222
n25q(32b|064|128a11|128a13|256a|512a|164k)))|\
23-
atmel,at25df(321a|641|081a)|\
23+
atmel,at(25|26)df(321a|641|081a)|\
2424
everspin,mr25h(10|40|128|256)|\
2525
(mxicy|macronix),mx25l(4005a|1606e|6405d|8005|12805d|25635e)|\
2626
(mxicy|macronix),mx25u(4033|4035)|\
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/mtd/nxp,lpc1773-spifi.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: NXP SPI Flash Interface (SPIFI)
8+
9+
description:
10+
NXP SPIFI is a specialized SPI interface for serial Flash devices.
11+
It supports one Flash device with 1-, 2- and 4-bits width in SPI
12+
mode 0 or 3. The controller operates in either command or memory
13+
mode. In memory mode the Flash is accessible from the CPU as
14+
normal memory.
15+
16+
maintainers:
17+
- Frank Li <[email protected]>
18+
19+
properties:
20+
compatible:
21+
const: nxp,lpc1773-spifi
22+
23+
reg:
24+
maxItems: 2
25+
26+
reg-names:
27+
items:
28+
- const: spifi
29+
- const: flash
30+
31+
interrupts:
32+
maxItems: 1
33+
34+
clocks:
35+
maxItems: 2
36+
37+
clock-names:
38+
items:
39+
- const: spifi
40+
- const: reg
41+
42+
resets:
43+
maxItems: 1
44+
45+
spi-cpol:
46+
enum: [0, 3]
47+
48+
required:
49+
- compatible
50+
- reg
51+
- reg-names
52+
- interrupts
53+
- clocks
54+
- clock-names
55+
56+
allOf:
57+
- $ref: /schemas/spi/spi-controller.yaml#
58+
59+
unevaluatedProperties: false
60+
61+
examples:
62+
- |
63+
#include <dt-bindings/clock/lpc18xx-ccu.h>
64+
65+
spi@40003000 {
66+
compatible = "nxp,lpc1773-spifi";
67+
reg = <0x40003000 0x1000>, <0x14000000 0x4000000>;
68+
reg-names = "spifi", "flash";
69+
interrupts = <30>;
70+
clocks = <&ccu1 CLK_SPIFI>, <&ccu1 CLK_CPU_SPIFI>;
71+
clock-names = "spifi", "reg";
72+
resets = <&rgu 53>;
73+
};
74+

Documentation/devicetree/bindings/mtd/nxp-spifi.txt

Lines changed: 0 additions & 58 deletions
This file was deleted.

drivers/mtd/ftl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ static int erase_xfer(partition_t *part,
344344
return -ENOMEM;
345345

346346
erase->addr = xfer->Offset;
347-
erase->len = 1 << part->header.EraseUnitSize;
347+
erase->len = 1ULL << part->header.EraseUnitSize;
348348

349349
ret = mtd_erase(part->mbd.mtd, erase);
350350
if (!ret) {

drivers/mtd/nand/raw/atmel/nand-controller.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
373373
dma_cookie_t cookie;
374374

375375
buf_dma = dma_map_single(nc->dev, buf, len, dir);
376-
if (dma_mapping_error(nc->dev, dev_dma)) {
376+
if (dma_mapping_error(nc->dev, buf_dma)) {
377377
dev_err(nc->dev,
378378
"Failed to prepare a buffer for DMA access\n");
379379
goto err;

drivers/mtd/nand/raw/atmel/pmecc.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ struct atmel_pmecc_caps {
143143
int nstrengths;
144144
int el_offset;
145145
bool correct_erased_chunks;
146+
bool clk_ctrl;
146147
};
147148

148149
struct atmel_pmecc {
@@ -843,6 +844,10 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
843844
if (IS_ERR(pmecc->regs.errloc))
844845
return ERR_CAST(pmecc->regs.errloc);
845846

847+
/* pmecc data setup time */
848+
if (caps->clk_ctrl)
849+
writel(PMECC_CLK_133MHZ, pmecc->regs.base + ATMEL_PMECC_CLK);
850+
846851
/* Disable all interrupts before registering the PMECC handler. */
847852
writel(0xffffffff, pmecc->regs.base + ATMEL_PMECC_IDR);
848853
atmel_pmecc_reset(pmecc);
@@ -896,6 +901,7 @@ static struct atmel_pmecc_caps at91sam9g45_caps = {
896901
.strengths = atmel_pmecc_strengths,
897902
.nstrengths = 5,
898903
.el_offset = 0x8c,
904+
.clk_ctrl = true,
899905
};
900906

901907
static struct atmel_pmecc_caps sama5d4_caps = {

drivers/mtd/nand/raw/brcmnand/brcmnand.c

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/static_key.h>
3030
#include <linux/list.h>
3131
#include <linux/log2.h>
32+
#include <linux/string_choices.h>
3233

3334
#include "brcmnand.h"
3435

@@ -359,6 +360,7 @@ enum brcmnand_reg {
359360
BRCMNAND_CORR_THRESHOLD_EXT,
360361
BRCMNAND_UNCORR_COUNT,
361362
BRCMNAND_CORR_COUNT,
363+
BRCMNAND_READ_ERROR_COUNT,
362364
BRCMNAND_CORR_EXT_ADDR,
363365
BRCMNAND_CORR_ADDR,
364366
BRCMNAND_UNCORR_EXT_ADDR,
@@ -389,6 +391,7 @@ static const u16 brcmnand_regs_v21[] = {
389391
[BRCMNAND_CORR_THRESHOLD_EXT] = 0,
390392
[BRCMNAND_UNCORR_COUNT] = 0,
391393
[BRCMNAND_CORR_COUNT] = 0,
394+
[BRCMNAND_READ_ERROR_COUNT] = 0,
392395
[BRCMNAND_CORR_EXT_ADDR] = 0x60,
393396
[BRCMNAND_CORR_ADDR] = 0x64,
394397
[BRCMNAND_UNCORR_EXT_ADDR] = 0x68,
@@ -419,6 +422,7 @@ static const u16 brcmnand_regs_v33[] = {
419422
[BRCMNAND_CORR_THRESHOLD_EXT] = 0,
420423
[BRCMNAND_UNCORR_COUNT] = 0,
421424
[BRCMNAND_CORR_COUNT] = 0,
425+
[BRCMNAND_READ_ERROR_COUNT] = 0x80,
422426
[BRCMNAND_CORR_EXT_ADDR] = 0x70,
423427
[BRCMNAND_CORR_ADDR] = 0x74,
424428
[BRCMNAND_UNCORR_EXT_ADDR] = 0x78,
@@ -449,6 +453,7 @@ static const u16 brcmnand_regs_v50[] = {
449453
[BRCMNAND_CORR_THRESHOLD_EXT] = 0,
450454
[BRCMNAND_UNCORR_COUNT] = 0,
451455
[BRCMNAND_CORR_COUNT] = 0,
456+
[BRCMNAND_READ_ERROR_COUNT] = 0x80,
452457
[BRCMNAND_CORR_EXT_ADDR] = 0x70,
453458
[BRCMNAND_CORR_ADDR] = 0x74,
454459
[BRCMNAND_UNCORR_EXT_ADDR] = 0x78,
@@ -479,6 +484,7 @@ static const u16 brcmnand_regs_v60[] = {
479484
[BRCMNAND_CORR_THRESHOLD_EXT] = 0xc4,
480485
[BRCMNAND_UNCORR_COUNT] = 0xfc,
481486
[BRCMNAND_CORR_COUNT] = 0x100,
487+
[BRCMNAND_READ_ERROR_COUNT] = 0x104,
482488
[BRCMNAND_CORR_EXT_ADDR] = 0x10c,
483489
[BRCMNAND_CORR_ADDR] = 0x110,
484490
[BRCMNAND_UNCORR_EXT_ADDR] = 0x114,
@@ -509,6 +515,7 @@ static const u16 brcmnand_regs_v71[] = {
509515
[BRCMNAND_CORR_THRESHOLD_EXT] = 0xe0,
510516
[BRCMNAND_UNCORR_COUNT] = 0xfc,
511517
[BRCMNAND_CORR_COUNT] = 0x100,
518+
[BRCMNAND_READ_ERROR_COUNT] = 0x104,
512519
[BRCMNAND_CORR_EXT_ADDR] = 0x10c,
513520
[BRCMNAND_CORR_ADDR] = 0x110,
514521
[BRCMNAND_UNCORR_EXT_ADDR] = 0x114,
@@ -539,6 +546,7 @@ static const u16 brcmnand_regs_v72[] = {
539546
[BRCMNAND_CORR_THRESHOLD_EXT] = 0xe0,
540547
[BRCMNAND_UNCORR_COUNT] = 0xfc,
541548
[BRCMNAND_CORR_COUNT] = 0x100,
549+
[BRCMNAND_READ_ERROR_COUNT] = 0x104,
542550
[BRCMNAND_CORR_EXT_ADDR] = 0x10c,
543551
[BRCMNAND_CORR_ADDR] = 0x110,
544552
[BRCMNAND_UNCORR_EXT_ADDR] = 0x114,
@@ -959,11 +967,11 @@ static inline u16 brcmnand_cs_offset(struct brcmnand_controller *ctrl, int cs,
959967
return offs_cs0 + cs * ctrl->reg_spacing + cs_offs;
960968
}
961969

962-
static inline u32 brcmnand_count_corrected(struct brcmnand_controller *ctrl)
970+
static inline u32 brcmnand_corr_total(struct brcmnand_controller *ctrl)
963971
{
964-
if (ctrl->nand_version < 0x0600)
965-
return 1;
966-
return brcmnand_read_reg(ctrl, BRCMNAND_CORR_COUNT);
972+
if (ctrl->nand_version < 0x400)
973+
return 0;
974+
return brcmnand_read_reg(ctrl, BRCMNAND_READ_ERROR_COUNT);
967975
}
968976

969977
static void brcmnand_wr_corr_thresh(struct brcmnand_host *host, u8 val)
@@ -1462,7 +1470,7 @@ static void brcmnand_wp(struct mtd_info *mtd, int wp)
14621470
int ret;
14631471

14641472
if (old_wp != wp) {
1465-
dev_dbg(ctrl->dev, "WP %s\n", wp ? "on" : "off");
1473+
dev_dbg(ctrl->dev, "WP %s\n", str_on_off(wp));
14661474
old_wp = wp;
14671475
}
14681476

@@ -1492,7 +1500,7 @@ static void brcmnand_wp(struct mtd_info *mtd, int wp)
14921500
if (ret)
14931501
dev_err_ratelimited(&host->pdev->dev,
14941502
"nand #WP expected %s\n",
1495-
wp ? "on" : "off");
1503+
str_on_off(wp));
14961504
}
14971505
}
14981506

@@ -1869,8 +1877,8 @@ static int brcmnand_edu_trans(struct brcmnand_host *host, u64 addr, u32 *buf,
18691877
unsigned int trans = len >> FC_SHIFT;
18701878
dma_addr_t pa;
18711879

1872-
dev_dbg(ctrl->dev, "EDU %s %p:%p\n", ((edu_cmd == EDU_CMD_READ) ?
1873-
"read" : "write"), buf, oob);
1880+
dev_dbg(ctrl->dev, "EDU %s %p:%p\n",
1881+
str_read_write(edu_cmd == EDU_CMD_READ), buf, oob);
18741882

18751883
pa = dma_map_single(ctrl->dev, buf, len, dir);
18761884
if (dma_mapping_error(ctrl->dev, pa)) {
@@ -2066,15 +2074,20 @@ static int brcmnand_dma_trans(struct brcmnand_host *host, u64 addr, u32 *buf,
20662074
*/
20672075
static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
20682076
u64 addr, unsigned int trans, u32 *buf,
2069-
u8 *oob, u64 *err_addr)
2077+
u8 *oob, u64 *err_addr, unsigned int *corr)
20702078
{
20712079
struct brcmnand_host *host = nand_get_controller_data(chip);
20722080
struct brcmnand_controller *ctrl = host->ctrl;
20732081
int i, ret = 0;
2082+
unsigned int prev_corr;
2083+
2084+
if (corr)
2085+
*corr = 0;
20742086

20752087
brcmnand_clear_ecc_addr(ctrl);
20762088

20772089
for (i = 0; i < trans; i++, addr += FC_BYTES) {
2090+
prev_corr = brcmnand_corr_total(ctrl);
20782091
brcmnand_set_cmd_addr(mtd, addr);
20792092
/* SPARE_AREA_READ does not use ECC, so just use PAGE_READ */
20802093
brcmnand_send_cmd(host, CMD_PAGE_READ);
@@ -2099,13 +2112,16 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
20992112

21002113
if (*err_addr)
21012114
ret = -EBADMSG;
2102-
}
2115+
else {
2116+
*err_addr = brcmnand_get_correcc_addr(ctrl);
21032117

2104-
if (!ret) {
2105-
*err_addr = brcmnand_get_correcc_addr(ctrl);
2118+
if (*err_addr) {
2119+
ret = -EUCLEAN;
21062120

2107-
if (*err_addr)
2108-
ret = -EUCLEAN;
2121+
if (corr && (brcmnand_corr_total(ctrl) - prev_corr) > *corr)
2122+
*corr = brcmnand_corr_total(ctrl) - prev_corr;
2123+
}
2124+
}
21092125
}
21102126
}
21112127

@@ -2173,6 +2189,8 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
21732189
int err;
21742190
bool retry = true;
21752191
bool edu_err = false;
2192+
unsigned int corrected = 0; /* max corrected bits per subpage */
2193+
unsigned int prev_tot = brcmnand_corr_total(ctrl);
21762194

21772195
dev_dbg(ctrl->dev, "read %llx -> %p\n", (unsigned long long)addr, buf);
21782196

@@ -2200,9 +2218,11 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
22002218
memset(oob, 0x99, mtd->oobsize);
22012219

22022220
err = brcmnand_read_by_pio(mtd, chip, addr, trans, buf,
2203-
oob, &err_addr);
2221+
oob, &err_addr, &corrected);
22042222
}
22052223

2224+
mtd->ecc_stats.corrected += brcmnand_corr_total(ctrl) - prev_tot;
2225+
22062226
if (mtd_is_eccerr(err)) {
22072227
/*
22082228
* On controller version and 7.0, 7.1 , DMA read after a
@@ -2240,16 +2260,20 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
22402260
}
22412261

22422262
if (mtd_is_bitflip(err)) {
2243-
unsigned int corrected = brcmnand_count_corrected(ctrl);
2244-
22452263
/* in case of EDU correctable error we read again using PIO */
22462264
if (edu_err)
22472265
err = brcmnand_read_by_pio(mtd, chip, addr, trans, buf,
2248-
oob, &err_addr);
2266+
oob, &err_addr, &corrected);
22492267

22502268
dev_dbg(ctrl->dev, "corrected error at 0x%llx\n",
22512269
(unsigned long long)err_addr);
2252-
mtd->ecc_stats.corrected += corrected;
2270+
/*
2271+
* if flipped bits accumulator is not supported but we detected
2272+
* a correction, increase stat by 1 to match previous behavior.
2273+
*/
2274+
if (brcmnand_corr_total(ctrl) == prev_tot)
2275+
mtd->ecc_stats.corrected++;
2276+
22532277
/* Always exceed the software-imposed threshold */
22542278
return max(mtd->bitflip_threshold, corrected);
22552279
}

drivers/mtd/nand/raw/fsmc_nand.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,8 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len,
503503

504504
dma_dev = chan->device;
505505
dma_addr = dma_map_single(dma_dev->dev, buffer, len, direction);
506+
if (dma_mapping_error(dma_dev->dev, dma_addr))
507+
return -EINVAL;
506508

507509
if (direction == DMA_TO_DEVICE) {
508510
dma_src = dma_addr;

0 commit comments

Comments
 (0)