aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/raw/nand_base.c26
-rw-r--r--drivers/mtd/nand/raw/nand_micron.c4
2 files changed, 23 insertions, 7 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 789c11e0925e..0bd9f22973e9 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -1160,9 +1160,16 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
return status;
}
-static bool nand_supports_set_get_features(struct nand_chip *chip)
+static bool nand_supports_get_features(struct nand_chip *chip, int addr)
{
- return chip->parameters.supports_set_get_features;
+ return (chip->parameters.supports_set_get_features &&
+ test_bit(addr, chip->parameters.get_feature_list));
+}
+
+static bool nand_supports_set_features(struct nand_chip *chip, int addr)
+{
+ return (chip->parameters.supports_set_get_features &&
+ test_bit(addr, chip->parameters.set_feature_list));
}
/**
@@ -1179,7 +1186,7 @@ int nand_get_features(struct nand_chip *chip, int addr,
{
struct mtd_info *mtd = nand_to_mtd(chip);
- if (!nand_supports_set_get_features(chip))
+ if (!nand_supports_get_features(chip, addr))
return -ENOTSUPP;
return chip->get_features(mtd, chip, addr, subfeature_param);
@@ -1200,7 +1207,7 @@ int nand_set_features(struct nand_chip *chip, int addr,
{
struct mtd_info *mtd = nand_to_mtd(chip);
- if (!nand_supports_set_get_features(chip))
+ if (!nand_supports_set_features(chip, addr))
return -ENOTSUPP;
return chip->set_features(mtd, chip, addr, subfeature_param);
@@ -1271,7 +1278,7 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
return 0;
/* Change the mode on the chip side (if supported by the NAND chip) */
- if (nand_supports_set_get_features(chip)) {
+ if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) {
chip->select_chip(mtd, chipnr);
ret = nand_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE,
tmode_param);
@@ -1286,7 +1293,7 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
return ret;
/* Check the mode has been accepted by the chip, if supported */
- if (!nand_supports_set_get_features(chip))
+ if (!nand_supports_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE))
return 0;
memset(tmode_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
@@ -5192,8 +5199,13 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
}
/* Save some parameters from the parameter page for future use */
- if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES)
+ if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES) {
chip->parameters.supports_set_get_features = true;
+ bitmap_set(chip->parameters.get_feature_list,
+ ONFI_FEATURE_ADDR_TIMING_MODE, 1);
+ bitmap_set(chip->parameters.set_feature_list,
+ ONFI_FEATURE_ADDR_TIMING_MODE, 1);
+ }
chip->parameters.onfi.tPROG = le16_to_cpu(p->t_prog);
chip->parameters.onfi.tBERS = le16_to_cpu(p->t_bers);
chip->parameters.onfi.tR = le16_to_cpu(p->t_r);
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index c5974d8313e7..0af45b134c0c 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -64,6 +64,10 @@ static int micron_nand_onfi_init(struct nand_chip *chip)
chip->setup_read_retry = micron_nand_setup_read_retry;
}
+ if (p->supports_set_get_features) {
+ set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->set_feature_list);
+ set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->get_feature_list);
+ }
return 0;
}