Patchwork [U-Boot,RFC] Add general nand functions

login
register
mail settings
Submitter Simon Schwarz
Date Sept. 23, 2011, 4:36 p.m.
Message ID <1316795819-3163-1-git-send-email-simonschwarzcor@gmail.com>
Download mbox | patch
Permalink /patch/116149/
State Superseded
Delegated to: Scott Wood
Headers show

Comments

Simon Schwarz - Sept. 23, 2011, 4:36 p.m.
Added a nand_base.h header that defines all prototypes of nand_base.c
functions. This is necessary because these functions were often copied
in SPLs. This patch also removes the static definition of these functions
in nand_base.c

It was necessary to also add nand_interface.c. This now defines static
inline functions former defined in nand.h - theses functions had name
conflicts with these in nand_base.c/h.

Files former included nand.h now include also nand_interface.h

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>
Cc: scottwood@freescale.com
Cc: albert.u.boot@aribaud.net
---

 arch/arm/cpu/armv7/omap-common/spl.c            |    1 +
 arch/arm/cpu/armv7/omap-common/spl_nand.c       |    1 +
 arch/arm/lib/board.c                            |    1 +
 arch/blackfin/lib/board.c                       |    3 +-
 arch/m68k/lib/board.c                           |    1 +
 arch/mips/lib/board.c                           |    1 +
 arch/nios2/lib/board.c                          |    3 +-
 arch/powerpc/cpu/mpc85xx/cpu_init.c             |    1 +
 arch/powerpc/lib/board.c                        |    1 +
 board/BuS/eb_cpux9k2/cpux9k2.c                  |    1 +
 board/atmel/at91sam9261ek/at91sam9261ek.c       |    1 +
 board/atmel/at91sam9263ek/at91sam9263ek.c       |    1 +
 board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c |    1 +
 board/atmel/at91sam9rlek/at91sam9rlek.c         |    1 +
 board/dave/PPChameleonEVB/nand.c                |    1 +
 board/davedenx/qong/qong.c                      |    1 +
 board/davinci/da8xxevm/hawkboard_nand_spl.c     |    1 +
 board/davinci/dm355evm/dm355evm.c               |    1 +
 board/davinci/dm355leopard/dm355leopard.c       |    1 +
 board/davinci/dm365evm/dm365evm.c               |    1 +
 board/davinci/dm6467evm/dm6467evm.c             |    1 +
 board/davinci/sonata/sonata.c                   |    1 +
 board/esd/common/esd405ep_nand.c                |    1 +
 board/freescale/m5329evb/nand.c                 |    1 +
 board/freescale/m5373evb/nand.c                 |    1 +
 board/freescale/mpc8313erdb/mpc8313erdb.c       |    1 +
 board/freescale/mpc8315erdb/mpc8315erdb.c       |    1 +
 board/freescale/mpc8360erdk/nand.c              |    1 +
 board/ids8247/ids8247.c                         |    1 +
 board/keymile/km_arm/km_arm.c                   |    1 +
 board/prodrive/alpr/nand.c                      |    1 +
 board/prodrive/pdnb3/nand.c                     |    1 +
 board/quad100hd/nand.c                          |    1 +
 board/ronetix/pm9261/pm9261.c                   |    1 +
 board/ronetix/pm9263/pm9263.c                   |    1 +
 board/sc3/sc3nand.c                             |    1 +
 board/sheldon/simpc8313/simpc8313.c             |    1 +
 board/socrates/nand.c                           |    1 +
 board/spear/spear300/spear300.c                 |    1 +
 board/spear/spear310/spear310.c                 |    1 +
 board/spear/spear320/spear320.c                 |    1 +
 board/spear/spear600/spear600.c                 |    1 +
 board/tqc/tqm8272/nand.c                        |    1 +
 board/tqc/tqm85xx/nand.c                        |    1 +
 board/ve8313/ve8313.c                           |    1 +
 board/xes/common/actl_nand.c                    |    1 +
 common/cmd_jffs2.c                              |    1 +
 common/cmd_mtdparts.c                           |    1 +
 common/cmd_nand.c                               |    1 +
 common/cmd_ubi.c                                |    1 +
 common/env_nand.c                               |    1 +
 drivers/mtd/nand/atmel_nand.c                   |    1 +
 drivers/mtd/nand/bfin_nand.c                    |    1 +
 drivers/mtd/nand/davinci_nand.c                 |    1 +
 drivers/mtd/nand/fsl_upm.c                      |    1 +
 drivers/mtd/nand/kb9202_nand.c                  |    1 +
 drivers/mtd/nand/kirkwood_nand.c                |    1 +
 drivers/mtd/nand/kmeter1_nand.c                 |    1 +
 drivers/mtd/nand/mpc5121_nfc.c                  |    1 +
 drivers/mtd/nand/mxc_nand.c                     |    1 +
 drivers/mtd/nand/nand.c                         |    1 +
 drivers/mtd/nand/nand_base.c                    |  142 +++++++++++------------
 drivers/mtd/nand/nand_plat.c                    |    1 +
 drivers/mtd/nand/nand_spl_simple.c              |    1 +
 drivers/mtd/nand/nand_util.c                    |    1 +
 drivers/mtd/nand/ndfc.c                         |    1 +
 drivers/mtd/nand/nomadik.c                      |    1 +
 drivers/mtd/nand/omap_gpmc.c                    |    1 +
 drivers/mtd/nand/s3c2410_nand.c                 |    1 +
 drivers/mtd/nand/s3c64xx.c                      |   27 +----
 drivers/mtd/nand/spr_nand.c                     |    1 +
 fs/jffs2/jffs2_1pass.c                          |    1 +
 fs/jffs2/jffs2_nand_1pass.c                     |    1 +
 include/nand.h                                  |  132 ++++++++++++++++-----
 include/nand_base.h                             |  127 ++++++++++++++++++++
 include/nand_interface.h                        |   32 +++++
 nand_spl/board/freescale/mpc8536ds/nand_boot.c  |    1 +
 nand_spl/board/freescale/mpc8569mds/nand_boot.c |    1 +
 nand_spl/board/freescale/mpc8572ds/nand_boot.c  |    1 +
 nand_spl/board/freescale/p1023rds/nand_boot.c   |    1 +
 nand_spl/board/freescale/p1_p2_rdb/nand_boot.c  |    1 +
 nand_spl/board/samsung/smdk6400/Makefile        |   10 +-
 nand_spl/nand_boot.c                            |    1 +
 nand_spl/nand_boot_fsl_nfc.c                    |    1 +
 84 files changed, 419 insertions(+), 133 deletions(-)
 create mode 100644 include/nand_base.h
 create mode 100644 include/nand_interface.h
Simon Schwarz - Sept. 23, 2011, 4:42 p.m.
RFC-Patch to solve this problem.

I had to modify many files because of a name conflict.

I will do BUILDALL for arm over the weekend...

What are the opinions for this solution? Scott?

Regards and have a nice weekend
Simon


On 09/23/2011 06:36 PM, Simon Schwarz wrote:
[SNIP]
Scott Wood - Sept. 23, 2011, 5:22 p.m.
On 09/23/2011 11:36 AM, Simon Schwarz wrote:
> Added a nand_base.h header that defines all prototypes of nand_base.c
> functions.

Just add the new prototypes to include/linux/mtd/nand.h (which gets
included by nand.h), that's the header that goes with
drivers/mtd/nand/nand_base.c.

> This is necessary because these functions were often copied
> in SPLs. 

You'd rather add new #includes to dozens of files, and keep duplicated
code around, than fix a few SPLs?  NACK.

> It was necessary to also add nand_interface.c. 

You maen nand_interface.h?

> This now defines static
> inline functions former defined in nand.h - theses functions had name
> conflicts with these in nand_base.c/h.

If we have two functions with the same name that do different things,
change the name of the one in nand.h.

> diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
> index bfdb586..4568820 100644
> --- a/arch/blackfin/lib/board.c
> +++ b/arch/blackfin/lib/board.c
> @@ -25,7 +25,8 @@
>  #include <kgdb.h>
>  
>  #ifdef CONFIG_CMD_NAND
> -#include <nand.h>	/* cannot even include nand.h if it isnt configured */
> +#include <nand.h>
> +#include <nand_interface.h>	/* cannot even include nand.h if it isnt configured */


I don't think it's still true that you can't include nand.h if it isn't
configured, BTW.

> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index e7dfcb1..3fe0935 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -51,6 +51,8 @@
>  #include <asm/io.h>
>  #include <asm/errno.h>
>  
> +#include <nand_base.h>

Wait, there's *two* new headers?

