aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_base.c57
-rw-r--r--include/linux/mtd/nand.h3
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 */
213static 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 */
227static 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,
2793static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, 2841static 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);