1 From c4172a95df8a57a66c70a8b9948b9600a01c4cb7 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Mon, 25 Jul 2022 11:32:08 +0800
4 Subject: [PATCH 49/71] mtd: spi-nor: add support to read flash unique ID
6 This patch adds support to read unique ID from spi-nor flashes.
8 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
10 drivers/mtd/spi/spi-nor-core.c | 95 ++++++++++++++++++++++++++++++++++
11 include/linux/mtd/spi-nor.h | 2 +
12 2 files changed, 97 insertions(+)
14 --- a/drivers/mtd/spi/spi-nor-core.c
15 +++ b/drivers/mtd/spi/spi-nor-core.c
16 @@ -2848,6 +2848,100 @@ static int spi_nor_init_params(struct sp
20 +static int spi_nor_read_uuid(struct spi_nor *nor)
22 + u8 read_opcode, addr_width, read_dummy;
29 + struct spi_mem_op op;
31 + read_opcode = nor->read_opcode;
32 + addr_width = nor->addr_width;
33 + read_dummy = nor->read_dummy;
35 + switch (JEDEC_MFR(nor->info)) {
36 + case SNOR_MFR_WINBOND:
38 + nor->read_opcode = 0x4b;
39 + nor->addr_width = 0;
41 + nor->read_dummy = 4;
43 + case SNOR_MFR_GIGADEVICE:
45 + nor->read_opcode = 0x4b;
46 + nor->addr_width = 3;
48 + nor->read_dummy = 1;
51 + case SNOR_MFR_MICRON:
54 + nor->read_opcode = 0x9f;
55 + nor->addr_width = 0;
57 + nor->read_dummy = 0;
61 + nor->read_opcode = 0x5a;
62 + nor->addr_width = 3;
64 + nor->read_dummy = 1;
66 + /* Automotive only in SPANSION's NOR devices */
67 + case SNOR_MFR_SPANSION:
70 + nor->read_opcode = 0x9f;
71 + nor->addr_width = 0;
73 + nor->read_dummy = 0;
76 + printf("UUID not supported on this device.\n");
80 + uuid = kmalloc((uuid_len + shift) * sizeof(*uuid), GFP_KERNEL);
85 + memset(uuid, 0x0, (uuid_len + shift) * sizeof(*uuid));
87 + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
88 + SPI_MEM_OP_ADDR(nor->addr_width, addr, 0),
89 + SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
90 + SPI_MEM_OP_DATA_IN(uuid_len+shift, NULL, 0));
92 + spi_nor_setup_op(nor, &op, nor->reg_proto);
94 + ret = spi_nor_read_write_reg(nor, &op, uuid);
96 + dev_dbg(nor->dev, "error %d reading %x\n", ret, nor->read_opcode);
100 + printf("UUID: 0x");
101 + for(i = 0; i<uuid_len; i++)
102 + printf("%02x", uuid[i+shift]);
106 + nor->read_opcode = read_opcode;
107 + nor->addr_width = addr_width;
108 + nor->read_dummy = read_dummy;
114 static int spi_nor_hwcaps2cmd(u32 hwcaps, const int table[][2], size_t size)
117 @@ -4045,6 +4139,7 @@ int spi_nor_scan(struct spi_nor *nor)
118 nor->write = spi_nor_write_data;
119 nor->read_reg = spi_nor_read_reg;
120 nor->write_reg = spi_nor_write_reg;
121 + nor->read_uuid = spi_nor_read_uuid;
123 nor->setup = spi_nor_default_setup;
125 --- a/include/linux/mtd/spi-nor.h
126 +++ b/include/linux/mtd/spi-nor.h
128 #define SNOR_MFR_SPANSION CFI_MFR_AMD
129 #define SNOR_MFR_SST CFI_MFR_SST
130 #define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */
131 +#define SNOR_MFR_EON CFI_MFR_EON
132 #define SNOR_MFR_CYPRESS 0x34
135 @@ -571,6 +572,7 @@ struct spi_nor {
136 void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
137 int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
138 int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
139 + int (*read_uuid)(struct spi_nor *nor);
141 ssize_t (*read)(struct spi_nor *nor, loff_t from,
142 size_t len, u_char *read_buf);