Skip to content

Commit 94005b5

Browse files
committed
Merge: mtd: spi-nor: core: Use auto-detection only once
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/4480 # Merge Request Required Information ## Summary of Changes When using the SPI driver, a spi-nor probing error -ENOENT is shown in dmesg. This commit makes it so that instead of returning -ENOENT when spi_nor_read_id results in NULL, we return NULL instead (the result of the function call to spi_nor_read_id) Tested on TIJ784 board with SPI configs enabled. After applying commits, the probing error was no longer shown in dmesg. Signed-off-by: Joel Slebodnick <jslebodn@redhat.com> ## Approved Development Ticket All submissions to CentOS Stream must reference an approved ticket in [Red Hat Jira](https://issues.redhat.com/). Please follow the CentOS Stream [contribution documentation](https://docs.centos.org/en-US/stream-contrib/quickstart/) for how to file this ticket and have it approved. JIRA: https://issues.redhat.com/browse/RHEL-40636 Approved-by: Radu Rendec <rrendec@redhat.com> Approved-by: Shawn Doherty <sdoherty@redhat.com> Approved-by: Eric Chanudet <echanude@redhat.com> Approved-by: Andrew Halaney <ahalaney@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Rado Vrbovsky <rvrbovsk@redhat.com>
2 parents 2f5ac66 + 79a064c commit 94005b5

File tree

2 files changed

+66
-41
lines changed

2 files changed

+66
-41
lines changed

drivers/mtd/spi-nor/core.c

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,37 @@ int spi_nor_write_disable(struct spi_nor *nor)
369369
return ret;
370370
}
371371

