diff options
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 57 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 3 |
2 files changed, 58 insertions, 2 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index b8c74cda7625..d388c7f6fec9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -204,6 +204,51 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr) | |||
204 | } | 204 | } |
205 | 205 | ||
206 | /** | 206 | /** |
207 | * nand_write_byte - [DEFAULT] write single byte to chip | ||
208 | * @mtd: MTD device structure | ||
209 | * @byte: value to write | ||
210 | * | ||
211 | * Default function to write a byte to I/O[7:0] | ||
212 | */ | ||
213 | static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) | ||
214 | { | ||
215 | struct nand_chip *chip = mtd->priv; | ||
216 | |||
217 | chip->write_buf(mtd, &byte, 1); | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16 | ||
222 | * @mtd: MTD device structure | ||
223 | * @byte: value to write | ||
224 | * | ||
225 | * Default function to write a byte to I/O[7:0] on a 16-bit wide chip. | ||
226 | */ | ||
227 | static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) | ||
228 | { | ||
229 | struct nand_chip *chip = mtd->priv; | ||
230 | uint16_t word = byte; | ||
231 | |||
232 | /* | ||
233 | * It's not entirely clear what should happen to I/O[15:8] when writing | ||
234 | * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads: | ||
235 | * | ||
236 | * When the host supports a 16-bit bus width, only data is | ||
237 | * transferred at the 16-bit width. All address and command line | ||
238 | * transfers shall use only the lower 8-bits of the data bus. During | ||
239 | * command transfers, the host may place any value on the upper | ||
240 | * 8-bits of the data bus. During address transfers, the host shall | ||
241 | * set the upper 8-bits of the data bus to 00h. | ||
242 | * | ||
243 | * One user of the write_byte callback is nand_onfi_set_features. The | ||
244 | * four parameters are specified to be written to I/O[7:0], but this is | ||
245 | * neither an address nor a command transfer. Let's assume a 0 on the | ||
246 | * upper I/O lines is OK. | ||
247 | */ | ||
248 | chip->write_buf(mtd, (uint8_t *)&word, 2); | ||
249 | } | ||
250 | |||
251 | /** | ||
207 | * nand_write_buf - [DEFAULT] write buffer to chip | 252 | * nand_write_buf - [DEFAULT] write buffer to chip |
208 | * @mtd: MTD device structure | 253 | * @mtd: MTD device structure |
209 | * @buf: data buffer | 254 | * @buf: data buffer |
@@ -2769,6 +2814,7 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
2769 | int addr, uint8_t *subfeature_param) | 2814 | int addr, uint8_t *subfeature_param) |
2770 | { | 2815 | { |
2771 | int status; | 2816 | int status; |
2817 | int i; | ||
2772 | 2818 | ||
2773 | if (!chip->onfi_version || | 2819 | if (!chip->onfi_version || |
2774 | !(le16_to_cpu(chip->onfi_params.opt_cmd) | 2820 | !(le16_to_cpu(chip->onfi_params.opt_cmd) |
@@ -2776,7 +2822,9 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
2776 | return -EINVAL; | 2822 | return -EINVAL; |
2777 | 2823 | ||
2778 | chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1); | 2824 | chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1); |
2779 | chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN); | 2825 | for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) |
2826 | chip->write_byte(mtd, subfeature_param[i]); | ||
2827 | |||
2780 | status = chip->waitfunc(mtd, chip); | 2828 | status = chip->waitfunc(mtd, chip); |
2781 | if (status & NAND_STATUS_FAIL) | 2829 | if (status & NAND_STATUS_FAIL) |
2782 | return -EIO; | 2830 | return -EIO; |
@@ -2793,6 +2841,8 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
2793 | static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, | 2841 | static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, |
2794 | int addr, uint8_t *subfeature_param) | 2842 | int addr, uint8_t *subfeature_param) |
2795 | { | 2843 | { |
2844 | int i; | ||
2845 | |||
2796 | if (!chip->onfi_version || | 2846 | if (!chip->onfi_version || |
2797 | !(le16_to_cpu(chip->onfi_params.opt_cmd) | 2847 | !(le16_to_cpu(chip->onfi_params.opt_cmd) |
2798 | & ONFI_OPT_CMD_SET_GET_FEATURES)) | 2848 | & ONFI_OPT_CMD_SET_GET_FEATURES)) |
@@ -2802,7 +2852,8 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
2802 | memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN); | 2852 | memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN); |
2803 | 2853 | ||
2804 | chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1); | 2854 | chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1); |
2805 | chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN); | 2855 | for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) |
2856 | *subfeature_param++ = chip->read_byte(mtd); | ||
2806 | return 0; | 2857 | return 0; |
2807 | } | 2858 | } |
2808 | 2859 | ||
@@ -2865,6 +2916,8 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) | |||
2865 | chip->block_markbad = nand_default_block_markbad; | 2916 | chip->block_markbad = nand_default_block_markbad; |
2866 | if (!chip->write_buf || chip->write_buf == nand_write_buf) | 2917 | if (!chip->write_buf || chip->write_buf == nand_write_buf) |
2867 | chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; | 2918 | chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; |
2919 | if (!chip->write_byte || chip->write_byte == nand_write_byte) | ||
2920 | chip->write_byte = busw ? nand_write_byte16 : nand_write_byte; | ||
2868 | if (!chip->read_buf || chip->read_buf == nand_read_buf) | 2921 | if (!chip->read_buf || chip->read_buf == nand_read_buf) |
2869 | chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; | 2922 | chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; |
2870 | if (!chip->scan_bbt) | 2923 | if (!chip->scan_bbt) |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 05fcdfea640b..352e23891f58 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -456,6 +456,8 @@ struct nand_buffers { | |||
456 | * flash device. | 456 | * flash device. |
457 | * @read_byte: [REPLACEABLE] read one byte from the chip | 457 | * @read_byte: [REPLACEABLE] read one byte from the chip |
458 | * @read_word: [REPLACEABLE] read one word from the chip | 458 | * @read_word: [REPLACEABLE] read one word from the chip |
459 | * @write_byte: [REPLACEABLE] write a single byte to the chip on the | ||
460 | * low 8 I/O lines | ||
459 | * @write_buf: [REPLACEABLE] write data from the buffer to the chip | 461 | * @write_buf: [REPLACEABLE] write data from the buffer to the chip |
460 | * @read_buf: [REPLACEABLE] read data from the chip into the buffer | 462 | * @read_buf: [REPLACEABLE] read data from the chip into the buffer |
461 | * @select_chip: [REPLACEABLE] select chip nr | 463 | * @select_chip: [REPLACEABLE] select chip nr |
@@ -548,6 +550,7 @@ struct nand_chip { | |||
548 | 550 | ||
549 | uint8_t (*read_byte)(struct mtd_info *mtd); | 551 | uint8_t (*read_byte)(struct mtd_info *mtd); |
550 | u16 (*read_word)(struct mtd_info *mtd); | 552 | u16 (*read_word)(struct mtd_info *mtd); |
553 | void (*write_byte)(struct mtd_info *mtd, uint8_t byte); | ||
551 | void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); | 554 | void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); |
552 | void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); | 555 | void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); |
553 | void (*select_chip)(struct mtd_info *mtd, int chip); | 556 | void (*select_chip)(struct mtd_info *mtd, int chip); |