Skip to content

Commit 3dd8aa0

Browse files
committed
Merge tag 'spi-nor/for-6.17' into mtd/next
SPI NOR changes for 6.17 Notable changes: - Fix 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. - Fix unlocking of flashes that are write-protected at power-on. This was caused by using an uninitialized mtd_info in spi_nor_try_unlock_all(). Signed-off-by: Miquel Raynal <[email protected]>
2 parents 56eb7c1 + 2e3a747 commit 3dd8aa0

File tree

4 files changed

+46
-18
lines changed

4 files changed

+46
-18
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)|\

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor,
189189
return 0;
190190
}
191191

192-
static struct spi_nor_fixups mt25qu512a_fixups = {
192+
static const struct spi_nor_fixups mt25qu512a_fixups = {
193193
.post_bfpt = mt25qu512a_post_bfpt_fixup,
194194
};
195195

@@ -225,15 +225,15 @@ static int st_nor_two_die_late_init(struct spi_nor *nor)
225225
return spi_nor_set_4byte_addr_mode(nor, true);
226226
}
227227

228-
static struct spi_nor_fixups n25q00_fixups = {
228+
static const struct spi_nor_fixups n25q00_fixups = {
229229
.late_init = st_nor_four_die_late_init,
230230
};
231231

232-
static struct spi_nor_fixups mt25q01_fixups = {
232+
static const struct spi_nor_fixups mt25q01_fixups = {
233233
.late_init = st_nor_two_die_late_init,
234234
};
235235

236-
static struct spi_nor_fixups mt25q02_fixups = {
236+
static const struct spi_nor_fixups mt25q02_fixups = {
237237
.late_init = st_nor_four_die_late_init,
238238
};
239239

drivers/mtd/spi-nor/spansion.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
1919
#define SPINOR_OP_CLPEF 0x82 /* Clear program/erase failure flags */
20+
#define SPINOR_OP_CYPRESS_EX4B 0xB8 /* Exit 4-byte address mode */
2021
#define SPINOR_OP_CYPRESS_DIE_ERASE 0x61 /* Chip (die) erase */
2122
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
2223
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
@@ -58,6 +59,13 @@
5859
SPI_MEM_OP_DUMMY(ndummy, 0), \
5960
SPI_MEM_OP_DATA_IN(1, buf, 0))
6061

62+
#define CYPRESS_NOR_EN4B_EX4B_OP(enable) \
63+
SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : \
64+
SPINOR_OP_CYPRESS_EX4B, 0), \
65+
SPI_MEM_OP_NO_ADDR, \
66+
SPI_MEM_OP_NO_DUMMY, \
67+
SPI_MEM_OP_NO_DATA)
68+
6169
#define SPANSION_OP(opcode) \
6270
SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \
6371
SPI_MEM_OP_NO_ADDR, \
@@ -356,6 +364,20 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
356364
return 0;
357365
}
358366

367+
static int cypress_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
368+
{
369+
int ret;
370+
struct spi_mem_op op = CYPRESS_NOR_EN4B_EX4B_OP(enable);
371+
372+
spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
373+
374+
ret = spi_mem_exec_op(nor->spimem, &op);
375+
if (ret)
376+
dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret);
377+
378+
return ret;
379+
}
380+
359381
/**
360382
* cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode
361383
* (3 or 4-byte) by querying status
@@ -526,6 +548,9 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
526548
struct spi_mem_op op;
527549
int ret;
528550

551+
/* Assign 4-byte address mode method that is not determined in BFPT */
552+
nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
553+
529554
ret = cypress_nor_set_addr_mode_nbytes(nor);
530555
if (ret)
531556
return ret;
@@ -578,7 +603,7 @@ static int s25fs256t_late_init(struct spi_nor *nor)
578603
return 0;
579604
}
580605

