Skip to content

Commit f7091fb

Browse files
committed
Merge tag 'spi-nor/for-6.6' into mtd/next
SPI NOR core changes: * fix assumption on enabling quad mode in spi_nor_write_16bit_sr_and_check() * avoid setting SRWD bit in SR if WP# signal not connected as it will configure the SR permanently as read only. Add "no-wp" dt property. * clarify the need for spi-nor compatibles in dt-bindings SPI NOR manufacturer drivers changes: * spansion: - add support for S28HS02GT - switch methods to use vreg_offset from SFDP instead of hardcoding the register value * microchip/sst: - add support for sst26vf032b flash * winbond: - correct flags for Winbond w25q128 Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2 parents a417ab3 + 69d50d0 commit f7091fb

File tree

14 files changed

+312
-185
lines changed

14 files changed

+312
-185
lines changed

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ properties:
4343
- const: jedec,spi-nor
4444
- const: jedec,spi-nor
4545
description:
46-
Must also include "jedec,spi-nor" for any SPI NOR flash that can be
47-
identified by the JEDEC READ ID opcode (0x9F).
46+
SPI NOR flashes compatible with the JEDEC SFDP standard or which may be
47+
identified with the READ ID opcode (0x9F) do not deserve a specific
48+
compatible. They should instead only be matched against the generic
49+
"jedec,spi-nor" compatible.
4850

4951
reg:
5052
minItems: 1
@@ -70,6 +72,21 @@ properties:
7072
be used on such systems, to denote the absence of a reliable reset
7173
mechanism.
7274

75+
no-wp:
76+
type: boolean
77+
description:
78+
The status register write disable (SRWD) bit in status register, combined
79+
with the WP# signal, provides hardware data protection for the device. When
80+
the SRWD bit is set to 1, and the WP# signal is either driven LOW or hard
81+
strapped to LOW, the status register nonvolatile bits become read-only and
82+
the WRITE STATUS REGISTER operation will not execute. The only way to exit
83+
this hardware-protected mode is to drive WP# HIGH. If the WP# signal of the
84+
flash device is not connected or is wrongly tied to GND (that includes internal
85+
pull-downs) then status register permanently becomes read-only as the SRWD bit
86+
cannot be reset. This boolean flag can be used on such systems to avoid setting
87+
the SRWD bit while writing the status register. WP# signal hard strapped to GND
88+
can be a valid use case.
89+
7390
reset-gpios:
7491
description:
7592
A GPIO line connected to the RESET (active low) signal of the device.

drivers/mtd/spi-nor/atmel.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ static const struct spi_nor_locking_ops at25fs_nor_locking_ops = {
4848
.is_locked = at25fs_nor_is_locked,
4949
};
5050

51-
static void at25fs_nor_late_init(struct spi_nor *nor)
51+
static int at25fs_nor_late_init(struct spi_nor *nor)
5252
{
5353
nor->params->locking_ops = &at25fs_nor_locking_ops;
54+
55+
return 0;
5456
}
5557