> +/* nand_base.c Standard implementation of nand functions */
> +void nand_release_device (struct mtd_info *mtd);
> +uint8_t nand_read_byte(struct mtd_info *mtd);
> +uint8_t nand_read_byte16(struct mtd_info *mtd);
> +u16 nand_read_word(struct mtd_info *mtd);
> +void nand_select_chip(struct mtd_info *mtd, int chipnr);
> +void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
> +void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
> +int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
> +void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
> +void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
> +int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
> +int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip);
> +int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs);
> +int nand_check_wp(struct mtd_info *mtd);
> +int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
> +		int allowbbt);
> +void nand_wait_ready(struct mtd_info *mtd);
> +void nand_command(struct mtd_info *mtd, unsigned int command, int column,
> +		int page_addr);
> +void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column,
> +		 int page_addr);
> +int nand_get_device (struct nand_chip *this, struct mtd_info *mtd,
> +		int new_state);
> +int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
> +int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
> +		uint8_t *buf, int page);
> +static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
> +		struct nand_chip *chip, uint8_t *buf, int page);
> +int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
> +		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi);
> +int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
> +		uint8_t *buf, int page);
> +int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
> +		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi);
> +int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
> +		uint8_t *buf, int page);
> +int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
> +		struct nand_chip *chip, uint8_t *buf, int page);
> +int nand_read_page_syndrome(struct mtd_info *mtd,
> +		struct nand_chip *chip, uint8_t *buf, int page);
> +uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
> +		struct mtd_oob_ops *ops, size_t len);
> +int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
> +		struct mtd_oob_ops *ops);
> +int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
> +		int page, int sndcmd);
> +int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
> +		int page, int sndcmd);
> +int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
> +		int page);
> +int nand_write_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
> +		int page);
> +int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
> +		struct mtd_oob_ops *ops);
> +int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
> +void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
> +		const uint8_t *buf);
> +void nand_write_page_raw_syndrome(struct mtd_info *mtd,
> +		struct nand_chip *chip, const uint8_t *buf);
> +void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
> +		const uint8_t *buf);
> +void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
> +		const uint8_t *buf);
> +void nand_write_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
> +		const uint8_t *buf);
> +int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
> +		const uint8_t *buf, int page, int cached, int raw);
> +uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
> +		struct mtd_oob_ops *ops);
> +int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
> +		struct mtd_oob_ops *ops);
> +int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
> +int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
> +void single_erase_cmd(struct mtd_info *mtd, int page);
> +void multi_erase_cmd(struct mtd_info *mtd, int page);
> +int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
> +		int allowbbt);
> +int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
> +		size_t *retlen, uint8_t *buf);
> +int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
> +		size_t *retlen, const uint8_t *buf);
> +int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
> +void nand_sync(struct mtd_info *mtd);
> +int nand_block_isbad(struct mtd_info *mtd, loff_t offs);
> +int nand_block_markbad(struct mtd_info *mtd, loff_t ofs);
> +void nand_set_defaults(struct nand_chip *chip, int busw);
> +u16 onfi_crc16(u16 crc, u8 const *p, size_t len);
> +int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
> +		int *busw);
> +void nand_flash_detect_non_onfi(struct mtd_info *mtd, struct nand_chip *chip,
> +		const struct nand_flash_dev *type, int *busw);
> +const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
> +		struct nand_chip *chip, int busw, int *maf_id, int *dev_id,
> +		const struct nand_flash_dev *type);
> +int nand_scan_ident(struct mtd_info *mtd, int maxchips,
> +		const struct nand_flash_dev *table);
> +int nand_scan_tail(struct mtd_info *mtd);
> +int nand_scan(struct mtd_info *mtd, int maxchips);
> +void nand_release(struct mtd_info *mtd);

Can we limit the scope of this to functions (or classes thereof -- if we
export one buffer function might as well export all the variants) that
we actually need from a current SPL?

> diff --git a/nand_spl/board/samsung/smdk6400/Makefile b/nand_spl/board/samsung/smdk6400/Makefile
> index 2f9c307..32ea116 100644
> --- a/nand_spl/board/samsung/smdk6400/Makefile
> +++ b/nand_spl/board/samsung/smdk6400/Makefile
> @@ -33,12 +33,12 @@ nandobj	:= $(OBJTREE)/nand_spl/
>  
>  LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds
>  LDFLAGS := -T $(nandobj)u-boot.lds -Ttext $(CONFIG_SYS_TEXT_BASE) $(LDFLAGS) \
> -	   $(LDFLAGS_FINAL)
> +	   $(LDFLAGS_FINAL) -gc-sections
>  AFLAGS	+= -DCONFIG_NAND_SPL
> -CFLAGS	+= -DCONFIG_NAND_SPL
> +CFLAGS	+= -DCONFIG_NAND_SPL -ffunction-sections 

Are gc-sections/function-sections not already being set?

>  SOBJS	= start.o cpu_init.o lowlevel_init.o
> -COBJS	= nand_boot.o nand_ecc.o s3c64xx.o smdk6400_nand_spl.o
> +COBJS	= nand_boot.o nand_ecc.o s3c64xx.o smdk6400_nand_spl.o nand_base.o
>  
>  SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
>  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
> @@ -98,6 +98,10 @@ $(obj)smdk6400_nand_spl.c:
>  	@rm -f $@
>  	@ln -s $(TOPDIR)/board/samsung/smdk6400/smdk6400_nand_spl.c $@
>  
> +$(obj)nand_base.c:
> +	@rm -f $@
> +	@ln -s $(TOPDIR)/drivers/mtd/nand/nand_base.c $@

This is a separate (albeit dependent) change from the NAND function
exporting, BTW.

-Scott
Simon Schwarz - Sept. 26, 2011, 8:27 a.m.
On 09/23/2011 07:22 PM, Scott Wood wrote:
> On 09/23/2011 11:36 AM, Simon Schwarz wrote:
>> Added a nand_base.h header that defines all prototypes of nand_base.c
>> functions.
>
> Just add the new prototypes to include/linux/mtd/nand.h (which gets
> included by nand.h), that's the header that goes with
> drivers/mtd/nand/nand_base.c.
>
That was my first intention. I changed my mind because of the name 
collisions.

>> This is necessary because these functions were often copied
>> in SPLs.
>
> You'd rather add new #includes to dozens of files, and keep duplicated
> code around, than fix a few SPLs?  NACK.
>
Where do you see duplicated code? The additional include?

>> It was necessary to also add nand_interface.c.
>
> You maen nand_interface.h?
>
Yes sorry.

>> This now defines static
>> inline functions former defined in nand.h - theses functions had name
>> conflicts with these in nand_base.c/h.
>
> If we have two functions with the same name that do different things,
> change the name of the one in nand.h.
>
>> diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
>> index bfdb586..4568820 100644
>> --- a/arch/blackfin/lib/board.c
>> +++ b/arch/blackfin/lib/board.c
>> @@ -25,7 +25,8 @@
>>   #include<kgdb.h>
>>
>>   #ifdef CONFIG_CMD_NAND
>> -#include<nand.h>	/* cannot even include nand.h if it isnt configured */
>> +#include<nand.h>
>> +#include<nand_interface.h>	/* cannot even include nand.h if it isnt configured */
>
>
> I don't think it's still true that you can't include nand.h if it isn't
> configured, BTW.
>
Auto search and replace.

[SNIP]

so in essence I will:
- rename the inline functions
- just add the functions used in SPL now
- make better patch-splitting

objections?

Regards
Simon
Scott Wood - Sept. 27, 2011, 12:28 a.m.
On 09/26/2011 03:27 AM, Simon Schwarz wrote:
> On 09/23/2011 07:22 PM, Scott Wood wrote:
>> On 09/23/2011 11:36 AM, Simon Schwarz wrote:
>>> Added a nand_base.h header that defines all prototypes of nand_base.c
>>> functions.
>>
>> Just add the new prototypes to include/linux/mtd/nand.h (which gets
>> included by nand.h), that's the header that goes with
>> drivers/mtd/nand/nand_base.c.
>>
> That was my first intention. I changed my mind because of the name
> collisions.
> 
>>> This is necessary because these functions were often copied
>>> in SPLs.
>>
>> You'd rather add new #includes to dozens of files, and keep duplicated
>> code around, than fix a few SPLs?  NACK.
>>
> Where do you see duplicated code? The additional include?

Sorry, I misparsed what was meant by the "this" in "this is necessary
because these functions were often copied...".

> so in essence I will:
> - rename the inline functions
> - just add the functions used in SPL now
> - make better patch-splitting
> 
> objections?

Sounds good.

-Scott
Simon Schwarz - Sept. 27, 2011, 10:14 a.m.
On 09/27/2011 02:28 AM, Scott Wood wrote:
> On 09/26/2011 03:27 AM, Simon Schwarz wrote:
>> On 09/23/2011 07:22 PM, Scott Wood wrote:
>>> On 09/23/2011 11:36 AM, Simon Schwarz wrote:
>>>> Added a nand_base.h header that defines all prototypes of nand_base.c
>>>> functions.
>>>
>>> Just add the new prototypes to include/linux/mtd/nand.h (which gets
>>> included by nand.h), that's the header that goes with
>>> drivers/mtd/nand/nand_base.c.
>>>
>> That was my first intention. I changed my mind because of the name
>> collisions.
>>
>>>> This is necessary because these functions were often copied
>>>> in SPLs.
>>>
>>> You'd rather add new #includes to dozens of files, and keep duplicated
>>> code around, than fix a few SPLs?  NACK.
>>>
>> Where do you see duplicated code? The additional include?
>
> Sorry, I misparsed what was meant by the "this" in "this is necessary
> because these functions were often copied...".
>
>> so in essence I will:
>> - rename the inline functions
>> - just add the functions used in SPL now
>> - make better patch-splitting
>>
>> objections?
>
> Sounds good.
>
> -Scott
>

Ok, new patch RFC is out. I didn't rename the inline functions because 
none of the duplicated names are used in an SPL.

Comments?

