Skip to content

Commit 35b6bcc

Browse files
committed
mtd: rawnand: Allocate the interface configurations dynamically
Instead of manipulating the statically allocated structure and copy timings around, allocate one at identification time and save it in the nand_chip structure once it has been initialized. All NAND chips using the same interface configuration during reset and startup, we define a helper to retrieve a single reset interface configuration object, shared across all NAND chips. We use a second pointer to always have a reference on the currently applied interface configuration, which may either point to the "best interface configuration" or to the "default reset interface configuration". Signed-off-by: Miquel Raynal <[email protected]> Reviewed-by: Boris Brezillon <[email protected]> Link: https://lore.kernel.org/linux-mtd/[email protected]
1 parent a69ad11 commit 35b6bcc

File tree

4 files changed

+67
-35
lines changed

4 files changed

+67
-35
lines changed

drivers/mtd/nand/raw/internals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings);
9393
int nand_choose_best_sdr_timings(struct nand_chip *chip,
9494
struct nand_interface_config *iface,
9595
struct nand_sdr_timings *spec_timings);
96+
const struct nand_interface_config *nand_get_reset_interface_config(void);
9697
int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
9798
int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
9899
int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf,

drivers/mtd/nand/raw/nand_base.c

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -928,9 +928,9 @@ static int nand_reset_interface(struct nand_chip *chip, int chipnr)
928928
* timings to timing mode 0.
929929
*/
930930

931-
onfi_fill_interface_config(chip, &chip->interface_config,
932-
NAND_SDR_IFACE, 0);
933-
ret = ops->setup_interface(chip, chipnr, &chip->interface_config);
931+
chip->current_interface_config = nand_get_reset_interface_config();
932+
ret = ops->setup_interface(chip, chipnr,
933+
chip->current_interface_config);
934934
if (ret)
935935
pr_err("Failed to configure data interface to SDR timing mode 0\n");
936936

@@ -949,13 +949,25 @@ static int nand_reset_interface(struct nand_chip *chip, int chipnr)
949949
*/
950950
static int nand_setup_interface(struct nand_chip *chip, int chipnr)
951951
{
952-
u8 mode = chip->interface_config.timings.mode;
953-
u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { mode, };
952+
const struct nand_controller_ops *ops = chip->controller->ops;
953+
u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { };
954954
int ret;
955955

956956
if (!nand_controller_can_setup_interface(chip))
957957
return 0;
958958

959+
/*
960+
* A nand_reset_interface() put both the NAND chip and the NAND
961+
* controller in timings mode 0. If the default mode for this chip is
962+
* also 0, no need to proceed to the change again. Plus, at probe time,
963+
* nand_setup_interface() uses ->set/get_features() which would
964+
* fail anyway as the parameter page is not available yet.
965+
*/
966+
if (!chip->best_interface_config)
967+
return 0;
968+
969+
tmode_param[0] = chip->best_interface_config->timings.mode;
970+
959971
/* Change the mode on the chip side (if supported by the NAND chip) */
960972
if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) {
961973
nand_select_target(chip, chipnr);
@@ -967,14 +979,13 @@ static int nand_setup_interface(struct nand_chip *chip, int chipnr)
967979
}
968980

969981
/* Change the mode on the controller side */
970-
ret = chip->controller->ops->setup_interface(chip, chipnr,
971-
&chip->interface_config);
982+
ret = ops->setup_interface(chip, chipnr, chip->best_interface_config);
972983
if (ret)
973984
return ret;
974985

975986
/* Check the mode has been accepted by the chip, if supported */
976987
if (!nand_supports_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE))
977-
return 0;
988+
goto update_interface_config;
978989

979990
memset(tmode_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
980991
nand_select_target(chip, chipnr);
@@ -984,12 +995,15 @@ static int nand_setup_interface(struct nand_chip *chip, int chipnr)
984995
if (ret)
985996
goto err_reset_chip;
986997

987-
if (tmode_param[0] != mode) {
998+
if (tmode_param[0] != chip->best_interface_config->timings.mode) {
988999
pr_warn("timing mode %d not acknowledged by the NAND chip\n",
989-
mode);
1000+
chip->best_interface_config->timings.mode);
9901001
goto err_reset_chip;
9911002
}
9921003

1004+
update_interface_config:
1005+
chip->current_interface_config = chip->best_interface_config;
1006+
9931007
return 0;
9941008

9951009
err_reset_chip:
@@ -1031,8 +1045,10 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip,
10311045
/* Verify the controller supports the requested interface */
10321046
ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY,
10331047
iface);
1034-
if (!ret)
1048+
if (!ret) {
1049+
chip->best_interface_config = iface;
10351050
return ret;
1051+
}
10361052

10371053
/* Fallback to slower modes */
10381054
best_mode = iface->timings.mode;
@@ -1046,9 +1062,11 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip,
10461062
ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY,
10471063
iface);
10481064
if (!ret)
1049-
return 0;
1065+
break;
10501066
}
10511067

1068+
chip->best_interface_config = iface;
1069+
10521070
return 0;
10531071
}
10541072

