diff mbox

[v2] mtd/nand: don't use {read,write}_buf for 8-bit transfers

Message ID 1362415655-13073-1-git-send-email-u.kleine-koenig@pengutronix.de
State Changes Requested
Headers show

Commit Message

Uwe Kleine-König March 4, 2013, 4:47 p.m. UTC
According to the Open NAND Flash Interface Specification (ONFI) Revision
3.1 "Parameters are always transferred on the lower 8-bits of the data
bus." for the Get Features and Set Features commands.

So using read_buf and write_buf is wrong for 16-bit wide nand chips as
they use I/O[15:0]. The Get Features command is easily fixed using 4
times the read_byte callback. For Set Features implement a new
overwritable callback "write_byte". Still I expect the default to work
just fine for all controllers.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---

Notes:
    v1 got an
    	Acked-by: Huang Shijie <b32955@freescale.com>
    
    Changes since (implicit) v1, sent with
    Message-Id:1361977852-18233-1-git-send-email-u.kleine-koenig@pengutronix.de:
    
     - implement a new write_byte callback to also fix
       nand_onfi_set_features (instead of returning -ENOSUPP in v1)

 drivers/mtd/nand/nand_base.c | 60 +++++++++++++++++++++++++++++++++++++++++---
 include/linux/mtd/nand.h     |  3 +++
 2 files changed, 59 insertions(+), 4 deletions(-)

Comments

Uwe Kleine-König March 4, 2013, 4:50 p.m. UTC | #1
Hello,

I forgot to add Huang Shijie to Cc: and copied the wrong Message-Id for
the --in-reply-to parameter to git-send-email.

@Huang Shijie: I didn't carry over your Ack to this new patch. Are you
still happy with this one?

Sorry,
Uwe