Regards
Simon
Scott Wood - Sept. 27, 2011, 10:50 p.m.
On 09/27/2011 05:14 AM, Simon Schwarz wrote:
> On 09/27/2011 02:28 AM, Scott Wood wrote:
>> On 09/26/2011 03:27 AM, Simon Schwarz wrote:
>>> so in essence I will:
>>> - rename the inline functions
>>> - just add the functions used in SPL now
>>> - make better patch-splitting
>>>
>>> objections?
>>
>> Sounds good.
>>
>> -Scott
>>
> 
> Ok, new patch RFC is out. I didn't rename the inline functions because
> none of the duplicated names are used in an SPL.
> 
> Comments?

Looks much better, thanks.

-Scott
Simon Schwarz - Sept. 28, 2011, 8:48 a.m.
On 09/28/2011 12:50 AM, Scott Wood wrote:
> On 09/27/2011 05:14 AM, Simon Schwarz wrote:
>> On 09/27/2011 02:28 AM, Scott Wood wrote:
>>> On 09/26/2011 03:27 AM, Simon Schwarz wrote:
>>>> so in essence I will:
>>>> - rename the inline functions
>>>> - just add the functions used in SPL now
>>>> - make better patch-splitting
>>>>
>>>> objections?
>>>
>>> Sounds good.
>>>
>>> -Scott
>>>
>>
>> Ok, new patch RFC is out. I didn't rename the inline functions because
>> none of the duplicated names are used in an SPL.
>>
>> Comments?
>
> Looks much better, thanks.
>
> -Scott
>
Great. Will do MAKEALL for arm and post it later this day.

Regards
Simon

Patch

diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
index c76fea6..0d42dcd 100644
--- a/arch/arm/cpu/armv7/omap-common/spl.c
+++ b/arch/arm/cpu/armv7/omap-common/spl.c
@@ -27,6 +27,7 @@ 
 #include <asm/utils.h>
 #include <asm/arch/sys_proto.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <mmc.h>
 #include <fat.h>
 #include <timestamp_autogenerated.h>
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c
index af02a59..31ce5b1 100644
--- a/arch/arm/cpu/armv7/omap-common/spl_nand.c
+++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c
@@ -25,6 +25,7 @@ 
 #include <asm/utils.h>
 #include <asm/arch/sys_proto.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <timestamp_autogenerated.h>
 #include <version_autogenerated.h>
 #include <asm/omap_common.h>
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 85320bc..c73d26a 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -46,6 +46,7 @@ 
 #include <net.h>
 #include <serial.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <onenand_uboot.h>
 #include <mmc.h>
 
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index bfdb586..4568820 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -25,7 +25,8 @@ 
 #include <kgdb.h>
 
 #ifdef CONFIG_CMD_NAND
-#include <nand.h>	/* cannot even include nand.h if it isnt configured */
+#include <nand.h>
+#include <nand_interface.h>	/* cannot even include nand.h if it isnt configured */
 #endif
 
 #ifdef CONFIG_BITBANGMII
diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c
index 1df50f1..b08a490 100644
--- a/arch/m68k/lib/board.c
+++ b/arch/m68k/lib/board.c
@@ -68,6 +68,7 @@ 
 #endif
 
 #include <nand.h>
+#include <nand_interface.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
index 4f85bbd..2b722d9 100644
--- a/arch/mips/lib/board.c
+++ b/arch/mips/lib/board.c
@@ -29,6 +29,7 @@ 
 #include <net.h>
 #include <environment.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <onenand_uboot.h>
 #include <spi.h>
 
diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c
index f6c6bc1..1b21814 100644
--- a/arch/nios2/lib/board.c
+++ b/arch/nios2/lib/board.c
@@ -37,7 +37,8 @@ 
 #include <nios2-epcs.h>
 #endif
 #ifdef CONFIG_CMD_NAND
-#include <nand.h>	/* cannot even include nand.h if it isnt configured */
+#include <nand.h>
+#include <nand_interface.h>	/* cannot even include nand.h if it isnt configured */
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index 6aca166..fe65e7f 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -39,6 +39,7 @@ 
 #include "mp.h"
 #ifdef CONFIG_SYS_QE_FW_IN_NAND
 #include <nand.h>
+#include <nand_interface.h>
 #include <errno.h>
 #endif
 
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index 9885b14..bcc1cf2 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -104,6 +104,7 @@  void doc_init (void);
 #endif
 #include <spi.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 static char *failed = "*** failed ***\n";
 
diff --git a/board/BuS/eb_cpux9k2/cpux9k2.c b/board/BuS/eb_cpux9k2/cpux9k2.c
index 856d798..abff1c0 100644
--- a/board/BuS/eb_cpux9k2/cpux9k2.c
+++ b/board/BuS/eb_cpux9k2/cpux9k2.c
@@ -27,6 +27,7 @@ 
 #include <net.h>
 #include <netdev.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c
index b6c7d9e..0dd3eb0 100644
--- a/board/atmel/at91sam9261ek/at91sam9261ek.c
+++ b/board/atmel/at91sam9261ek/at91sam9261ek.c
@@ -212,6 +212,7 @@  static void at91sam9261ek_lcd_hw_init(void)
 
 #ifdef CONFIG_LCD_INFO
 #include <nand.h>
+#include <nand_interface.h>
 #include <version.h>
 
 void lcd_show_board_info(void)
diff --git a/board/atmel/at91sam9263ek/at91sam9263ek.c b/board/atmel/at91sam9263ek/at91sam9263ek.c
index 4d2937d..44f1db6 100644
--- a/board/atmel/at91sam9263ek/at91sam9263ek.c
+++ b/board/atmel/at91sam9263ek/at91sam9263ek.c
@@ -200,6 +200,7 @@  static void at91sam9263ek_lcd_hw_init(void)
 
 #ifdef CONFIG_LCD_INFO
 #include <nand.h>
+#include <nand_interface.h>
 #include <version.h>
 
 #ifndef CONFIG_SYS_NO_FLASH
diff --git a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
index 24a8606..771769b 100644
--- a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
+++ b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
@@ -222,6 +222,7 @@  static void at91sam9m10g45ek_lcd_hw_init(void)
 
 #ifdef CONFIG_LCD_INFO
 #include <nand.h>
+#include <nand_interface.h>
 #include <version.h>
 
 void lcd_show_board_info(void)
diff --git a/board/atmel/at91sam9rlek/at91sam9rlek.c b/board/atmel/at91sam9rlek/at91sam9rlek.c
index e559084..c7b5033 100644
--- a/board/atmel/at91sam9rlek/at91sam9rlek.c
+++ b/board/atmel/at91sam9rlek/at91sam9rlek.c
@@ -150,6 +150,7 @@  static void at91sam9rlek_lcd_hw_init(void)
 
 #ifdef CONFIG_LCD_INFO
 #include <nand.h>
+#include <nand_interface.h>
 #include <version.h>
 
 void lcd_show_board_info(void)
diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c
index 14b61a4..36f88a9 100644
--- a/board/dave/PPChameleonEVB/nand.c
+++ b/board/dave/PPChameleonEVB/nand.c
@@ -26,6 +26,7 @@ 
 #if defined(CONFIG_CMD_NAND)
 
 #include <nand.h>