@@ -1067,15 +1085,25 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip,
10671085
*/
10681086
static int nand_choose_interface_config(struct nand_chip *chip)
10691087
{
1088+
struct nand_interface_config *iface;
1089+
int ret;
1090+
10701091
if (!nand_controller_can_setup_interface(chip))
10711092
return 0;
10721093

1094+
iface = kzalloc(sizeof(*iface), GFP_KERNEL);
1095+
if (!iface)
1096+
return -ENOMEM;
1097+
10731098
if (chip->ops.choose_interface_config)
1074-
return chip->ops.choose_interface_config(chip,
1075-
&chip->interface_config);
1099+
ret = chip->ops.choose_interface_config(chip, iface);
1100+
else
1101+
ret = nand_choose_best_sdr_timings(chip, iface, NULL);
10761102

1077-
return nand_choose_best_sdr_timings(chip, &chip->interface_config,
1078-
NULL);
1103+
if (ret)
1104+
kfree(iface);
1105+
1106+
return ret;
10791107
}
10801108

10811109
/**
@@ -2501,7 +2529,6 @@ EXPORT_SYMBOL_GPL(nand_subop_get_data_len);
25012529
*/
25022530
int nand_reset(struct nand_chip *chip, int chipnr)
25032531
{
2504-
struct nand_interface_config saved_intf_config = chip->interface_config;
25052532
int ret;
25062533

25072534
ret = nand_reset_interface(chip, chipnr);
@@ -2519,18 +2546,6 @@ int nand_reset(struct nand_chip *chip, int chipnr)
25192546
if (ret)
25202547
return ret;
25212548

2522-
/*
2523-
* A nand_reset_interface() put both the NAND chip and the NAND
2524-
* controller in timings mode 0. If the default mode for this chip is
2525-
* also 0, no need to proceed to the change again. Plus, at probe time,
2526-
* nand_setup_interface() uses ->set/get_features() which would
2527-
* fail anyway as the parameter page is not available yet.
2528-
*/
2529-
if (!memcmp(&chip->interface_config, &saved_intf_config,
2530-
sizeof(saved_intf_config)))
2531-
return 0;
2532-
2533-
chip->interface_config = saved_intf_config;
25342549
ret = nand_setup_interface(chip, chipnr);
25352550
if (ret)
25362551
return ret;
@@ -5198,7 +5213,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
51985213
mutex_init(&chip->lock);
51995214

52005215
/* Enforce the right timings for reset/detection */
5201-
onfi_fill_interface_config(chip, &chip->interface_config, NAND_SDR_IFACE, 0);
5216+
chip->current_interface_config = nand_get_reset_interface_config();
52025217

52035218
ret = nand_dt_init(chip);
52045219
if (ret)
@@ -5994,7 +6009,7 @@ static int nand_scan_tail(struct nand_chip *chip)
59946009
for (i = 0; i < nanddev_ntargets(&chip->base); i++) {
59956010
ret = nand_setup_interface(chip, i);
59966011
if (ret)
5997-
goto err_nanddev_cleanup;
6012+
goto err_free_interface_config;
59986013
}
59996014

60006015
/* Check, if we should skip the bad block table scan */
@@ -6004,10 +6019,12 @@ static int nand_scan_tail(struct nand_chip *chip)
60046019
/* Build bad block table */
60056020
ret = nand_create_bbt(chip);
60066021
if (ret)
6007-
goto err_nanddev_cleanup;
6022+
goto err_free_interface_config;
60086023

60096024
return 0;
60106025

6026+
err_free_interface_config:
6027+
kfree(chip->best_interface_config);
60116028

60126029
err_nanddev_cleanup:
60136030
nanddev_cleanup(&chip->base);
@@ -6101,6 +6118,9 @@ void nand_cleanup(struct nand_chip *chip)
61016118
& NAND_BBT_DYNAMICSTRUCT)
61026119
kfree(chip->badblock_pattern);
61036120

6121+
/* Free the data interface */
6122+
kfree(chip->best_interface_config);
6123+
61046124
/* Free manufacturer priv data. */
61056125
nand_manufacturer_cleanup(chip);
61066126

drivers/mtd/nand/raw/nand_timings.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ static const struct nand_interface_config onfi_sdr_timings[] = {
292292
},
293293
};
294294

295+
/* All NAND chips share the same reset data interface: SDR mode 0 */
296+
const struct nand_interface_config *nand_get_reset_interface_config(void)
297+
{
298+
return &onfi_sdr_timings[0];
299+
}
300+
295301
/**
296302
* onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a
297303
* set of timings

include/linux/mtd/rawnand.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,11 @@ struct nand_manufacturer {
10691069
* @options: Various chip options. They can partly be set to inform nand_scan
10701070
* about special functionality. See the defines for further
10711071
* explanation.
1072-
* @interface_config: NAND interface timing information
1072+
* @current_interface_config: The currently used NAND interface configuration
1073+
* @best_interface_config: The best NAND interface configuration which fits both
1074+
* the NAND chip and NAND controller constraints. If
1075+
* unset, the default reset interface configuration must
1076+
* be used.
10731077
* @bbt_erase_shift: Number of address bits in a bbt entry
10741078
* @bbt_options: Bad block table specific options. All options used here must
10751079
* come from bbm.h. By default, these options will be copied to
@@ -1116,7 +1120,8 @@ struct nand_chip {
11161120
unsigned int options;
11171121

11181122
/* Data interface */
1119-
struct nand_interface_config interface_config;
1123+
const struct nand_interface_config *current_interface_config;
1124+
struct nand_interface_config *best_interface_config;
11201125

11211126
/* Bad block information */
11221127
unsigned int bbt_erase_shift;
@@ -1209,7 +1214,7 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
12091214
static inline const struct nand_interface_config *
12101215
nand_get_interface_config(struct nand_chip *chip)
12111216
{
1212-
return &chip->interface_config;
1217+
return chip->current_interface_config;
12131218
}
12141219

12151220
/*

0 commit comments

Comments
 (0)