5658
static const struct spi_nor_fixups at25fs_nor_fixups = {
@@ -149,9 +151,11 @@ static const struct spi_nor_locking_ops atmel_nor_global_protection_ops = {
149151
.is_locked = atmel_nor_is_global_protected,
150152
};
151153

152-
static void atmel_nor_global_protection_late_init(struct spi_nor *nor)
154+
static int atmel_nor_global_protection_late_init(struct spi_nor *nor)
153155
{
154156
nor->params->locking_ops = &atmel_nor_global_protection_ops;
157+
158+
return 0;
155159
}
156160

157161
static const struct spi_nor_fixups atmel_nor_global_protection_fixups = {

drivers/mtd/spi-nor/controllers/nxp-spifi.c

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -394,30 +394,18 @@ static int nxp_spifi_probe(struct platform_device *pdev)
394394
if (IS_ERR(spifi->flash_base))
395395
return PTR_ERR(spifi->flash_base);
396396

397-
spifi->clk_spifi = devm_clk_get(&pdev->dev, "spifi");
397+
spifi->clk_spifi = devm_clk_get_enabled(&pdev->dev, "spifi");
398398
if (IS_ERR(spifi->clk_spifi)) {
399-
dev_err(&pdev->dev, "spifi clock not found\n");
399+
dev_err(&pdev->dev, "spifi clock not found or unable to enable\n");
400400
return PTR_ERR(spifi->clk_spifi);
401401
}
402402

403-
spifi->clk_reg = devm_clk_get(&pdev->dev, "reg");
403+
spifi->clk_reg = devm_clk_get_enabled(&pdev->dev, "reg");
404404
if (IS_ERR(spifi->clk_reg)) {
405-
dev_err(&pdev->dev, "reg clock not found\n");
405+
dev_err(&pdev->dev, "reg clock not found or unable to enable\n");
406406
return PTR_ERR(spifi->clk_reg);
407407
}
408408

409-
ret = clk_prepare_enable(spifi->clk_reg);
410-
if (ret) {
411-
dev_err(&pdev->dev, "unable to enable reg clock\n");
412-
return ret;
413-
}
414-
415-
ret = clk_prepare_enable(spifi->clk_spifi);
416-
if (ret) {
417-
dev_err(&pdev->dev, "unable to enable spifi clock\n");
418-
goto dis_clk_reg;
419-
}
420-
421409
spifi->dev = &pdev->dev;
422410
platform_set_drvdata(pdev, spifi);
423411

@@ -430,33 +418,24 @@ static int nxp_spifi_probe(struct platform_device *pdev)
430418
flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
431419
if (!flash_np) {
432420
dev_err(&pdev->dev, "no SPI flash device to configure\n");
433-
ret = -ENODEV;
434-
goto dis_clks;
421+
return -ENODEV;
435422
}
436423

437424
ret = nxp_spifi_setup_flash(spifi, flash_np);
438425
of_node_put(flash_np);
439426
if (ret) {
440427
dev_err(&pdev->dev, "unable to setup flash chip\n");
441-
goto dis_clks;
428+
return ret;
442429
}
443430

444431
return 0;
445-
446-
dis_clks:
447-
clk_disable_unprepare(spifi->clk_spifi);
448-
dis_clk_reg:
449-
clk_disable_unprepare(spifi->clk_reg);
450-
return ret;
451432
}
452433

453434
static int nxp_spifi_remove(struct platform_device *pdev)
454435
{
455436
struct nxp_spifi *spifi = platform_get_drvdata(pdev);
456437

457438
mtd_device_unregister(&spifi->nor.mtd);
458-
clk_disable_unprepare(spifi->clk_spifi);
459-
clk_disable_unprepare(spifi->clk_reg);
460439

461440
return 0;
462441
}

drivers/mtd/spi-nor/core.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -870,21 +870,22 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
870870
ret = spi_nor_read_cr(nor, &sr_cr[1]);
871871
if (ret)
872872
return ret;
873-
} else if (nor->params->quad_enable) {
873+
} else if (spi_nor_get_protocol_width(nor->read_proto) == 4 &&
874+
spi_nor_get_protocol_width(nor->write_proto) == 4 &&
875+
nor->params->quad_enable) {
874876
/*
875877
* If the Status Register 2 Read command (35h) is not
876878
* supported, we should at least be sure we don't
877879
* change the value of the SR2 Quad Enable bit.
878880
*
879-
* We can safely assume that when the Quad Enable method is
880-
* set, the value of the QE bit is one, as a consequence of the
881-
* nor->params->quad_enable() call.
881+
* When the Quad Enable method is set and the buswidth is 4, we
882+
* can safely assume that the value of the QE bit is one, as a
883+
* consequence of the nor->params->quad_enable() call.
882884
*
883-
* We can safely assume that the Quad Enable bit is present in
884-
* the Status Register 2 at BIT(1). According to the JESD216
885-
* revB standard, BFPT DWORDS[15], bits 22:20, the 16-bit
886-
* Write Status (01h) command is available just for the cases
887-
* in which the QE bit is described in SR2 at BIT(1).
885+
* According to the JESD216 revB standard, BFPT DWORDS[15],
886+
* bits 22:20, the 16-bit Write Status (01h) command is
887+
* available just for the cases in which the QE bit is
888+
* described in SR2 at BIT(1).
888889
*/
889890
sr_cr[1] = SR2_QUAD_EN_BIT1;
890891
} else {
@@ -2844,6 +2845,9 @@ static void spi_nor_init_flags(struct spi_nor *nor)
28442845
if (of_property_read_bool(np, "broken-flash-reset"))
28452846
nor->flags |= SNOR_F_BROKEN_RESET;
28462847

2848+
if (of_property_read_bool(np, "no-wp"))
2849+
nor->flags |= SNOR_F_NO_WP;
2850+
28472851
if (flags & SPI_NOR_SWP_IS_VOLATILE)
28482852
nor->flags |= SNOR_F_SWP_IS_VOLATILE;
28492853

@@ -2897,16 +2901,23 @@ static void spi_nor_init_fixup_flags(struct spi_nor *nor)
28972901
* SFDP standard, or where SFDP tables are not defined at all.
28982902
* Will replace the spi_nor_manufacturer_init_params() method.
28992903
*/
2900-
static void spi_nor_late_init_params(struct spi_nor *nor)
2904+
static int spi_nor_late_init_params(struct spi_nor *nor)
29012905
{
29022906
struct spi_nor_flash_parameter *params = nor->params;
2907+
int ret;
29032908

29042909
if (nor->manufacturer && nor->manufacturer->fixups &&
2905-
nor->manufacturer->fixups->late_init)
2906-
nor->manufacturer->fixups->late_init(nor);
2910+
nor->manufacturer->fixups->late_init) {
2911+
ret = nor->manufacturer->fixups->late_init(nor);
2912+
if (ret)
2913+
return ret;
2914+
}
29072915

2908-
if (nor->info->fixups && nor->info->fixups->late_init)
2909-
nor->info->fixups->late_init(nor);
2916+
if (nor->info->fixups && nor->info->fixups->late_init) {
2917+
ret = nor->info->fixups->late_init(nor);
2918+
if (ret)
2919+
return ret;
2920+
}
29102921

29112922
/* Default method kept for backward compatibility. */
29122923
if (!params->set_4byte_addr_mode)
@@ -2924,6 +2935,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
29242935

29252936
if (nor->info->n_banks > 1)
29262937
params->bank_size = div64_u64(params->size, nor->info->n_banks);
2938+
2939+
return 0;
29272940
}
29282941