+#include <nand_interface.h>
 
 /*
  * hardware specific access to control-lines
diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c
index 99432ed..9cec15f 100644
--- a/board/davedenx/qong/qong.c
+++ b/board/davedenx/qong/qong.c
@@ -27,6 +27,7 @@ 
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <fsl_pmic.h>
 #include <asm/gpio.h>
 #include "qong_fpga.h"
diff --git a/board/davinci/da8xxevm/hawkboard_nand_spl.c b/board/davinci/da8xxevm/hawkboard_nand_spl.c
index e5e65e5..bc6e0fd 100644
--- a/board/davinci/da8xxevm/hawkboard_nand_spl.c
+++ b/board/davinci/da8xxevm/hawkboard_nand_spl.c
@@ -29,6 +29,7 @@ 
 #include <asm/arch/davinci_misc.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/davinci/dm355evm/dm355evm.c b/board/davinci/dm355evm/dm355evm.c
index 112851a..ab00cc8 100644
--- a/board/davinci/dm355evm/dm355evm.c
+++ b/board/davinci/dm355evm/dm355evm.c
@@ -18,6 +18,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/emif_defs.h>
diff --git a/board/davinci/dm355leopard/dm355leopard.c b/board/davinci/dm355leopard/dm355leopard.c
index 0ad5678..f1c5c10 100644
--- a/board/davinci/dm355leopard/dm355leopard.c
+++ b/board/davinci/dm355leopard/dm355leopard.c
@@ -18,6 +18,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/gpio.h>
diff --git a/board/davinci/dm365evm/dm365evm.c b/board/davinci/dm365evm/dm365evm.c
index ac54106..50666a6 100644
--- a/board/davinci/dm365evm/dm365evm.c
+++ b/board/davinci/dm365evm/dm365evm.c
@@ -18,6 +18,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/emif_defs.h>
diff --git a/board/davinci/dm6467evm/dm6467evm.c b/board/davinci/dm6467evm/dm6467evm.c
index 1a01c3c..6230c21 100644
--- a/board/davinci/dm6467evm/dm6467evm.c
+++ b/board/davinci/dm6467evm/dm6467evm.c
@@ -20,6 +20,7 @@ 
 #include <netdev.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/arch/nand_defs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/davinci/sonata/sonata.c b/board/davinci/sonata/sonata.c
index c194290..7696646 100644
--- a/board/davinci/sonata/sonata.c
+++ b/board/davinci/sonata/sonata.c
@@ -26,6 +26,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/arch/nand_defs.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/davinci_misc.h>
diff --git a/board/esd/common/esd405ep_nand.c b/board/esd/common/esd405ep_nand.c
index 736176f..cf466b4 100644
--- a/board/esd/common/esd405ep_nand.c
+++ b/board/esd/common/esd405ep_nand.c
@@ -26,6 +26,7 @@ 
 #if defined(CONFIG_CMD_NAND)
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 /*
  * hardware specific access to control-lines
diff --git a/board/freescale/m5329evb/nand.c b/board/freescale/m5329evb/nand.c
index 16025f9..056eca4 100644
--- a/board/freescale/m5329evb/nand.c
+++ b/board/freescale/m5329evb/nand.c
@@ -33,6 +33,7 @@  DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_CMD_NAND)
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/mtd/mtd.h>
 
 #define SET_CLE		0x10
diff --git a/board/freescale/m5373evb/nand.c b/board/freescale/m5373evb/nand.c
index df8c03b..0cd052f 100644
--- a/board/freescale/m5373evb/nand.c
+++ b/board/freescale/m5373evb/nand.c
@@ -33,6 +33,7 @@  DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_CMD_NAND)
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/mtd/mtd.h>
 
 #define SET_CLE		0x10
diff --git a/board/freescale/mpc8313erdb/mpc8313erdb.c b/board/freescale/mpc8313erdb/mpc8313erdb.c
index 08f873d..0bf75a5 100644
--- a/board/freescale/mpc8313erdb/mpc8313erdb.c
+++ b/board/freescale/mpc8313erdb/mpc8313erdb.c
@@ -31,6 +31,7 @@ 
 #include <vsc7385.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/freescale/mpc8315erdb/mpc8315erdb.c b/board/freescale/mpc8315erdb/mpc8315erdb.c
index 5dc558a..3f05326 100644
--- a/board/freescale/mpc8315erdb/mpc8315erdb.c
+++ b/board/freescale/mpc8315erdb/mpc8315erdb.c
@@ -34,6 +34,7 @@ 
 #include <asm/io.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/freescale/mpc8360erdk/nand.c b/board/freescale/mpc8360erdk/nand.c
index 92d56a3..6ac994b 100644
--- a/board/freescale/mpc8360erdk/nand.c
+++ b/board/freescale/mpc8360erdk/nand.c
@@ -17,6 +17,7 @@ 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/fsl_upm.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 static struct immap *im = (struct immap *)CONFIG_SYS_IMMR;
 
diff --git a/board/ids8247/ids8247.c b/board/ids8247/ids8247.c
index d621833..8edb57c 100644
--- a/board/ids8247/ids8247.c
+++ b/board/ids8247/ids8247.c
@@ -309,6 +309,7 @@  int misc_init_r (void)
 
 #if defined(CONFIG_CMD_NAND)
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/mtd/mtd.h>
 #include <asm/io.h>
 
diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c
index a8f2b23..9dbd8c1 100644
--- a/board/keymile/km_arm/km_arm.c
+++ b/board/keymile/km_arm/km_arm.c
@@ -31,6 +31,7 @@ 
 #include <common.h>
 #include <i2c.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <netdev.h>
 #include <miiphy.h>
 #include <asm/io.h>
diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c
index b18c96b..e99a920 100644
--- a/board/prodrive/alpr/nand.c
+++ b/board/prodrive/alpr/nand.c
@@ -30,6 +30,7 @@ 
 
 #include <asm/processor.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 struct alpr_ndfc_regs {
 	u8 cmd[4];
diff --git a/board/prodrive/pdnb3/nand.c b/board/prodrive/pdnb3/nand.c
index 2efe027..470df66 100644
--- a/board/prodrive/pdnb3/nand.c
+++ b/board/prodrive/pdnb3/nand.c
@@ -26,6 +26,7 @@ 
 #if defined(CONFIG_CMD_NAND)
 
 #include <nand.h>
+#include <nand_interface.h>
 
 struct pdnb3_ndfc_regs {
 	uchar cmd;
diff --git a/board/quad100hd/nand.c b/board/quad100hd/nand.c
index a222099..e86aa8a 100644
--- a/board/quad100hd/nand.c
+++ b/board/quad100hd/nand.c
@@ -27,6 +27,7 @@ 
 #include <asm/ppc4xx-gpio.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 /*
  *	hardware specific access to control-lines
diff --git a/board/ronetix/pm9261/pm9261.c b/board/ronetix/pm9261/pm9261.c
index 871b94a..2c96c33 100644
--- a/board/ronetix/pm9261/pm9261.c
+++ b/board/ronetix/pm9261/pm9261.c
@@ -192,6 +192,7 @@  static void pm9261_lcd_hw_init(void)
 
 #ifdef CONFIG_LCD_INFO
 #include <nand.h>
+#include <nand_interface.h>
 #include <version.h>
 
 extern flash_info_t flash_info[];
diff --git a/board/ronetix/pm9263/pm9263.c b/board/ronetix/pm9263/pm9263.c
index cfc9847..3e11152 100644
--- a/board/ronetix/pm9263/pm9263.c
+++ b/board/ronetix/pm9263/pm9263.c
@@ -292,6 +292,7 @@  static void pm9263_lcd_hw_init(void)
 
 #ifdef CONFIG_LCD_INFO
 #include <nand.h>
+#include <nand_interface.h>
 #include <version.h>
 
 extern flash_info_t flash_info[];
diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c
index 62b40f1..0f06b30 100644
--- a/board/sc3/sc3nand.c
+++ b/board/sc3/sc3nand.c
@@ -26,6 +26,7 @@ 
 #if defined(CONFIG_CMD_NAND)
 
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/processor.h>
 
 #define readb(addr)	*(volatile u_char *)(addr)
diff --git a/board/sheldon/simpc8313/simpc8313.c b/board/sheldon/simpc8313/simpc8313.c
index 9126c42..caafdcb 100644
--- a/board/sheldon/simpc8313/simpc8313.c
+++ b/board/sheldon/simpc8313/simpc8313.c
@@ -29,6 +29,7 @@ 
 #include <mpc83xx.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/socrates/nand.c b/board/socrates/nand.c
index 7d76f42..3722e0e 100644
--- a/board/socrates/nand.c
+++ b/board/socrates/nand.c
@@ -25,6 +25,7 @@ 
 
 #if defined(CONFIG_SYS_NAND_BASE)
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 
diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c
index 60ee544..14f96fc 100644
--- a/board/spear/spear300/spear300.c
+++ b/board/spear/spear300/spear300.c
@@ -23,6 +23,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index 03dfe16..ea160bd 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
@@ -24,6 +24,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index 2ba2dbb..be65c12 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
@@ -24,6 +24,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c
index eef9a37..a6ad096 100644
--- a/board/spear/spear600/spear600.c
+++ b/board/spear/spear600/spear600.c
@@ -23,6 +23,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/spr_defs.h>
diff --git a/board/tqc/tqm8272/nand.c b/board/tqc/tqm8272/nand.c
index 8c8341b..f771d2a 100644
--- a/board/tqc/tqm8272/nand.c
+++ b/board/tqc/tqm8272/nand.c
@@ -134,6 +134,7 @@  static int	chipsel = 0;
 #if defined(CONFIG_CMD_NAND)
 
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/mtd/mtd.h>
 
 static u8 hwctl = 0;
diff --git a/board/tqc/tqm85xx/nand.c b/board/tqc/tqm85xx/nand.c
index 4b16c31..da137be 100644
--- a/board/tqc/tqm85xx/nand.c
+++ b/board/tqc/tqm85xx/nand.c
@@ -35,6 +35,7 @@ 
 #include <ioports.h>
 
 #include <nand.h>
+#include <nand_interface.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/ve8313/ve8313.c b/board/ve8313/ve8313.c
index 166e459..c611c14 100644
--- a/board/ve8313/ve8313.c
+++ b/board/ve8313/ve8313.c
@@ -31,6 +31,7 @@ 
 #include <mpc83xx.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
diff --git a/board/xes/common/actl_nand.c b/board/xes/common/actl_nand.c
index 465aeb0..2a3467b 100644
--- a/board/xes/common/actl_nand.c
+++ b/board/xes/common/actl_nand.c
@@ -25,6 +25,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 
 /*
diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c
index 27296dd..b4f0f15 100644
--- a/common/cmd_jffs2.c
+++ b/common/cmd_jffs2.c
@@ -98,6 +98,7 @@ 
 #if defined(CONFIG_CMD_NAND)
 #include <linux/mtd/nand.h>
 #include <nand.h>
+#include <nand_interface.h>
 #endif
 
 #if defined(CONFIG_CMD_ONENAND)
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 5481c88..ed7171b 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -99,6 +99,7 @@ 
 #if defined(CONFIG_CMD_NAND)
 #include <linux/mtd/nand.h>
 #include <nand.h>
+#include <nand_interface.h>
 #endif
 
 #if defined(CONFIG_CMD_ONENAND)
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 66e06a5..cca8754 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -27,6 +27,7 @@ 
 #include <asm/byteorder.h>
 #include <jffs2/jffs2.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 #if defined(CONFIG_CMD_MTDPARTS)
 
diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c
index 629758f..09aceee 100644
--- a/common/cmd_ubi.c
+++ b/common/cmd_ubi.c
@@ -16,6 +16,7 @@ 
 #include <exports.h>
 
 #include <nand.h>
+#include <nand_interface.h>
 #include <onenand_uboot.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
diff --git a/common/env_nand.c b/common/env_nand.c
index 14446a6..2197431 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -38,6 +38,7 @@ 
 #include <linux/stddef.h>
 #include <malloc.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <search.h>
 #include <errno.h>
 
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 818d362..4a1eab2 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -30,6 +30,7 @@ 
 #include <asm/arch/at91_pio.h>
 
 #include <nand.h>
+#include <nand_interface.h>
 
 #ifdef CONFIG_ATMEL_NAND_HWECC
 
diff --git a/drivers/mtd/nand/bfin_nand.c b/drivers/mtd/nand/bfin_nand.c
index 3ee060f..8623eef 100644
--- a/drivers/mtd/nand/bfin_nand.c
+++ b/drivers/mtd/nand/bfin_nand.c
@@ -24,6 +24,7 @@ 
 #endif
 
 #include <nand.h>
+#include <nand_interface.h>
 
 #include <asm/blackfin.h>
 #include <asm/portmux.h>
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index d41579c..a4ba354 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -44,6 +44,7 @@ 
 #include <common.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/arch/nand_defs.h>
 #include <asm/arch/emif_defs.h>
 
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index c33e278..8a99269 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -17,6 +17,7 @@ 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/fsl_upm.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 static void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset)
 {
diff --git a/drivers/mtd/nand/kb9202_nand.c b/drivers/mtd/nand/kb9202_nand.c
index b8f46fa..7a48cd5 100644
--- a/drivers/mtd/nand/kb9202_nand.c
+++ b/drivers/mtd/nand/kb9202_nand.c
@@ -30,6 +30,7 @@ 
 #include <asm/arch/hardware.h>
 
 #include <nand.h>
+#include <nand_interface.h>
 
 /*
  *      hardware specific access to control-lines
diff --git a/drivers/mtd/nand/kirkwood_nand.c b/drivers/mtd/nand/kirkwood_nand.c
index 376378e..aad3a41 100644
--- a/drivers/mtd/nand/kirkwood_nand.c
+++ b/drivers/mtd/nand/kirkwood_nand.c
@@ -26,6 +26,7 @@ 
 #include <asm/io.h>
 #include <asm/arch/kirkwood.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 /* NAND Flash Soc registers */
 struct kwnandf_registers {
diff --git a/drivers/mtd/nand/kmeter1_nand.c b/drivers/mtd/nand/kmeter1_nand.c
index e8e5b7b..5bd6ff5 100644
--- a/drivers/mtd/nand/kmeter1_nand.c
+++ b/drivers/mtd/nand/kmeter1_nand.c
@@ -23,6 +23,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 
 #define CONFIG_NAND_MODE_REG	(void *)(CONFIG_SYS_NAND_BASE + 0x20000)
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c
index 7fd8a35..11a419c 100644
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ b/drivers/mtd/nand/mpc5121_nfc.c
@@ -35,6 +35,7 @@ 
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 #define DRV_NAME		"mpc5121_nfc"
 
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 2a8dd7e..d70bcb5 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -20,6 +20,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/err.h>
 #include <asm/io.h>
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35)
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index d987f4c..82675a6 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -23,6 +23,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 #ifndef CONFIG_SYS_NAND_BASE_LIST
 #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e7dfcb1..3fe0935 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -51,6 +51,8 @@ 
 #include <asm/io.h>
 #include <asm/errno.h>
 