372+
/**
373+
* spi_nor_read_id() - Read the JEDEC ID.
374+
* @nor: pointer to 'struct spi_nor'.
375+
* @naddr: number of address bytes to send. Can be zero if the operation
376+
* does not need to send an address.
377+
* @ndummy: number of dummy bytes to send after an opcode or address. Can
378+
* be zero if the operation does not require dummy bytes.
379+
* @id: pointer to a DMA-able buffer where the value of the JEDEC ID
380+
* will be written.
381+
* @proto: the SPI protocol for register operation.
382+
*
383+
* Return: 0 on success, -errno otherwise.
384+
*/
385+
int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
386+
enum spi_nor_protocol proto)
387+
{
388+
int ret;
389+
390+
if (nor->spimem) {
391+
struct spi_mem_op op =
392+
SPI_NOR_READID_OP(naddr, ndummy, id, SPI_NOR_MAX_ID_LEN);
393+
394+
spi_nor_spimem_setup_op(nor, &op, proto);
395+
ret = spi_mem_exec_op(nor->spimem, &op);
396+
} else {
397+
ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
398+
SPI_NOR_MAX_ID_LEN);
399+
}
400+
return ret;
401+
}
402+
372403
/**
373404
* spi_nor_read_sr() - Read the Status Register.
374405
* @nor: pointer to 'struct spi_nor'.
@@ -1848,58 +1879,45 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
18481879
&spi_nor_xmc,
18491880
};
18501881

1851-
static const struct flash_info *
1852-
spi_nor_search_part_by_id(const struct flash_info *parts, unsigned int nparts,
1853-
const u8 *id)
1882+
static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
1883+
const u8 *id)
18541884
{
1855-
unsigned int i;
1885+
const struct flash_info *part;
1886+
unsigned int i, j;
18561887

1857-
for (i = 0; i < nparts; i++) {
1858-
if (parts[i].id_len &&
1859-
!memcmp(parts[i].id, id, parts[i].id_len))
1860-
return &parts[i];
1888+
for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
1889+
for (j = 0; j < manufacturers[i]->nparts; j++) {
1890+
part = &manufacturers[i]->parts[j];
1891+
if (part->id_len &&
1892+
!memcmp(part->id, id, part->id_len)) {
1893+
nor->manufacturer = manufacturers[i];
1894+
return part;
1895+
}
1896+
}
18611897
}
18621898

18631899
return NULL;
18641900
}
18651901

1866-
static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
1902+
static const struct flash_info *spi_nor_detect(struct spi_nor *nor)
18671903
{
18681904
const struct flash_info *info;
18691905
u8 *id = nor->bouncebuf;
1870-
unsigned int i;
18711906
int ret;
18721907

1873-
if (nor->spimem) {
1874-
struct spi_mem_op op =
1875-
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
1876-
SPI_MEM_OP_NO_ADDR,
1877-
SPI_MEM_OP_NO_DUMMY,
1878-
SPI_MEM_OP_DATA_IN(SPI_NOR_MAX_ID_LEN, id, 1));
1879-
1880-
ret = spi_mem_exec_op(nor->spimem, &op);
1881-
} else {
1882-
ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
1883-
SPI_NOR_MAX_ID_LEN);
1884-
}
1908+
ret = spi_nor_read_id(nor, 0, 0, id, nor->reg_proto);
18851909
if (ret) {
18861910
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", ret);
18871911
return ERR_PTR(ret);
18881912
}
18891913

1890-
for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
1891-
info = spi_nor_search_part_by_id(manufacturers[i]->parts,
1892-
manufacturers[i]->nparts,
1893-
id);
1894-
if (info) {
1895-
nor->manufacturer = manufacturers[i];
1896-
return info;
1897-
}
1914+
info = spi_nor_match_id(nor, id);
1915+
if (!info) {
1916+
dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
1917+
SPI_NOR_MAX_ID_LEN, id);
1918+
return ERR_PTR(-ENODEV);
18981919
}
1899-
1900-
dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
1901-
SPI_NOR_MAX_ID_LEN, id);
1902-
return ERR_PTR(-ENODEV);
1920+
return info;
19031921
}
19041922

19051923
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -2961,8 +2979,8 @@ void spi_nor_restore(struct spi_nor *nor)
29612979
}
29622980
EXPORT_SYMBOL_GPL(spi_nor_restore);
29632981

2964-
static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
2965-
const char *name)
2982+
static const struct flash_info *spi_nor_match_name(struct spi_nor *nor,
2983+
const char *name)
29662984
{
29672985
unsigned int i, j;
29682986

@@ -3037,12 +3055,10 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
30373055
const struct flash_info *info = NULL;
30383056

30393057
if (name)
3040-
info = spi_nor_match_id(nor, name);
3058+
info = spi_nor_match_name(nor, name);
30413059
/* Try to auto-detect if chip name wasn't specified or not found */
30423060
if (!info)
3043-
info = spi_nor_read_id(nor);
3044-
if (IS_ERR_OR_NULL(info))
3045-
return ERR_PTR(-ENOENT);
3061+
return spi_nor_detect(nor);
30463062

30473063
/*
30483064
* If caller has specified name of flash model that can normally be
@@ -3051,7 +3067,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
30513067
if (name && info->id_len) {
30523068
const struct flash_info *jinfo;
30533069

3054-
jinfo = spi_nor_read_id(nor);
3070+
jinfo = spi_nor_detect(nor);
30553071
if (IS_ERR(jinfo)) {
30563072
return jinfo;
30573073
} else if (jinfo != info) {

drivers/mtd/spi-nor/core.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
#define SPI_NOR_MAX_ID_LEN 6
1313

14+
/* Standard SPI NOR flash operations. */
15+
#define SPI_NOR_READID_OP(naddr, ndummy, buf, len) \
16+
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 0), \
17+
SPI_MEM_OP_ADDR(naddr, 0, 0), \
18+
SPI_MEM_OP_DUMMY(ndummy, 0), \
19+
SPI_MEM_OP_DATA_IN(len, buf, 0))
20+
1421
enum spi_nor_option_flags {
1522
SNOR_F_USE_FSR = BIT(0),
1623
SNOR_F_HAS_SR_TB = BIT(1),
@@ -506,6 +513,8 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor);
506513
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
507514
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
508515
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
516+
int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
517+
enum spi_nor_protocol reg_proto);
509518
int spi_nor_read_sr(struct spi_nor *nor, u8 *sr);
510519
int spi_nor_read_cr(struct spi_nor *nor, u8 *cr);
511520
int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len);

0 commit comments

Comments
 (0)