On Mon, Mar 04, 2013 at 05:47:35PM +0100, Uwe Kleine-König wrote:
> According to the Open NAND Flash Interface Specification (ONFI) Revision
> 3.1 "Parameters are always transferred on the lower 8-bits of the data
> bus." for the Get Features and Set Features commands.
> 
> So using read_buf and write_buf is wrong for 16-bit wide nand chips as
> they use I/O[15:0]. The Get Features command is easily fixed using 4
> times the read_byte callback. For Set Features implement a new
> overwritable callback "write_byte". Still I expect the default to work
> just fine for all controllers.
> 
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> ---
> 
> Notes:
>     v1 got an
>     	Acked-by: Huang Shijie <b32955@freescale.com>
>     
>     Changes since (implicit) v1, sent with
>     Message-Id:1361977852-18233-1-git-send-email-u.kleine-koenig@pengutronix.de:
>     
>      - implement a new write_byte callback to also fix
>        nand_onfi_set_features (instead of returning -ENOSUPP in v1)
> 
>  drivers/mtd/nand/nand_base.c | 60 +++++++++++++++++++++++++++++++++++++++++---
>  include/linux/mtd/nand.h     |  3 +++
>  2 files changed, 59 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 3766682..956b499 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -205,6 +205,50 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr)
>  }
>  
>  /**
> + * nand_write_byte - [DEFAULT] write single byte to chip
> + * @mtd: MTD device structure
> + * @byte: value to write
> + *
> + * Default function to write a byte to I/O[7:0]
> + */
> +static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
> +{
> +	struct nand_chip *chip = mtd->priv;
> +
> +	chip->write_buf(mtd, &byte, 1);
> +}
> +
> +/**
> + * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16
> + * @mtd: MTD device structure
> + * @byte: value to write
> + *
> + * Default function to write a byte to I/O[7:0] on a 16-bit wide chip.
> + */
> +static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
> +{
> +	struct nand_chip *chip = mtd->priv;
> +
> +	/*
> +	 * It's not entirely clear what should happen to I/O[15:8] when writing
> +	 * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads:
> +	 *
> +	 *    When the host supports a 16-bit bus width, only data is
> +	 *    transferred at the 16-bit width. All address and command line
> +	 *    transfers shall use only the lower 8-bits of the data bus. During
> +	 *    command transfers, the host may place any value on the upper
> +	 *    8-bits of the data bus. During address transfers, the host shall
> +	 *    set the upper 8-bits of the data bus to 00h.
> +	 *
> +	 * One user of the write_byte callback is nand_onfi_set_features. The
> +	 * four parameters are specified to be written to I/O[7:0], but this is
> +	 * neither an address nor a command transfer. Let's assume a 0 on the
> +	 * upper I/O lines is OK.
> +	 */
> +	chip->write_buf(mtd, (uint8_t[]){ byte, 0 }, 2);
> +}
> +
> +/**
>   * nand_write_buf - [DEFAULT] write buffer to chip
>   * @mtd: MTD device structure
>   * @buf: data buffer
> @@ -2710,7 +2754,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
>  }
>  
>  /**
> - * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
> + * nand_onfi_set_features - [REPLACEABLE] set features for ONFI nand
>   * @mtd: MTD device structure
>   * @chip: nand chip info structure
>   * @addr: feature address.
> @@ -2720,12 +2764,15 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
>  			int addr, uint8_t *subfeature_param)
>  {
>  	int status;
> +	int i;
>  
>  	if (!chip->onfi_version)
>  		return -EINVAL;
>  
>  	chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
> -	chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
> +	for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
> +		chip->write_byte(mtd, subfeature_param[i]);
> +
>  	status = chip->waitfunc(mtd, chip);
>  	if (status & NAND_STATUS_FAIL)
>  		return -EIO;
> @@ -2733,7 +2780,7 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
>  }
>  
>  /**
> - * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
> + * nand_onfi_get_features - [REPLACEABLE] get features for ONFI nand
>   * @mtd: MTD device structure
>   * @chip: nand chip info structure
>   * @addr: feature address.
> @@ -2742,6 +2789,8 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
>  static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
>  			int addr, uint8_t *subfeature_param)
>  {
> +	int i;
> +
>  	if (!chip->onfi_version)
>  		return -EINVAL;
>  
> @@ -2749,7 +2798,8 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
>  	memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
>  
>  	chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
> -	chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
> +	for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
> +		*subfeature_param++ = chip->read_byte(mtd);
>  	return 0;
>  }
>  
> @@ -2804,6 +2854,8 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
>  		chip->block_markbad = nand_default_block_markbad;
>  	if (!chip->write_buf)
>  		chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
> +	if (!chip->write_byte)
> +		chip->write_byte = busw ? nand_write_byte16 : nand_write_byte;
>  	if (!chip->read_buf)
>  		chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
>  	if (!chip->scan_bbt)
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> index 7ccb3c5..8ee4ed1 100644
> --- a/include/linux/mtd/nand.h
> +++ b/include/linux/mtd/nand.h
> @@ -419,6 +419,8 @@ struct nand_buffers {
>   *			flash device.
>   * @read_byte:		[REPLACEABLE] read one byte from the chip
>   * @read_word:		[REPLACEABLE] read one word from the chip
> + * @write_byte		[REPLACEABLE] write a single byte to the chip on the
> + *			low 8 I/O lines
>   * @write_buf:		[REPLACEABLE] write data from the buffer to the chip
>   * @read_buf:		[REPLACEABLE] read data from the chip into the buffer
>   * @select_chip:	[REPLACEABLE] select chip nr
> @@ -503,6 +505,7 @@ struct nand_chip {
>  
>  	uint8_t (*read_byte)(struct mtd_info *mtd);
>  	u16 (*read_word)(struct mtd_info *mtd);
> +	void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
>  	void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
>  	void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
>  	void (*select_chip)(struct mtd_info *mtd, int chip);
> -- 
> 1.8.2.rc2
> 
>
Huang Shijie March 5, 2013, 2 a.m. UTC | #2
于 2013年03月05日 00:50, Uwe Kleine-König 写道:
> @Huang Shijie: I didn't carry over your Ack to this new patch. Are you
> still happy with this one?
it's ok. :)


thanks
Huang Shijie
Artem Bityutskiy March 13, 2013, 9:33 a.m. UTC | #3
On Mon, 2013-03-04 at 17:47 +0100, Uwe Kleine-König wrote:
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> index 7ccb3c5..8ee4ed1 100644
> --- a/include/linux/mtd/nand.h
> +++ b/include/linux/mtd/nand.h
> @@ -419,6 +419,8 @@ struct nand_buffers {
>   *                     flash device.
>   * @read_byte:         [REPLACEABLE] read one byte from the chip
>   * @read_word:         [REPLACEABLE] read one word from the chip
> + * @write_byte         [REPLACEABLE] write a single byte to the chip on the
> + *                     low 8 I/O lines
>   * @write_buf:         [REPLACEABLE] write data from the buffer to the chip
>   * @read_buf:          [REPLACEABLE] read data from the chip into the buffer
>   * @select_chip:       [REPLACEABLE] select chip nr
> @@ -503,6 +505,7 @@ struct nand_chip {
>  
>         uint8_t (*read_byte)(struct mtd_info *mtd);
>         u16 (*read_word)(struct mtd_info *mtd);
> +       void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
>         void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
>         void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
>         void (*select_chip)(struct mtd_info *mtd, int chip);

I would like to make the interface symmetric for read and write. I do
not have any 16 bit flashes, so need to somehow encouredge someone who
has one to do this. Namely, I'd like to kill 'read_word()', if possible.
What's your take on this?
Artem Bityutskiy March 13, 2013, 10:26 a.m. UTC | #4
On Mon, 2013-03-04 at 17:47 +0100, Uwe Kleine-König wrote:
> According to the Open NAND Flash Interface Specification (ONFI) Revision
> 3.1 "Parameters are always transferred on the lower 8-bits of the data
> bus." for the Get Features and Set Features commands.
> 
> So using read_buf and write_buf is wrong for 16-bit wide nand chips as
> they use I/O[15:0]. The Get Features command is easily fixed using 4
> times the read_byte callback. For Set Features implement a new
> overwritable callback "write_byte". Still I expect the default to work
> just fine for all controllers.
> 
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Pushed to l2-mtd.git, thanks!
David Woodhouse April 5, 2013, 12:13 p.m. UTC | #5
On Mon, 2013-03-04 at 17:47 +0100, Uwe Kleine-König wrote:
> + */
> +static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
> +{
> +       struct nand_chip *chip = mtd->priv;
> +
> +       /*
> +        * It's not entirely clear what should happen to I/O[15:8] when writing
> +        * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads:
> +        *
> +        *    When the host supports a 16-bit bus width, only data is
> +        *    transferred at the 16-bit width. All address and command line
> +        *    transfers shall use only the lower 8-bits of the data bus. During
> +        *    command transfers, the host may place any value on the upper
> +        *    8-bits of the data bus. During address transfers, the host shall
> +        *    set the upper 8-bits of the data bus to 00h.
> +        *
> +        * One user of the write_byte callback is nand_onfi_set_features. The
> +        * four parameters are specified to be written to I/O[7:0], but this is
> +        * neither an address nor a command transfer. Let's assume a 0 on the
> +        * upper I/O lines is OK.
> +        */
> +       chip->write_buf(mtd, (uint8_t[]){ byte, 0 }, 2);

Ick. Can you declare that array separately, rather than in the function
call please?

And also this seems broken on big-endian. nand_write_buf16() will cast
the 'buf' pointer to a uint16_t *, load a single uint16_t from it (for
example 0x5a00 if byte==0x5a), and proceed to write the 'byte' value on
the *high* side of the data bus, not the low side. Won't it?
Uwe Kleine-König Nov. 26, 2013, 9:03 p.m. UTC | #6
On Wed, Mar 13, 2013 at 11:33:04AM +0200, Artem Bityutskiy wrote:
> On Mon, 2013-03-04 at 17:47 +0100, Uwe Kleine-König wrote:
> > diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> > index 7ccb3c5..8ee4ed1 100644
> > --- a/include/linux/mtd/nand.h
> > +++ b/include/linux/mtd/nand.h
> > @@ -419,6 +419,8 @@ struct nand_buffers {
> >   *                     flash device.
> >   * @read_byte:         [REPLACEABLE] read one byte from the chip
> >   * @read_word:         [REPLACEABLE] read one word from the chip
> > + * @write_byte         [REPLACEABLE] write a single byte to the chip on the
> > + *                     low 8 I/O lines
> >   * @write_buf:         [REPLACEABLE] write data from the buffer to the chip
> >   * @read_buf:          [REPLACEABLE] read data from the chip into the buffer
> >   * @select_chip:       [REPLACEABLE] select chip nr
> > @@ -503,6 +505,7 @@ struct nand_chip {
> >  
> >         uint8_t (*read_byte)(struct mtd_info *mtd);
> >         u16 (*read_word)(struct mtd_info *mtd);
> > +       void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
> >         void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
> >         void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
> >         void (*select_chip)(struct mtd_info *mtd, int chip);
> 
> I would like to make the interface symmetric for read and write. I do
> not have any 16 bit flashes, so need to somehow encouredge someone who
> has one to do this. Namely, I'd like to kill 'read_word()', if possible.
> What's your take on this?
I don't have a 16 bit flash, so I have the same excuse as you do :-)

Uwe
Brian Norris Nov. 27, 2013, 6:59 a.m. UTC | #7
+ Pekon, Ezequiel

On Tue, Nov 26, 2013 at 10:03:41PM +0100, Uwe Kleine-König wrote:
> On Wed, Mar 13, 2013 at 11:33:04AM +0200, Artem Bityutskiy wrote:

Resurrecting a really old thread, eh? :) I like it!

> > On Mon, 2013-03-04 at 17:47 +0100, Uwe Kleine-König wrote:
> > > diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> > > index 7ccb3c5..8ee4ed1 100644
> > > --- a/include/linux/mtd/nand.h
> > > +++ b/include/linux/mtd/nand.h
> > > @@ -419,6 +419,8 @@ struct nand_buffers {
> > >   *                     flash device.
> > >   * @read_byte:         [REPLACEABLE] read one byte from the chip
> > >   * @read_word:         [REPLACEABLE] read one word from the chip
> > > + * @write_byte         [REPLACEABLE] write a single byte to the chip on the
> > > + *                     low 8 I/O lines
> > >   * @write_buf:         [REPLACEABLE] write data from the buffer to the chip
> > >   * @read_buf:          [REPLACEABLE] read data from the chip into the buffer
> > >   * @select_chip:       [REPLACEABLE] select chip nr
> > > @@ -503,6 +505,7 @@ struct nand_chip {
> > >  
> > >         uint8_t (*read_byte)(struct mtd_info *mtd);
> > >         u16 (*read_word)(struct mtd_info *mtd);
> > > +       void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
> > >         void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
> > >         void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
> > >         void (*select_chip)(struct mtd_info *mtd, int chip);
> > 
> > I would like to make the interface symmetric for read and write. I do
> > not have any 16 bit flashes, so need to somehow encouredge someone who
> > has one to do this. Namely, I'd like to kill 'read_word()', if possible.
> > What's your take on this?
> I don't have a 16 bit flash, so I have the same excuse as you do :-)

Ezequiel and Pekon have 16-bit devices and can do testing, I think. They
also may be interested in your v3 patch.

Brian
diff mbox

Patch

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3766682..956b499 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -205,6 +205,50 @@  static void nand_select_chip(struct mtd_info *mtd, int chipnr)
 }
 
 /**
+ * nand_write_byte - [DEFAULT] write single byte to chip
+ * @mtd: MTD device structure
+ * @byte: value to write
+ *
+ * Default function to write a byte to I/O[7:0]
+ */
+static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	chip->write_buf(mtd, &byte, 1);
+}
+
+/**
+ * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16
+ * @mtd: MTD device structure
+ * @byte: value to write
+ *
+ * Default function to write a byte to I/O[7:0] on a 16-bit wide chip.
+ */
+static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	/*
+	 * It's not entirely clear what should happen to I/O[15:8] when writing
+	 * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads:
+	 *
+	 *    When the host supports a 16-bit bus width, only data is
+	 *    transferred at the 16-bit width. All address and command line
+	 *    transfers shall use only the lower 8-bits of the data bus. During
+	 *    command transfers, the host may place any value on the upper
+	 *    8-bits of the data bus. During address transfers, the host shall
+	 *    set the upper 8-bits of the data bus to 00h.
+	 *
+	 * One user of the write_byte callback is nand_onfi_set_features. The
+	 * four parameters are specified to be written to I/O[7:0], but this is
+	 * neither an address nor a command transfer. Let's assume a 0 on the
+	 * upper I/O lines is OK.
+	 */
+	chip->write_buf(mtd, (uint8_t[]){ byte, 0 }, 2);
+}
+
+/**
  * nand_write_buf - [DEFAULT] write buffer to chip
  * @mtd: MTD device structure
  * @buf: data buffer
@@ -2710,7 +2754,7 @@  static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 }
 
 /**
- * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
+ * nand_onfi_set_features - [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
  * @addr: feature address.
@@ -2720,12 +2764,15 @@  static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
 			int addr, uint8_t *subfeature_param)
 {
 	int status;
+	int i;
 
 	if (!chip->onfi_version)
 		return -EINVAL;
 
 	chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
-	chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+	for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
+		chip->write_byte(mtd, subfeature_param[i]);
+
 	status = chip->waitfunc(mtd, chip);
 	if (status & NAND_STATUS_FAIL)
 		return -EIO;
@@ -2733,7 +2780,7 @@  static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
+ * nand_onfi_get_features - [REPLACEABLE] get features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
  * @addr: feature address.
@@ -2742,6 +2789,8 @@  static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
 static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
 			int addr, uint8_t *subfeature_param)
 {
+	int i;
+
 	if (!chip->onfi_version)
 		return -EINVAL;
 
@@ -2749,7 +2798,8 @@  static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
 	memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
 
 	chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
-	chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+	for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
+		*subfeature_param++ = chip->read_byte(mtd);
 	return 0;
 }
 
@@ -2804,6 +2854,8 @@  static void nand_set_defaults(struct nand_chip *chip, int busw)
 		chip->block_markbad = nand_default_block_markbad;
 	if (!chip->write_buf)
 		chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
+	if (!chip->write_byte)
+		chip->write_byte = busw ? nand_write_byte16 : nand_write_byte;
 	if (!chip->read_buf)
 		chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
 	if (!chip->scan_bbt)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 7ccb3c5..8ee4ed1 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -419,6 +419,8 @@  struct nand_buffers {
  *			flash device.
  * @read_byte:		[REPLACEABLE] read one byte from the chip
  * @read_word:		[REPLACEABLE] read one word from the chip
+ * @write_byte		[REPLACEABLE] write a single byte to the chip on the
+ *			low 8 I/O lines
  * @write_buf:		[REPLACEABLE] write data from the buffer to the chip
  * @read_buf:		[REPLACEABLE] read data from the chip into the buffer
  * @select_chip:	[REPLACEABLE] select chip nr
@@ -503,6 +505,7 @@  struct nand_chip {
 
 	uint8_t (*read_byte)(struct mtd_info *mtd);
 	u16 (*read_word)(struct mtd_info *mtd);
+	void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
 	void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
 	void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
 	void (*select_chip)(struct mtd_info *mtd, int chip);