+#include <nand_base.h>
+
 /*
  * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting
  * a flash.  NAND flash is initialized prior to interrupts so standard timers
@@ -63,7 +65,7 @@ 
 #endif
 
 /* Define default oob placement schemes for large and small page devices */
-static struct nand_ecclayout nand_oob_8 = {
+struct nand_ecclayout nand_oob_8 = {
 	.eccbytes = 3,
 	.eccpos = {0, 1, 2},
 	.oobfree = {
@@ -73,7 +75,7 @@  static struct nand_ecclayout nand_oob_8 = {
 		 .length = 2}}
 };
 
-static struct nand_ecclayout nand_oob_16 = {
+struct nand_ecclayout nand_oob_16 = {
 	.eccbytes = 6,
 	.eccpos = {0, 1, 2, 3, 6, 7},
 	.oobfree = {
@@ -81,7 +83,7 @@  static struct nand_ecclayout nand_oob_16 = {
 		 . length = 8}}
 };
 
-static struct nand_ecclayout nand_oob_64 = {
+struct nand_ecclayout nand_oob_64 = {
 	.eccbytes = 24,
 	.eccpos = {
 		   40, 41, 42, 43, 44, 45, 46, 47,
@@ -92,7 +94,7 @@  static struct nand_ecclayout nand_oob_64 = {
 		 .length = 38}}
 };
 
-static struct nand_ecclayout nand_oob_128 = {
+struct nand_ecclayout nand_oob_128 = {
 	.eccbytes = 48,
 	.eccpos = {
 		    80,  81,  82,  83,	84,  85,  86,  87,
@@ -107,13 +109,13 @@  static struct nand_ecclayout nand_oob_128 = {
 };
 
 
-static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
+int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
 			   int new_state);
 
-static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
+int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops);
 
-static int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
+int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
 
 /**
  * nand_release_device - [GENERIC] release chip
@@ -121,7 +123,7 @@  static int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
  *
  * Deselect, release chip lock and wake up anyone waiting on the device
  */
-static void nand_release_device (struct mtd_info *mtd)
+void nand_release_device (struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
 	this->select_chip(mtd, -1);	/* De-select the NAND device */
@@ -133,7 +135,7 @@  static void nand_release_device (struct mtd_info *mtd)
  *
  * Default read function for 8bit buswith
  */
-static uint8_t nand_read_byte(struct mtd_info *mtd)
+uint8_t nand_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
 	return readb(chip->IO_ADDR_R);
@@ -146,7 +148,7 @@  static uint8_t nand_read_byte(struct mtd_info *mtd)
  * Default read function for 16bit buswith with
  * endianess conversion
  */
-static uint8_t nand_read_byte16(struct mtd_info *mtd)
+uint8_t nand_read_byte16(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
 	return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
@@ -159,7 +161,7 @@  static uint8_t nand_read_byte16(struct mtd_info *mtd)
  * Default read function for 16bit buswith without
  * endianess conversion
  */
-static u16 nand_read_word(struct mtd_info *mtd)
+u16 nand_read_word(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
 	return readw(chip->IO_ADDR_R);
@@ -172,7 +174,7 @@  static u16 nand_read_word(struct mtd_info *mtd)
  *
  * Default select function for 1 chip devices.
  */
-static void nand_select_chip(struct mtd_info *mtd, int chipnr)
+void nand_select_chip(struct mtd_info *mtd, int chipnr)
 {
 	struct nand_chip *chip = mtd->priv;
 
@@ -196,7 +198,7 @@  static void nand_select_chip(struct mtd_info *mtd, int chipnr)
  *
  * Default write function for 8bit buswith
  */
-static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
@@ -230,7 +232,7 @@  void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
  *
  * Default verify function for 8bit buswith
  */
-static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
@@ -249,7 +251,7 @@  static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
  *
  * Default write function for 16bit buswith
  */
-static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
@@ -288,7 +290,7 @@  void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
  *
  * Default verify function for 16bit buswith
  */
-static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
@@ -310,7 +312,7 @@  static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
  *
  * Check, if the block is bad.
  */
-static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 {
 	int page, chipnr, res = 0;
 	struct nand_chip *chip = mtd->priv;
@@ -355,7 +357,7 @@  static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
  * This is the default implementation, which can be overridden by
  * a hardware specific driver.
 */
-static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
+int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
 	struct nand_chip *chip = mtd->priv;
 	uint8_t buf[2] = { 0, 0 };
@@ -396,7 +398,7 @@  static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
  *
  * The function expects, that the device is already selected
  */
-static int nand_check_wp(struct mtd_info *mtd)
+int nand_check_wp(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
 	/* Check the WP bit */
@@ -414,7 +416,7 @@  static int nand_check_wp(struct mtd_info *mtd)
  * Check, if the block is bad. Either by reading the bad block table or
  * calling of the scan function.
  */
-static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
+int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
 			       int allowbbt)
 {
 	struct nand_chip *chip = mtd->priv;
@@ -461,7 +463,7 @@  void nand_wait_ready(struct mtd_info *mtd)
  * Send command to NAND device. This function is used for small page
  * devices (256/512 Bytes per page)
  */
-static void nand_command(struct mtd_info *mtd, unsigned int command,
+void nand_command(struct mtd_info *mtd, unsigned int command,
 			 int column, int page_addr)
 {
 	register struct nand_chip *chip = mtd->priv;
@@ -566,8 +568,8 @@  static void nand_command(struct mtd_info *mtd, unsigned int command,
  * devices We dont have the separate regions as we have in the small page
  * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
  */
-static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
-			    int column, int page_addr)
+void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column,
+	int page_addr)
 {
 	register struct nand_chip *chip = mtd->priv;
 	uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
@@ -686,7 +688,7 @@  static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
  *
  * Get the device and lock it for exclusive access
  */
-static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
+int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
 {
 	this->state = new_state;
 	return 0;
@@ -701,7 +703,7 @@  static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int ne
  * Erase can take up to 400ms and program up to 20ms according to
  * general NAND and SmartMedia specs
  */
-static int nand_wait(struct mtd_info *mtd, struct nand_chip *this)
+int nand_wait(struct mtd_info *mtd, struct nand_chip *this)
 {
 	unsigned long	timeo;
 	int state = this->state;
@@ -751,7 +753,7 @@  static int nand_wait(struct mtd_info *mtd, struct nand_chip *this)
  *
  * Not for syndrome calculating ecc controllers, which use a special oob layout
  */
-static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 			      uint8_t *buf, int page)
 {
 	chip->read_buf(mtd, buf, mtd->writesize);
@@ -768,7 +770,7 @@  static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  *
  * We need a special oob layout and handling even when OOB isn't used.
  */
-static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 			      uint8_t *buf, int page)
 {
 	int eccsize = chip->ecc.size;
@@ -808,7 +810,7 @@  static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *c
  * @buf:	buffer to store read data
  * @page:	page number to read
  */
-static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 				uint8_t *buf, int page)
 {
 	int i, eccsize = chip->ecc.size;
@@ -850,7 +852,8 @@  static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @readlen:	data length
  * @bufpoi:	buffer to store read data
  */
-static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
+int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
 {
 	int start_step, end_step, num_steps;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -932,7 +935,7 @@  static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
  *
  * Not for syndrome calculating ecc controllers which need a special oob layout
  */
-static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 				uint8_t *buf, int page)
 {
 	int i, eccsize = chip->ecc.size;
@@ -982,7 +985,7 @@  static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  * "infix ECC" scheme and reads/writes ECC from the data area, by
  * overwriting the NAND manufacturer bad block markings.
  */
-static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
+int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	struct nand_chip *chip, uint8_t *buf, int page)
 {
 	int i, eccsize = chip->ecc.size;
@@ -1027,7 +1030,7 @@  static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
  * The hw generator calculates the error syndrome automatically. Therefor
  * we need a special oob layout and handling.
  */
-static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 				   uint8_t *buf, int page)
 {
 	int i, eccsize = chip->ecc.size;
@@ -1079,7 +1082,7 @@  static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  * @ops:	oob ops structure
  * @len:	size of oob to transfer
  */
-static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 				  struct mtd_oob_ops *ops, size_t len)
 {
 	switch(ops->mode) {
@@ -1129,7 +1132,7 @@  static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
  *
  * Internal function. Called with chip held.
  */
-static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
+int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 			    struct mtd_oob_ops *ops)
 {
 	int chipnr, page, realpage, col, bytes, aligned;
@@ -1272,7 +1275,7 @@  static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
  *
  * Get hold of the chip and call nand_do_read
  */
-static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
+int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
 		     size_t *retlen, uint8_t *buf)
 {
 	struct nand_chip *chip = mtd->priv;
@@ -1306,7 +1309,7 @@  static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
  * @page:	page number to read
  * @sndcmd:	flag whether to issue read command or not
  */
-static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 			     int page, int sndcmd)
 {
 	if (sndcmd) {
@@ -1325,7 +1328,7 @@  static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
  * @page:	page number to read
  * @sndcmd:	flag whether to issue read command or not
  */
-static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 				  int page, int sndcmd)
 {
 	uint8_t *buf = chip->oob_poi;
@@ -1362,7 +1365,7 @@  static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip:	nand chip info structure
  * @page:	page number to write
  */
-static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 			      int page)
 {
 	int status = 0;
@@ -1386,7 +1389,7 @@  static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip:	nand chip info structure
  * @page:	page number to write
  */
-static int nand_write_oob_syndrome(struct mtd_info *mtd,
+int nand_write_oob_syndrome(struct mtd_info *mtd,
 				   struct nand_chip *chip, int page)
 {
 	int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
@@ -1446,8 +1449,7 @@  static int nand_write_oob_syndrome(struct mtd_info *mtd,
  *
  * NAND read out-of-band data from the spare area
  */
-static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
-			    struct mtd_oob_ops *ops)
+int nand_do_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
 {
 	int page, realpage, chipnr, sndcmd = 1;
 	struct nand_chip *chip = mtd->priv;
@@ -1540,8 +1542,7 @@  static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
  *
  * NAND read data and/or out-of-band data
  */
-static int nand_read_oob(struct mtd_info *mtd, loff_t from,
-			 struct mtd_oob_ops *ops)
+int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
 {
 	struct nand_chip *chip = mtd->priv;
 	int ret = -ENOTSUPP;
@@ -1586,7 +1587,7 @@  static int nand_read_oob(struct mtd_info *mtd, loff_t from,
  *
  * Not for syndrome calculating ecc controllers, which use a special oob layout
  */
-static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
@@ -1601,7 +1602,7 @@  static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
-static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf)
 {
 	int eccsize = chip->ecc.size;
@@ -1637,7 +1638,7 @@  static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip
  * @chip:	nand chip info structure
  * @buf:	data buffer
  */
-static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 				  const uint8_t *buf)
 {
 	int i, eccsize = chip->ecc.size;
@@ -1663,7 +1664,7 @@  static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip:	nand chip info structure
  * @buf:	data buffer
  */
-static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 				  const uint8_t *buf)
 {
 	int i, eccsize = chip->ecc.size;
@@ -1694,8 +1695,8 @@  static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  * The hw generator calculates the error syndrome automatically. Therefor
  * we need a special oob layout and handling.
  */
-static void nand_write_page_syndrome(struct mtd_info *mtd,
-				    struct nand_chip *chip, const uint8_t *buf)
+void nand_write_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf)
 {
 	int i, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
@@ -1738,7 +1739,7 @@  static void nand_write_page_syndrome(struct mtd_info *mtd,
  * @cached:	cached programming
  * @raw:	use _raw version of write_page
  */
-static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 			   const uint8_t *buf, int page, int cached, int raw)
 {
 	int status;
@@ -1791,7 +1792,7 @@  static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
  * @oob:	oob data buffer
  * @ops:	oob ops structure
  */
-static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
+uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
 				  struct mtd_oob_ops *ops)
 {
 	size_t len = ops->ooblen;
@@ -1844,7 +1845,7 @@  static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
  *
  * NAND write with ECC
  */
-static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
+int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops)
 {
 	int chipnr, realpage, page, blockmask, column;
@@ -1944,7 +1945,7 @@  static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
  *
  * NAND write with ECC
  */
-static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
+int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 			  size_t *retlen, const uint8_t *buf)
 {
 	struct nand_chip *chip = mtd->priv;
@@ -1979,7 +1980,7 @@  static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
  *
  * NAND write out-of-band
  */
-static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
+int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops)
 {
 	int chipnr, page, status, len;
@@ -2057,7 +2058,7 @@  static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
  * @to:		offset to write to
  * @ops:	oob operation description structure
  */
-static int nand_write_oob(struct mtd_info *mtd, loff_t to,
+int nand_write_oob(struct mtd_info *mtd, loff_t to,
 			  struct mtd_oob_ops *ops)
 {
 	struct nand_chip *chip = mtd->priv;
@@ -2101,7 +2102,7 @@  static int nand_write_oob(struct mtd_info *mtd, loff_t to,
  *
  * Standard erase command for NAND chips
  */
-static void single_erase_cmd(struct mtd_info *mtd, int page)
+void single_erase_cmd(struct mtd_info *mtd, int page)
 {
 	struct nand_chip *chip = mtd->priv;
 	/* Send commands to erase a block */
@@ -2117,7 +2118,7 @@  static void single_erase_cmd(struct mtd_info *mtd, int page)
  * AND multi block erase command function
  * Erase 4 consecutive blocks
  */
-static void multi_erase_cmd(struct mtd_info *mtd, int page)
+void multi_erase_cmd(struct mtd_info *mtd, int page)
 {
 	struct nand_chip *chip = mtd->priv;
 	/* Send commands to erase a block */
@@ -2135,7 +2136,7 @@  static void multi_erase_cmd(struct mtd_info *mtd, int page)
  *
  * Erase one ore more blocks
  */
-static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
+int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	return nand_erase_nand(mtd, instr, 0);
 }
@@ -2330,7 +2331,7 @@  int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
  *
  * Sync is actually a wait for chip ready function
  */
-static void nand_sync(struct mtd_info *mtd)
+void nand_sync(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
 
@@ -2347,7 +2348,7 @@  static void nand_sync(struct mtd_info *mtd)
  * @mtd:	MTD device structure
  * @offs:	offset relative to mtd start
  */
-static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
+int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
 	/* Check for invalid offset */
 	if (offs > mtd->size)
@@ -2361,7 +2362,7 @@  static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
  * @mtd:	MTD device structure
  * @ofs:	offset relative to mtd start
  */
-static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
+int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
 	struct nand_chip *chip = mtd->priv;
 	int ret;
@@ -2379,7 +2380,7 @@  static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 /*
  * Set default functions
  */
-static void nand_set_defaults(struct nand_chip *chip, int busw)
+void nand_set_defaults(struct nand_chip *chip, int busw)
 {
 	/* check for proper chip_delay setup, set 20us if not */
 	if (!chip->chip_delay)
@@ -2416,7 +2417,7 @@  static void nand_set_defaults(struct nand_chip *chip, int busw)
 }
 
 #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
-static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
+u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
 {
 	int i;
 
@@ -2432,9 +2433,8 @@  static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
 /*
  * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
  */
-static int nand_flash_detect_onfi(struct mtd_info *mtd,
-					struct nand_chip *chip,
-					int *busw)
+int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+		int *busw)
 {
 	struct nand_onfi_params *p = &chip->onfi_params;
 	int i;
@@ -2494,7 +2494,7 @@  static int nand_flash_detect_onfi(struct mtd_info *mtd,
 	return 1;
 }
 #else
-static inline int nand_flash_detect_onfi(struct mtd_info *mtd,
+inline int nand_flash_detect_onfi(struct mtd_info *mtd,
 					struct nand_chip *chip,
 					int *busw)
 {
@@ -2502,10 +2502,8 @@  static inline int nand_flash_detect_onfi(struct mtd_info *mtd,
 }
 #endif
 
-static void nand_flash_detect_non_onfi(struct mtd_info *mtd,
-					struct nand_chip *chip,
-					const struct nand_flash_dev *type,
-					int *busw)
+void nand_flash_detect_non_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+		const struct nand_flash_dev *type, int *busw)
 {
 	/* Newer devices have all the information in additional id bytes */
 	if (!type->pagesize) {
@@ -2540,7 +2538,7 @@  static void nand_flash_detect_non_onfi(struct mtd_info *mtd,
 /*
  * Get the flash and manufacturer id and lookup if the type is supported
  */
-static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 						  struct nand_chip *chip,
 						  int busw,
 						  int *maf_id, int *dev_id,
diff --git a/drivers/mtd/nand/nand_plat.c b/drivers/mtd/nand/nand_plat.c
index 37a0206..d0e22a4 100644
--- a/drivers/mtd/nand/nand_plat.c
+++ b/drivers/mtd/nand/nand_plat.c
@@ -22,6 +22,7 @@ 
 #endif
 
 #include <nand.h>
+#include <nand_interface.h>
 
 static void plat_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c
index 71491d4..5025491 100644
--- a/drivers/mtd/nand/nand_spl_simple.c
+++ b/drivers/mtd/nand/nand_spl_simple.c
@@ -20,6 +20,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 
 static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 81bf366..d59dc4e 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -48,6 +48,7 @@ 
 #include <asm/errno.h>
 #include <linux/mtd/mtd.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <jffs2/jffs2.h>
 
 typedef struct erase_info erase_info_t;
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 6ebbb5e..510d755 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -31,6 +31,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/mtd/ndfc.h>
 #include <linux/mtd/nand_ecc.h>
 #include <asm/processor.h>
diff --git a/drivers/mtd/nand/nomadik.c b/drivers/mtd/nand/nomadik.c
index b76f4cb..8f7a9da 100644
--- a/drivers/mtd/nand/nomadik.c
+++ b/drivers/mtd/nand/nomadik.c
@@ -23,6 +23,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 
 static inline int parity(int b) /* b is really a byte; returns 0 or ~0 */
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 5bbec48..2cde42b 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -28,6 +28,7 @@ 
 #include <asm/arch/omap_gpmc.h>
 #include <linux/mtd/nand_ecc.h>
 #include <nand.h>
+#include <nand_base.h>
 
 static uint8_t cs;
 static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT;
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c
index 27351fb..8e9c69e 100644
--- a/drivers/mtd/nand/s3c2410_nand.c
+++ b/drivers/mtd/nand/s3c2410_nand.c
@@ -21,6 +21,7 @@ 
 #include <common.h>
 
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/arch/s3c24x0_cpu.h>
 #include <asm/io.h>
 
diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c
index 084e475..c833ecf 100644
--- a/drivers/mtd/nand/s3c64xx.c
+++ b/drivers/mtd/nand/s3c64xx.c
@@ -28,6 +28,7 @@ 
 #include <common.h>
 
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/arch/s3c6400.h>
 
 #include <asm/io.h>
@@ -60,32 +61,6 @@  static void print_oob(const char *header, struct mtd_info *mtd)
 }
 #endif /* S3C_NAND_DEBUG */
 
-#ifdef CONFIG_NAND_SPL
-static u_char nand_read_byte(struct mtd_info *mtd)
-{
-	struct nand_chip *this = mtd->priv;
-	return readb(this->IO_ADDR_R);
-}
-
-static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i = 0; i < len; i++)
-		writeb(buf[i], this->IO_ADDR_W);
-}
-
-static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i = 0; i < len; i++)
-		buf[i] = readb(this->IO_ADDR_R);
-}
-#endif
-
 static void s3c_nand_select_chip(struct mtd_info *mtd, int chip)
 {
 	int ctrl = readl(NFCONT);
diff --git a/drivers/mtd/nand/spr_nand.c b/drivers/mtd/nand/spr_nand.c
index 097d0c6..93d7f84 100644
--- a/drivers/mtd/nand/spr_nand.c
+++ b/drivers/mtd/nand/spr_nand.c
@@ -23,6 +23,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <linux/mtd/nand_ecc.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
index 5ddc2b9..a604265 100644
--- a/fs/jffs2/jffs2_1pass.c
+++ b/fs/jffs2/jffs2_1pass.c
@@ -148,6 +148,7 @@  static struct part_info *current_part;
 #if (defined(CONFIG_JFFS2_NAND) && \
      defined(CONFIG_CMD_NAND) )
 #include <nand.h>
+#include <nand_interface.h>
 /*
  * Support for jffs2 on top of NAND-flash
  *
diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c
index 740f787..084d1a9 100644
--- a/fs/jffs2/jffs2_nand_1pass.c
+++ b/fs/jffs2/jffs2_nand_1pass.c
@@ -7,6 +7,7 @@ 
 #include <jffs2/jffs2.h>
 #include <jffs2/jffs2_1pass.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 #include "jffs2_nand_private.h"
 
diff --git a/include/nand.h b/include/nand.h
index b4140794..09b793e 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -37,34 +37,6 @@  typedef struct mtd_info nand_info_t;
 extern int nand_curr_device;
 extern nand_info_t nand_info[];
 
-static inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)
-{
-	return info->read(info, ofs, *len, (size_t *)len, buf);
-}
-
-static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)
-{
-	return info->write(info, ofs, *len, (size_t *)len, buf);
-}
-
-static inline int nand_block_isbad(nand_info_t *info, loff_t ofs)
-{
-	return info->block_isbad(info, ofs);
-}
-
-static inline int nand_erase(nand_info_t *info, loff_t off, size_t size)
-{
-	struct erase_info instr;
-
-	instr.mtd = info;
-	instr.addr = off;
-	instr.len = size;
-	instr.callback = 0;
-
-	return info->erase(info, &instr);
-}
-
-
 /*****************************************************************************
  * declarations from nand_util.c
  ****************************************************************************/
@@ -135,8 +107,6 @@  int nand_get_lock_status(nand_info_t *meminfo, loff_t offset);
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
 void nand_deselect(void);
 
-void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
-void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
 
 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
 void board_nand_select_device(struct nand_chip *nand, int chip);
@@ -153,4 +123,106 @@  __attribute__((noreturn)) void nand_boot(void);
 					stored as byte number */
 #define ENV_OFFSET_SIZE 8
 int get_nand_env_oob(nand_info_t *nand, unsigned long *result);
+
+/* nand_base.c Standard implementation of nand functions */
+void nand_release_device (struct mtd_info *mtd);
+uint8_t nand_read_byte(struct mtd_info *mtd);
+uint8_t nand_read_byte16(struct mtd_info *mtd);
+u16 nand_read_word(struct mtd_info *mtd);
+void nand_select_chip(struct mtd_info *mtd, int chipnr);
+void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
+int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
+int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
+int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip);
+int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs);
+int nand_check_wp(struct mtd_info *mtd);
+int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
+		int allowbbt);
+void nand_wait_ready(struct mtd_info *mtd);
+void nand_command(struct mtd_info *mtd, unsigned int command, int column,
+		int page_addr);
+void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column,
+		 int page_addr);
+int nand_get_device (struct nand_chip *this, struct mtd_info *mtd,
+		int new_state);
+int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
+int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int page);
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page);
+int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi);
+int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int page);
+int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi);
+int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int page);
+int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page);
+int nand_read_page_syndrome(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page);
+uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+		struct mtd_oob_ops *ops, size_t len);
+int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
+		struct mtd_oob_ops *ops);
+int nand_read(struct mtd_info *mtd, loff_t from, size_t len,i
+		size_t *retlen, uint8_t *buf);
+int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+		int page, int sndcmd);
+int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		int page, int sndcmd);
+int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+		int page);
+int nand_write_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		int page);
+int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+		struct mtd_oob_ops *ops);
+int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
+void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+void nand_write_page_raw_syndrome(struct mtd_info *mtd,
+		struct nand_chip *chip, const uint8_t *buf);
+void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+void nand_write_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf, int page, int cached, int raw);
+uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
+		struct mtd_oob_ops *ops);
+int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
+		struct mtd_oob_ops *ops);
+int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+		const uint8_t *buf);
+int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
+int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
+void single_erase_cmd(struct mtd_info *mtd, int page);
+void multi_erase_cmd(struct mtd_info *mtd, int page);
+int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
+int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+		int allowbbt);
+
+void nand_sync(struct mtd_info *mtd);
+int nand_block_isbad(struct mtd_info *mtd, loff_t offs);
+int nand_block_markbad(struct mtd_info *mtd, loff_t ofs);
+void nand_set_defaults(struct nand_chip *chip, int busw);
+u16 onfi_crc16(u16 crc, u8 const *p, size_t len);
+int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+		int *busw);
+void nand_flash_detect_non_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+		const struct nand_flash_dev *type, int *busw);
+const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+		struct nand_chip *chip, int busw, int *maf_id, int *dev_id,
+		const struct nand_flash_dev *type);
+int nand_scan_ident(struct mtd_info *mtd, int maxchips,
+		const struct nand_flash_dev *table);
+int nand_scan_tail(struct mtd_info *mtd);
+int nand_scan(struct mtd_info *mtd, int maxchips);
+void nand_release(struct mtd_info *mtd);
 #endif
diff --git a/include/nand_base.h b/include/nand_base.h
new file mode 100644
index 0000000..2b70313
--- /dev/null
+++ b/include/nand_base.h
@@ -0,0 +1,127 @@ 
+/*
+ * (C) Copyright 2005
+ * 2N Telekomunikace, a.s. <www.2n.cz>
+ * Ladislav Michl <michl@2n.cz>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _NAND_BASE_H_
+#define _NAND_BASE_H_
+
+/* nand_base.c Standard implementation of nand functions */
+void nand_release_device (struct mtd_info *mtd);
+uint8_t nand_read_byte(struct mtd_info *mtd);
+uint8_t nand_read_byte16(struct mtd_info *mtd);
+u16 nand_read_word(struct mtd_info *mtd);
+void nand_select_chip(struct mtd_info *mtd, int chipnr);
+void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
+int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
+int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
+int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip);
+int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs);
+int nand_check_wp(struct mtd_info *mtd);
+int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
+		int allowbbt);
+void nand_wait_ready(struct mtd_info *mtd);
+void nand_command(struct mtd_info *mtd, unsigned int command, int column,
+		int page_addr);
+void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column,
+		 int page_addr);
+int nand_get_device (struct nand_chip *this, struct mtd_info *mtd,
+		int new_state);
+int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
+int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int page);
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page);
+int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi);
+int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int page);
+int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+		uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi);
+int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int page);
+int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page);
+int nand_read_page_syndrome(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page);
+uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+		struct mtd_oob_ops *ops, size_t len);
+int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
+		struct mtd_oob_ops *ops);
+int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+		int page, int sndcmd);
+int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		int page, int sndcmd);
+int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+		int page);
+int nand_write_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		int page);
+int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+		struct mtd_oob_ops *ops);
+int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
+void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+void nand_write_page_raw_syndrome(struct mtd_info *mtd,
+		struct nand_chip *chip, const uint8_t *buf);
+void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+void nand_write_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf);
+int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+		const uint8_t *buf, int page, int cached, int raw);
+uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
+		struct mtd_oob_ops *ops);
+int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
+		struct mtd_oob_ops *ops);
+int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
+int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
+void single_erase_cmd(struct mtd_info *mtd, int page);
+void multi_erase_cmd(struct mtd_info *mtd, int page);
+int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+		int allowbbt);
+int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, uint8_t *buf);
+int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const uint8_t *buf);
+int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
+void nand_sync(struct mtd_info *mtd);
+int nand_block_isbad(struct mtd_info *mtd, loff_t offs);
+int nand_block_markbad(struct mtd_info *mtd, loff_t ofs);
+void nand_set_defaults(struct nand_chip *chip, int busw);
+u16 onfi_crc16(u16 crc, u8 const *p, size_t len);
+int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+		int *busw);
+void nand_flash_detect_non_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+		const struct nand_flash_dev *type, int *busw);
+const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+		struct nand_chip *chip, int busw, int *maf_id, int *dev_id,
+		const struct nand_flash_dev *type);
+int nand_scan_ident(struct mtd_info *mtd, int maxchips,
+		const struct nand_flash_dev *table);
+int nand_scan_tail(struct mtd_info *mtd);
+int nand_scan(struct mtd_info *mtd, int maxchips);
+void nand_release(struct mtd_info *mtd);
+#endif /* NAND_BASE_H */
diff --git a/include/nand_interface.h b/include/nand_interface.h
new file mode 100644
index 0000000..f5caab3
--- /dev/null
+++ b/include/nand_interface.h
@@ -0,0 +1,32 @@ 
+#ifndef NAND_INTERFACE_H
+#define NAND_INTERFACE_H
+static  inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len,
+		u_char *buf)
+{
+        return info->read(info, ofs, *len, (size_t *)len, buf);
+}
+
+static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len,
+		u_char *buf)
+{
+        return info->write(info, ofs, *len, (size_t *)len, buf);
+}
+
+static inline int nand_block_isbad(nand_info_t *info, loff_t ofs)
+{
+        return info->block_isbad(info, ofs);
+}
+
+static inline int nand_erase(nand_info_t *info, loff_t off,
+		size_t size)
+{
+        struct erase_info instr;
+
+        instr.mtd = info;
+        instr.addr = off;
+        instr.len = size;
+        instr.callback = 0;
+
+        return info->erase(info, &instr);
+}
+#endif /* NAND_INTERFACE_H */
diff --git a/nand_spl/board/freescale/mpc8536ds/nand_boot.c b/nand_spl/board/freescale/mpc8536ds/nand_boot.c
index 5a0a0c7..51d6738 100644
--- a/nand_spl/board/freescale/mpc8536ds/nand_boot.c
+++ b/nand_spl/board/freescale/mpc8536ds/nand_boot.c
@@ -23,6 +23,7 @@ 
 #include <ns16550.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 u32 sysclk_tbl[] = {
 	33333000, 39999600, 49999500, 66666000,