29292942
/**
@@ -3082,22 +3095,20 @@ static int spi_nor_init_params(struct spi_nor *nor)
30823095
spi_nor_init_params_deprecated(nor);
30833096
}
30843097

3085-
spi_nor_late_init_params(nor);
3086-
3087-
return 0;
3098+
return spi_nor_late_init_params(nor);
30883099
}
30893100

3090-
/** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed
3101+
/** spi_nor_set_octal_dtr() - enable or disable Octal DTR I/O.
30913102
* @nor: pointer to a 'struct spi_nor'
30923103
* @enable: whether to enable or disable Octal DTR
30933104
*
30943105
* Return: 0 on success, -errno otherwise.
30953106
*/
3096-
static int spi_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
3107+
static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
30973108
{
30983109
int ret;
30993110

3100-
if (!nor->params->octal_dtr_enable)
3111+
if (!nor->params->set_octal_dtr)
31013112
return 0;
31023113

31033114
if (!(nor->read_proto == SNOR_PROTO_8_8_8_DTR &&
@@ -3107,7 +3118,7 @@ static int spi_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
31073118
if (!(nor->flags & SNOR_F_IO_MODE_EN_VOLATILE))
31083119
return 0;
31093120

3110-
ret = nor->params->octal_dtr_enable(nor, enable);
3121+
ret = nor->params->set_octal_dtr(nor, enable);
31113122
if (ret)
31123123
return ret;
31133124

@@ -3168,7 +3179,7 @@ static int spi_nor_init(struct spi_nor *nor)
31683179
{
31693180
int err;
31703181

3171-
err = spi_nor_octal_dtr_enable(nor, true);
3182+
err = spi_nor_set_octal_dtr(nor, true);
31723183
if (err) {
31733184
dev_dbg(nor->dev, "octal mode not supported\n");
31743185
return err;
@@ -3270,7 +3281,7 @@ static int spi_nor_suspend(struct mtd_info *mtd)
32703281
int ret;
32713282

32723283
/* Disable octal DTR mode if we enabled it. */
3273-
ret = spi_nor_octal_dtr_enable(nor, false);
3284+
ret = spi_nor_set_octal_dtr(nor, false);
32743285
if (ret)
32753286
dev_err(nor->dev, "suspend() failed\n");
32763287

drivers/mtd/spi-nor/core.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ enum spi_nor_option_flags {
132132
SNOR_F_SWP_IS_VOLATILE = BIT(13),
133133
SNOR_F_RWW = BIT(14),
134134
SNOR_F_ECC = BIT(15),
135+
SNOR_F_NO_WP = BIT(16),
135136
};
136137

137138
struct spi_nor_read_command {
@@ -363,7 +364,7 @@ struct spi_nor_otp {
363364
* @erase_map: the erase map parsed from the SFDP Sector Map Parameter
364365
* Table.
365366
* @otp: SPI NOR OTP info.
366-
* @octal_dtr_enable: enables SPI NOR octal DTR mode.
367+
* @set_octal_dtr: enables or disables SPI NOR octal DTR mode.
367368
* @quad_enable: enables SPI NOR quad mode.
368369
* @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
369370
* @convert_addr: converts an absolute address into something the flash
@@ -377,6 +378,7 @@ struct spi_nor_otp {
377378
* than reading the status register to indicate they
378379
* are ready for a new command
379380
* @locking_ops: SPI NOR locking methods.
381+
* @priv: flash's private data.
380382
*/
381383
struct spi_nor_flash_parameter {
382384
u64 bank_size;
@@ -397,14 +399,15 @@ struct spi_nor_flash_parameter {
397399
struct spi_nor_erase_map erase_map;
398400
struct spi_nor_otp otp;
399401

400-
int (*octal_dtr_enable)(struct spi_nor *nor, bool enable);
402+
int (*set_octal_dtr)(struct spi_nor *nor, bool enable);
401403
int (*quad_enable)(struct spi_nor *nor);
402404
int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);
403405
u32 (*convert_addr)(struct spi_nor *nor, u32 addr);
404406
int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps);
405407
int (*ready)(struct spi_nor *nor);
406408

407409
const struct spi_nor_locking_ops *locking_ops;
410+
void *priv;
408411
};
409412

410413
/**
@@ -431,7 +434,7 @@ struct spi_nor_fixups {
431434
const struct sfdp_parameter_header *bfpt_header,
432435
const struct sfdp_bfpt *bfpt);
433436
int (*post_sfdp)(struct spi_nor *nor);
434-
void (*late_init)(struct spi_nor *nor);
437+
int (*late_init)(struct spi_nor *nor);
435438
};
436439

437440
/**

drivers/mtd/spi-nor/debugfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static const char *const snor_f_names[] = {
2727
SNOR_F_NAME(SWP_IS_VOLATILE),
2828
SNOR_F_NAME(RWW),
2929
SNOR_F_NAME(ECC),
30+
SNOR_F_NAME(NO_WP),
3031
};
3132
#undef SNOR_F_NAME
3233

drivers/mtd/spi-nor/issi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static const struct spi_nor_fixups is25lp256_fixups = {
2929
.post_bfpt = is25lp256_post_bfpt_fixups,
3030
};
3131

32-
static void pm25lv_nor_late_init(struct spi_nor *nor)
32+
static int pm25lv_nor_late_init(struct spi_nor *nor)
3333
{
3434
struct spi_nor_erase_map *map = &nor->params->erase_map;
3535
int i;
@@ -38,6 +38,8 @@ static void pm25lv_nor_late_init(struct spi_nor *nor)
3838
for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++)
3939
if (map->erase_type[i].size == 4096)
4040
map->erase_type[i].opcode = SPINOR_OP_BE_4K_PMC;
41+
42+
return 0;
4143
}
4244

4345
static const struct spi_nor_fixups pm25lv_nor_fixups = {

drivers/mtd/spi-nor/macronix.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,12 @@ static void macronix_nor_default_init(struct spi_nor *nor)
110110
nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
111111
}
112112

113-
static void macronix_nor_late_init(struct spi_nor *nor)
113+
static int macronix_nor_late_init(struct spi_nor *nor)
114114
{
115115
if (!nor->params->set_4byte_addr_mode)
116116
nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b;
117+
118+
return 0;
117119
}
118120

119121
static const struct spi_nor_fixups macronix_nor_fixups = {

drivers/mtd/spi-nor/micron-st.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,15 @@ static int micron_st_nor_octal_dtr_dis(struct spi_nor *nor)
120120
return 0;
121121
}
122122

123-
static int micron_st_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
123+
static int micron_st_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
124124
{
125125
return enable ? micron_st_nor_octal_dtr_en(nor) :
126126
micron_st_nor_octal_dtr_dis(nor);
127127
}
128128

129129
static void mt35xu512aba_default_init(struct spi_nor *nor)
130130
{
131-
nor->params->octal_dtr_enable = micron_st_nor_octal_dtr_enable;
131+
nor->params->set_octal_dtr = micron_st_nor_set_octal_dtr;
132132
}
133133

134134
static int mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor)
@@ -429,7 +429,7 @@ static void micron_st_nor_default_init(struct spi_nor *nor)
429429
nor->params->quad_enable = NULL;
430430
}
431431

432-
static void micron_st_nor_late_init(struct spi_nor *nor)
432+
static int micron_st_nor_late_init(struct spi_nor *nor)
433433
{
434434
struct spi_nor_flash_parameter *params = nor->params;
435435

@@ -438,6 +438,8 @@ static void micron_st_nor_late_init(struct spi_nor *nor)
438438

439439
if (!params->set_4byte_addr_mode)
440440
params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_wren_en4b_ex4b;
441+
442+
return 0;
441443
}
442444

443445
static const struct spi_nor_fixups micron_st_nor_fixups = {

0 commit comments

Comments
 (0)