Skip to content

Commit 9f820fc

Browse files
committed
mtd: rawnand: Check the data only read pattern only once
Instead of checking if a pattern is supported each time we need it, let's create a bitfield that only the core would be allowed to fill at startup time. The core and the individual drivers may then use it in order to check what operation they should use. This bitfield is supposed to grow over time. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Tested-by: Liao Jaime <jaimeliao.tw@gmail.com> Link: https://lore.kernel.org/linux-mtd/20230112093637.987838-2-miquel.raynal@bootlin.com
1 parent 568494d commit 9f820fc

4 files changed

Lines changed: 30 additions & 4 deletions

File tree

drivers/mtd/nand/raw/nand_base.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4991,6 +4991,24 @@ nand_manufacturer_name(const struct nand_manufacturer_desc *manufacturer_desc)
49914991
return manufacturer_desc ? manufacturer_desc->name : "Unknown";
49924992
}
49934993

4994+
static void rawnand_check_data_only_read_support(struct nand_chip *chip)
4995+
{
4996+
/* Use an arbitrary size for the check */
4997+
if (!nand_read_data_op(chip, NULL, SZ_512, true, true))
4998+
chip->controller->supported_op.data_only_read = 1;
4999+
}
5000+
5001+
static void rawnand_early_check_supported_ops(struct nand_chip *chip)
5002+
{
5003+
/* The supported_op fields should not be set by individual drivers */
5004+
WARN_ON_ONCE(chip->controller->supported_op.data_only_read);
5005+
5006+
if (!nand_has_exec_op(chip))
5007+
return;
5008+
5009+
rawnand_check_data_only_read_support(chip);
5010+
}
5011+
49945012
/*
49955013
* Get the flash and manufacturer id and lookup if the type is supported.
49965014
*/
@@ -5023,6 +5041,8 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
50235041
/* Select the device */
50245042
nand_select_target(chip, 0);
50255043

5044+
rawnand_early_check_supported_ops(chip);
5045+
50265046
/* Send the command for reading device ID */
50275047
ret = nand_readid_op(chip, 0, id_data, 2);
50285048
if (ret)

drivers/mtd/nand/raw/nand_jedec.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ int nand_jedec_detect(struct nand_chip *chip)
4646
if (!p)
4747
return -ENOMEM;
4848

49-
if (!nand_has_exec_op(chip) ||
50-
!nand_read_data_op(chip, p, sizeof(*p), true, true))
49+
if (!nand_has_exec_op(chip) || chip->controller->supported_op.data_only_read)
5150
use_datain = true;
5251

5352
for (i = 0; i < JEDEC_PARAM_PAGES; i++) {

drivers/mtd/nand/raw/nand_onfi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@ int nand_onfi_detect(struct nand_chip *chip)
166166
if (!pbuf)
167167
return -ENOMEM;
168168

169-
if (!nand_has_exec_op(chip) ||
170-
!nand_read_data_op(chip, &pbuf[0], sizeof(*pbuf), true, true))
169+
if (!nand_has_exec_op(chip) || chip->controller->supported_op.data_only_read)
171170
use_datain = true;
172171

173172
for (i = 0; i < ONFI_PARAM_PAGES; i++) {

include/linux/mtd/rawnand.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,10 +1094,18 @@ struct nand_controller_ops {
10941094
*
10951095
* @lock: lock used to serialize accesses to the NAND controller
10961096
* @ops: NAND controller operations.
1097+
* @supported_op: NAND controller known-to-be-supported operations,
1098+
* only writable by the core after initial checking.
1099+
* @supported_op.data_only_read: The controller supports reading more data from
1100+
* the bus without restarting an entire read operation nor
1101+
* changing the column.
10971102
*/
10981103
struct nand_controller {
10991104
struct mutex lock;
11001105
const struct nand_controller_ops *ops;
1106+
struct {
1107+
unsigned int data_only_read: 1;
1108+
} supported_op;
11011109
};
11021110

11031111
static inline void nand_controller_init(struct nand_controller *nfc)

0 commit comments

Comments
 (0)