diff --git a/nand_spl/board/freescale/mpc8569mds/nand_boot.c b/nand_spl/board/freescale/mpc8569mds/nand_boot.c
index 047da34..6efbf22 100644
--- a/nand_spl/board/freescale/mpc8569mds/nand_boot.c
+++ b/nand_spl/board/freescale/mpc8569mds/nand_boot.c
@@ -23,6 +23,7 @@ 
 #include <asm/io.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/mmu.h>
 #include <asm/immap_85xx.h>
 #include <asm/fsl_ddr_sdram.h>
diff --git a/nand_spl/board/freescale/mpc8572ds/nand_boot.c b/nand_spl/board/freescale/mpc8572ds/nand_boot.c
index 7ca4d4d..2b785fa 100644
--- a/nand_spl/board/freescale/mpc8572ds/nand_boot.c
+++ b/nand_spl/board/freescale/mpc8572ds/nand_boot.c
@@ -23,6 +23,7 @@ 
 #include <ns16550.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 
 u32 sysclk_tbl[] = {
 	33333000, 39999600, 49999500, 66666000,
diff --git a/nand_spl/board/freescale/p1023rds/nand_boot.c b/nand_spl/board/freescale/p1023rds/nand_boot.c
index 0065c87..9eac83f 100644
--- a/nand_spl/board/freescale/p1023rds/nand_boot.c
+++ b/nand_spl/board/freescale/p1023rds/nand_boot.c
@@ -24,6 +24,7 @@ 
 #include <ns16550.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/fsl_law.h>
 
 /* Fixed sdram init -- doesn't use serial presence detect. */
diff --git a/nand_spl/board/freescale/p1_p2_rdb/nand_boot.c b/nand_spl/board/freescale/p1_p2_rdb/nand_boot.c
index 16a756c..fbfe31e 100644
--- a/nand_spl/board/freescale/p1_p2_rdb/nand_boot.c
+++ b/nand_spl/board/freescale/p1_p2_rdb/nand_boot.c
@@ -23,6 +23,7 @@ 
 #include <asm/io.h>
 #include <ns16550.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/mmu.h>
 #include <asm/immap_85xx.h>
 #include <asm/fsl_ddr_sdram.h>
diff --git a/nand_spl/board/samsung/smdk6400/Makefile b/nand_spl/board/samsung/smdk6400/Makefile
index 2f9c307..32ea116 100644
--- a/nand_spl/board/samsung/smdk6400/Makefile
+++ b/nand_spl/board/samsung/smdk6400/Makefile
@@ -33,12 +33,12 @@  nandobj	:= $(OBJTREE)/nand_spl/
 
 LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds
 LDFLAGS := -T $(nandobj)u-boot.lds -Ttext $(CONFIG_SYS_TEXT_BASE) $(LDFLAGS) \
-	   $(LDFLAGS_FINAL)
+	   $(LDFLAGS_FINAL) -gc-sections
 AFLAGS	+= -DCONFIG_NAND_SPL
-CFLAGS	+= -DCONFIG_NAND_SPL
+CFLAGS	+= -DCONFIG_NAND_SPL -ffunction-sections 
 
 SOBJS	= start.o cpu_init.o lowlevel_init.o
-COBJS	= nand_boot.o nand_ecc.o s3c64xx.o smdk6400_nand_spl.o
+COBJS	= nand_boot.o nand_ecc.o s3c64xx.o smdk6400_nand_spl.o nand_base.o
 
 SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
@@ -98,6 +98,10 @@  $(obj)smdk6400_nand_spl.c:
 	@rm -f $@
 	@ln -s $(TOPDIR)/board/samsung/smdk6400/smdk6400_nand_spl.c $@
 
+$(obj)nand_base.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/drivers/mtd/nand/nand_base.c $@
+
 #########################################################################
 
 $(obj)%.o:	$(obj)%.S
diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c
index 4683c7c..af1235e 100644
--- a/nand_spl/nand_boot.c
+++ b/nand_spl/nand_boot.c
@@ -20,6 +20,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/io.h>
 
 static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c
index d6b0d9b..04e3ded 100644
--- a/nand_spl/nand_boot_fsl_nfc.c
+++ b/nand_spl/nand_boot_fsl_nfc.c
@@ -26,6 +26,7 @@ 
 
 #include <common.h>
 #include <nand.h>
+#include <nand_interface.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
 #include <fsl_nfc.h>