581-
static struct spi_nor_fixups s25fs256t_fixups = {
606+
static const struct spi_nor_fixups s25fs256t_fixups = {
582607
.post_bfpt = s25fs256t_post_bfpt_fixup,
583608
.post_sfdp = s25fs256t_post_sfdp_fixup,
584609
.late_init = s25fs256t_late_init,
@@ -591,6 +616,9 @@ s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
591616
{
592617
int ret;
593618

619+
/* Assign 4-byte address mode method that is not determined in BFPT */
620+
nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
621+
594622
ret = cypress_nor_set_addr_mode_nbytes(nor);
595623
if (ret)
596624
return ret;
@@ -650,7 +678,7 @@ static int s25hx_t_late_init(struct spi_nor *nor)
650678
return 0;
651679
}
652680

653-
static struct spi_nor_fixups s25hx_t_fixups = {
681+
static const struct spi_nor_fixups s25hx_t_fixups = {
654682
.post_bfpt = s25hx_t_post_bfpt_fixup,
655683
.post_sfdp = s25hx_t_post_sfdp_fixup,
656684
.late_init = s25hx_t_late_init,
@@ -718,6 +746,9 @@ static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
718746
const struct sfdp_parameter_header *bfpt_header,
719747
const struct sfdp_bfpt *bfpt)
720748
{
749+
/* Assign 4-byte address mode method that is not determined in BFPT */
750+
nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
751+
721752
return cypress_nor_set_addr_mode_nbytes(nor);
722753
}
723754

drivers/mtd/spi-nor/swp.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
5656
static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
5757
u64 *len)
5858
{
59-
struct mtd_info *mtd = &nor->mtd;
6059
u64 min_prot_len;
6160
u8 mask = spi_nor_get_sr_bp_mask(nor);
6261
u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
@@ -77,13 +76,13 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
7776
min_prot_len = spi_nor_get_min_prot_length_sr(nor);
7877
*len = min_prot_len << (bp - 1);
7978

80-
if (*len > mtd->size)
81-
*len = mtd->size;
79+
if (*len > nor->params->size)
80+
*len = nor->params->size;
8281

8382
if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
8483
*ofs = 0;
8584
else
86-
*ofs = mtd->size - *len;
85+
*ofs = nor->params->size - *len;
8786
}
8887

8988
/*
@@ -158,7 +157,6 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 len,
158157
*/
159158
static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
160159
{
161-
struct mtd_info *mtd = &nor->mtd;
162160
u64 min_prot_len;
163161
int ret, status_old, status_new;
164162
u8 mask = spi_nor_get_sr_bp_mask(nor);
@@ -183,7 +181,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
183181
can_be_bottom = false;
184182

185183
/* If anything above us is unlocked, we can't use 'top' protection */
186-
if (!spi_nor_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len),
184+
if (!spi_nor_is_locked_sr(nor, ofs + len, nor->params->size - (ofs + len),
187185
status_old))
188186
can_be_top = false;
189187

@@ -195,11 +193,11 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
195193

196194
/* lock_len: length of region that should end up locked */
197195
if (use_top)
198-
lock_len = mtd->size - ofs;
196+
lock_len = nor->params->size - ofs;
199197
else
200198
lock_len = ofs + len;
201199

202-
if (lock_len == mtd->size) {
200+
if (lock_len == nor->params->size) {
203201
val = mask;
204202
} else {
205203
min_prot_len = spi_nor_get_min_prot_length_sr(nor);
@@ -248,7 +246,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
248246
*/
249247
static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
250248
{
251-
struct mtd_info *mtd = &nor->mtd;
252249
u64 min_prot_len;
253250
int ret, status_old, status_new;
254251
u8 mask = spi_nor_get_sr_bp_mask(nor);
@@ -273,7 +270,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
273270
can_be_top = false;
274271

275272
/* If anything above us is locked, we can't use 'bottom' protection */
276-
if (!spi_nor_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len),
273+
if (!spi_nor_is_unlocked_sr(nor, ofs + len, nor->params->size - (ofs + len),
277274
status_old))
278275
can_be_bottom = false;
279276

@@ -285,7 +282,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
285282

286283
/* lock_len: length of region that should remain locked */
287284
if (use_top)
288-
lock_len = mtd->size - (ofs + len);
285+
lock_len = nor->params->size - (ofs + len);
289286
else
290287
lock_len = ofs;
291288

0 commit comments

Comments
 (0)