linux/drivers/mtd/nand/onenand/onenand_base.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Copyright © 2005-2009 Samsung Electronics
 *  Copyright © 2007 Nokia Corporation
 *
 *  Kyungmin Park <[email protected]>
 *
 *  Credits:
 *	Adrian Hunter <[email protected]>:
 *	auto-placement support, read-while load support, various fixes
 *
 *	Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com>
 *	Flex-OneNAND support
 *	Amul Kumar Saha <amul.saha at samsung.com>
 *	OTP support
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>

#include <asm/io.h>

/*
 * Multiblock erase if number of blocks to erase is 2 or more.
 * Maximum number of blocks for simultaneous erase is 64.
 */
#define MB_ERASE_MIN_BLK_COUNT
#define MB_ERASE_MAX_BLK_COUNT

/* Default Flex-OneNAND boundary and lock respectively */
static int flex_bdry[MAX_DIES * 2] =;

module_param_array();
MODULE_PARM_DESC();

/* Default OneNAND/Flex-OneNAND OTP options*/
static int otp;

module_param(otp, int, 0400);
MODULE_PARM_DESC();

/*
 * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
 * For now, we expose only 64 out of 80 ecc bytes
 */
static int flexonenand_ooblayout_ecc(struct mtd_info *mtd, int section,
				     struct mtd_oob_region *oobregion)
{}

static int flexonenand_ooblayout_free(struct mtd_info *mtd, int section,
				      struct mtd_oob_region *oobregion)
{}

static const struct mtd_ooblayout_ops flexonenand_ooblayout_ops =;

/*
 * onenand_oob_128 - oob info for OneNAND with 4KB page
 *
 * Based on specification:
 * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
 *
 */
static int onenand_ooblayout_128_ecc(struct mtd_info *mtd, int section,
				     struct mtd_oob_region *oobregion)
{}

static int onenand_ooblayout_128_free(struct mtd_info *mtd, int section,
				      struct mtd_oob_region *oobregion)
{}

static const struct mtd_ooblayout_ops onenand_oob_128_ooblayout_ops =;

/*
 * onenand_oob_32_64 - oob info for large (2KB) page
 */
static int onenand_ooblayout_32_64_ecc(struct mtd_info *mtd, int section,
				       struct mtd_oob_region *oobregion)
{}

static int onenand_ooblayout_32_64_free(struct mtd_info *mtd, int section,
					struct mtd_oob_region *oobregion)
{}

static const struct mtd_ooblayout_ops onenand_oob_32_64_ooblayout_ops =;

static const unsigned char ffchars[] =;

/**
 * onenand_readw - [OneNAND Interface] Read OneNAND register
 * @addr:		address to read
 *
 * Read OneNAND register
 */
static unsigned short onenand_readw(void __iomem *addr)
{}

/**
 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
 * @value:		value to write
 * @addr:		address to write
 *
 * Write OneNAND register with value
 */
static void onenand_writew(unsigned short value, void __iomem *addr)
{}

/**
 * onenand_block_address - [DEFAULT] Get block address
 * @this:		onenand chip data structure
 * @block:		the block
 * @return		translated block address if DDP, otherwise same
 *
 * Setup Start Address 1 Register (F100h)
 */
static int onenand_block_address(struct onenand_chip *this, int block)
{}

/**
 * onenand_bufferram_address - [DEFAULT] Get bufferram address
 * @this:		onenand chip data structure
 * @block:		the block
 * @return		set DBS value if DDP, otherwise 0
 *
 * Setup Start Address 2 Register (F101h) for DDP
 */
static int onenand_bufferram_address(struct onenand_chip *this, int block)
{}

/**
 * onenand_page_address - [DEFAULT] Get page address
 * @page:		the page address
 * @sector:	the sector address
 * @return		combined page and sector address
 *
 * Setup Start Address 8 Register (F107h)
 */
static int onenand_page_address(int page, int sector)
{}

/**
 * onenand_buffer_address - [DEFAULT] Get buffer address
 * @dataram1:	DataRAM index
 * @sectors:	the sector address
 * @count:		the number of sectors
 * Return:		the start buffer value
 *
 * Setup Start Buffer Register (F200h)
 */
static int onenand_buffer_address(int dataram1, int sectors, int count)
{}

/**
 * flexonenand_block- For given address return block number
 * @this:         - OneNAND device structure
 * @addr:		- Address for which block number is needed
 */
static unsigned flexonenand_block(struct onenand_chip *this, loff_t addr)
{}

inline unsigned onenand_block(struct onenand_chip *this, loff_t addr)
{}

/**
 * flexonenand_addr - Return address of the block
 * @this:		OneNAND device structure
 * @block:		Block number on Flex-OneNAND
 *
 * Return address of the block
 */
static loff_t flexonenand_addr(struct onenand_chip *this, int block)
{}

loff_t onenand_addr(struct onenand_chip *this, int block)
{}
EXPORT_SYMBOL();

/**
 * onenand_get_density - [DEFAULT] Get OneNAND density
 * @dev_id:	OneNAND device ID
 *
 * Get OneNAND density from device ID
 */
static inline int onenand_get_density(int dev_id)
{}

/**
 * flexonenand_region - [Flex-OneNAND] Return erase region of addr
 * @mtd:		MTD device structure
 * @addr:		address whose erase region needs to be identified
 */
int flexonenand_region(struct mtd_info *mtd, loff_t addr)
{}
EXPORT_SYMBOL();

/**
 * onenand_command - [DEFAULT] Send command to OneNAND device
 * @mtd:		MTD device structure
 * @cmd:		the command to be sent
 * @addr:		offset to read from or write to
 * @len:		number of bytes to read or write
 *
 * Send command to OneNAND device. This function is used for middle/large page
 * devices (1KB/2KB Bytes per page)
 */
static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
{}

/**
 * onenand_read_ecc - return ecc status
 * @this:		onenand chip structure
 */
static inline int onenand_read_ecc(struct onenand_chip *this)
{}

/**
 * onenand_wait - [DEFAULT] wait until the command is done
 * @mtd:		MTD device structure
 * @state:		state to select the max. timeout value
 *
 * Wait for command done. This applies to all OneNAND command
 * Read can take up to 30us, erase up to 2ms and program up to 350us
 * according to general OneNAND specs
 */
static int onenand_wait(struct mtd_info *mtd, int state)
{}

/*
 * onenand_interrupt - [DEFAULT] onenand interrupt handler
 * @irq:		onenand interrupt number
 * @dev_id:	interrupt data
 *
 * complete the work
 */
static irqreturn_t onenand_interrupt(int irq, void *data)
{}

/*
 * onenand_interrupt_wait - [DEFAULT] wait until the command is done
 * @mtd:		MTD device structure
 * @state:		state to select the max. timeout value
 *
 * Wait for command done.
 */
static int onenand_interrupt_wait(struct mtd_info *mtd, int state)
{}

/*
 * onenand_try_interrupt_wait - [DEFAULT] try interrupt wait
 * @mtd:		MTD device structure
 * @state:		state to select the max. timeout value
 *
 * Try interrupt based wait (It is used one-time)
 */
static int onenand_try_interrupt_wait(struct mtd_info *mtd, int state)
{}

/*
 * onenand_setup_wait - [OneNAND Interface] setup onenand wait method
 * @mtd:		MTD device structure
 *
 * There's two method to wait onenand work
 * 1. polling - read interrupt status register
 * 2. interrupt - use the kernel interrupt method
 */
static void onenand_setup_wait(struct mtd_info *mtd)
{}

/**
 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
 * @mtd:		MTD data structure
 * @area:		BufferRAM area
 * @return		offset given area
 *
 * Return BufferRAM offset given area
 */
static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
{}

/**
 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
 * @mtd:		MTD data structure
 * @area:		BufferRAM area
 * @buffer:	the databuffer to put/get data
 * @offset:	offset to read from or write to
 * @count:		number of bytes to read/write
 *
 * Read the BufferRAM area
 */
static int onenand_read_bufferram(struct mtd_info *mtd, int area,
		unsigned char *buffer, int offset, size_t count)
{}

/**
 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
 * @mtd:		MTD data structure
 * @area:		BufferRAM area
 * @buffer:	the databuffer to put/get data
 * @offset:	offset to read from or write to
 * @count:		number of bytes to read/write
 *
 * Read the BufferRAM area with Sync. Burst Mode
 */
static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
		unsigned char *buffer, int offset, size_t count)
{}

/**
 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
 * @mtd:		MTD data structure
 * @area:		BufferRAM area
 * @buffer:	the databuffer to put/get data
 * @offset:	offset to read from or write to
 * @count:		number of bytes to read/write
 *
 * Write the BufferRAM area
 */
static int onenand_write_bufferram(struct mtd_info *mtd, int area,
		const unsigned char *buffer, int offset, size_t count)
{}

/**
 * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
 * @mtd:		MTD data structure
 * @addr:		address to check
 * @return		blockpage address
 *
 * Get blockpage address at 2x program mode
 */
static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
{}

/**
 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
 * @mtd:		MTD data structure
 * @addr:		address to check
 * @return		1 if there are valid data, otherwise 0
 *
 * Check bufferram if there is data we required
 */
static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
{}

/**
 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
 * @mtd:		MTD data structure
 * @addr:		address to update
 * @valid:		valid flag
 *
 * Update BufferRAM information
 */
static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
		int valid)
{}

/**
 * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
 * @mtd:		MTD data structure
 * @addr:		start address to invalidate
 * @len:		length to invalidate
 *
 * Invalidate BufferRAM information
 */
static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
		unsigned int len)
{}

/**
 * onenand_get_device - [GENERIC] Get chip for selected access
 * @mtd:		MTD device structure
 * @new_state:	the state which is requested
 *
 * Get the device and lock it for exclusive access
 */
static int onenand_get_device(struct mtd_info *mtd, int new_state)
{}

/**
 * onenand_release_device - [GENERIC] release chip
 * @mtd:		MTD device structure
 *
 * Deselect, release chip lock and wake up anyone waiting on the device
 */
static void onenand_release_device(struct mtd_info *mtd)
{}

/**
 * onenand_transfer_auto_oob - [INTERN] oob auto-placement transfer
 * @mtd:		MTD device structure
 * @buf:		destination address
 * @column:	oob offset to read from
 * @thislen:	oob length to read
 */
static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
				int thislen)
{}

/**
 * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data
 * @mtd:		MTD device structure
 * @addr:		address to recover
 * @status:	return value from onenand_wait / onenand_bbt_wait
 *
 * MLC NAND Flash cell has paired pages - LSB page and MSB page. LSB page has
 * lower page address and MSB page has higher page address in paired pages.
 * If power off occurs during MSB page program, the paired LSB page data can
 * become corrupt. LSB page recovery read is a way to read LSB page though page
 * data are corrupted. When uncorrectable error occurs as a result of LSB page
 * read after power up, issue LSB page recovery read.
 */
static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
{}

/**
 * onenand_mlc_read_ops_nolock - MLC OneNAND read main and/or out-of-band
 * @mtd:		MTD device structure
 * @from:		offset to read from
 * @ops:		oob operation description structure
 *
 * MLC OneNAND / Flex-OneNAND has 4KB page size and 4KB dataram.
 * So, read-while-load is not present.
 */
static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
				struct mtd_oob_ops *ops)
{}

/**
 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
 * @mtd:		MTD device structure
 * @from:		offset to read from
 * @ops:		oob operation description structure
 *
 * OneNAND read main and/or out-of-band data
 */
static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
				struct mtd_oob_ops *ops)
{}

/**
 * onenand_read_oob_nolock - [MTD Interface] OneNAND read out-of-band
 * @mtd:		MTD device structure
 * @from:		offset to read from
 * @ops:		oob operation description structure
 *
 * OneNAND read out-of-band data from the spare area
 */
static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
			struct mtd_oob_ops *ops)
{}

/**
 * onenand_read_oob - [MTD Interface] Read main and/or out-of-band
 * @mtd:		MTD device structure
 * @from:		offset to read from
 * @ops:		oob operation description structure
 *
 * Read main and/or out-of-band
 */
static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
			    struct mtd_oob_ops *ops)
{}

/**
 * onenand_bbt_wait - [DEFAULT] wait until the command is done
 * @mtd:		MTD device structure
 * @state:		state to select the max. timeout value
 *
 * Wait for command done.
 */
static int onenand_bbt_wait(struct mtd_info *mtd, int state)
{}

/**
 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
 * @mtd:		MTD device structure
 * @from:		offset to read from
 * @ops:		oob operation description structure
 *
 * OneNAND read out-of-band data from the spare area for bbt scan
 */
int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, 
			    struct mtd_oob_ops *ops)
{}

#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
/**
 * onenand_verify_oob - [GENERIC] verify the oob contents after a write
 * @mtd:		MTD device structure
 * @buf:		the databuffer to verify
 * @to:		offset to read from
 */
static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
{}

/**
 * onenand_verify - [GENERIC] verify the chip contents after a write
 * @mtd:          MTD device structure
 * @buf:          the databuffer to verify
 * @addr:         offset to read from
 * @len:          number of bytes to read and compare
 */
static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
{}
#else
#define onenand_verify
#define onenand_verify_oob
#endif

#define NOTALIGNED(x)

static void onenand_panic_wait(struct mtd_info *mtd)
{}

/**
 * onenand_panic_write - [MTD Interface] write buffer to FLASH in a panic context
 * @mtd:		MTD device structure
 * @to:		offset to write to
 * @len:		number of bytes to write
 * @retlen:	pointer to variable to store the number of written bytes
 * @buf:		the data to write
 *
 * Write with ECC
 */
static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
			 size_t *retlen, const u_char *buf)
{}

/**
 * onenand_fill_auto_oob - [INTERN] oob auto-placement transfer
 * @mtd:		MTD device structure
 * @oob_buf:	oob buffer
 * @buf:		source address
 * @column:	oob offset to write to
 * @thislen:	oob length to write
 */
static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
				  const u_char *buf, int column, int thislen)
{}

/**
 * onenand_write_ops_nolock - [OneNAND Interface] write main and/or out-of-band
 * @mtd:		MTD device structure
 * @to:		offset to write to
 * @ops:		oob operation description structure
 *
 * Write main and/or oob with ECC
 */
static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
				struct mtd_oob_ops *ops)
{}


/**
 * onenand_write_oob_nolock - [INTERN] OneNAND write out-of-band
 * @mtd:		MTD device structure
 * @to:			offset to write to
 * @ops:                oob operation description structure
 *
 * OneNAND write out-of-band
 */
static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
				    struct mtd_oob_ops *ops)
{}

/**
 * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
 * @mtd:		MTD device structure
 * @to:			offset to write
 * @ops:		oob operation description structure
 */
static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
			     struct mtd_oob_ops *ops)
{}

/**
 * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
 * @mtd:		MTD device structure
 * @ofs:		offset from device start
 * @allowbbt:	1, if its allowed to access the bbt area
 *
 * Check, if the block is bad. Either by reading the bad block table or
 * calling of the scan function.
 */
static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
{}


static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
					   struct erase_info *instr)
{}

/**
 * onenand_multiblock_erase - [INTERN] erase block(s) using multiblock erase
 * @mtd:		MTD device structure
 * @instr:		erase instruction
 * @block_size:		block size
 *
 * Erase one or more blocks up to 64 block at a time
 */
static int onenand_multiblock_erase(struct mtd_info *mtd,
				    struct erase_info *instr,
				    unsigned int block_size)
{}


/**
 * onenand_block_by_block_erase - [INTERN] erase block(s) using regular erase
 * @mtd:		MTD device structure
 * @instr:		erase instruction
 * @region:	erase region
 * @block_size:	erase block size
 *
 * Erase one or more blocks one block at a time
 */
static int onenand_block_by_block_erase(struct mtd_info *mtd,
					struct erase_info *instr,
					struct mtd_erase_region_info *region,
					unsigned int block_size)
{}

/**
 * onenand_erase - [MTD Interface] erase block(s)
 * @mtd:		MTD device structure
 * @instr:		erase instruction
 *
 * Erase one or more blocks
 */
static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
{}

/**
 * onenand_sync - [MTD Interface] sync
 * @mtd:		MTD device structure
 *
 * Sync is actually a wait for chip ready function
 */
static void onenand_sync(struct mtd_info *mtd)
{}

/**
 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
 * @mtd:		MTD device structure
 * @ofs:		offset relative to mtd start
 *
 * Check whether the block is bad
 */
static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
{}

/**
 * onenand_default_block_markbad - [DEFAULT] mark a block bad
 * @mtd:		MTD device structure
 * @ofs:		offset from device start
 *
 * This is the default implementation, which can be overridden by
 * a hardware specific driver.
 */
static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
{}

/**
 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
 * @mtd:		MTD device structure
 * @ofs:		offset relative to mtd start
 *
 * Mark the block as bad
 */
static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
{}

/**
 * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
 * @mtd:		MTD device structure
 * @ofs:		offset relative to mtd start
 * @len:		number of bytes to lock or unlock
 * @cmd:		lock or unlock command
 *
 * Lock or unlock one or more blocks
 */
static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
{}

/**
 * onenand_lock - [MTD Interface] Lock block(s)
 * @mtd:		MTD device structure
 * @ofs:		offset relative to mtd start
 * @len:		number of bytes to unlock
 *
 * Lock one or more blocks
 */
static int onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{}

/**
 * onenand_unlock - [MTD Interface] Unlock block(s)
 * @mtd:		MTD device structure
 * @ofs:		offset relative to mtd start
 * @len:		number of bytes to unlock
 *
 * Unlock one or more blocks
 */
static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{}

/**
 * onenand_check_lock_status - [OneNAND Interface] Check lock status
 * @this:		onenand chip data structure
 *
 * Check lock status
 */
static int onenand_check_lock_status(struct onenand_chip *this)
{}

/**
 * onenand_unlock_all - [OneNAND Interface] unlock all blocks
 * @mtd:		MTD device structure
 *
 * Unlock all blocks
 */
static void onenand_unlock_all(struct mtd_info *mtd)
{}

#ifdef CONFIG_MTD_ONENAND_OTP

/**
 * onenand_otp_command - Send OTP specific command to OneNAND device
 * @mtd:	 MTD device structure
 * @cmd:	 the command to be sent
 * @addr:	 offset to read from or write to
 * @len:	 number of bytes to read or write
 */
static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr,
				size_t len)
{}

/**
 * onenand_otp_write_oob_nolock - [INTERN] OneNAND write out-of-band, specific to OTP
 * @mtd:		MTD device structure
 * @to:			offset to write to
 * @ops:                oob operation description structure
 *
 * OneNAND write out-of-band only for OTP
 */
static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to,
				    struct mtd_oob_ops *ops)
{}

/* Internal OTP operation */
otp_op_t;

/**
 * do_otp_read - [DEFAULT] Read OTP block area
 * @mtd:		MTD device structure
 * @from:		The offset to read
 * @len:		number of bytes to read
 * @retlen:	pointer to variable to store the number of readbytes
 * @buf:		the databuffer to put/get data
 *
 * Read OTP block area.
 */
static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
		size_t *retlen, u_char *buf)
{}

/**
 * do_otp_write - [DEFAULT] Write OTP block area
 * @mtd:		MTD device structure
 * @to:		The offset to write
 * @len:		number of bytes to write
 * @retlen:	pointer to variable to store the number of write bytes
 * @buf:		the databuffer to put/get data
 *
 * Write OTP block area.
 */
static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
		size_t *retlen, u_char *buf)
{}

/**
 * do_otp_lock - [DEFAULT] Lock OTP block area
 * @mtd:		MTD device structure
 * @from:		The offset to lock
 * @len:		number of bytes to lock
 * @retlen:	pointer to variable to store the number of lock bytes
 * @buf:		the databuffer to put/get data
 *
 * Lock OTP block area.
 */
static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
		size_t *retlen, u_char *buf)
{}

/**
 * onenand_otp_walk - [DEFAULT] Handle OTP operation
 * @mtd:		MTD device structure
 * @from:		The offset to read/write
 * @len:		number of bytes to read/write
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:		the databuffer to put/get data
 * @action:	do given action
 * @mode:		specify user and factory
 *
 * Handle OTP operation.
 */
static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
			size_t *retlen, u_char *buf,
			otp_op_t action, int mode)
{}

/**
 * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
 * @mtd:		MTD device structure
 * @len:		number of bytes to read
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:		the databuffer to put/get data
 *
 * Read factory OTP info.
 */
static int onenand_get_fact_prot_info(struct mtd_info *mtd, size_t len,
				      size_t *retlen, struct otp_info *buf)
{}

/**
 * onenand_read_fact_prot_reg - [MTD Interface] Read factory OTP area
 * @mtd:		MTD device structure
 * @from:		The offset to read
 * @len:		number of bytes to read
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:		the databuffer to put/get data
 *
 * Read factory OTP area.
 */
static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
			size_t len, size_t *retlen, u_char *buf)
{}

/**
 * onenand_get_user_prot_info - [MTD Interface] Read user OTP info
 * @mtd:		MTD device structure
 * @retlen:	pointer to variable to store the number of read bytes
 * @len:		number of bytes to read
 * @buf:		the databuffer to put/get data
 *
 * Read user OTP info.
 */
static int onenand_get_user_prot_info(struct mtd_info *mtd, size_t len,
				      size_t *retlen, struct otp_info *buf)
{}

/**
 * onenand_read_user_prot_reg - [MTD Interface] Read user OTP area
 * @mtd:		MTD device structure
 * @from:		The offset to read
 * @len:		number of bytes to read
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:		the databuffer to put/get data
 *
 * Read user OTP area.
 */
static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
			size_t len, size_t *retlen, u_char *buf)
{}

/**
 * onenand_write_user_prot_reg - [MTD Interface] Write user OTP area
 * @mtd:		MTD device structure
 * @from:		The offset to write
 * @len:		number of bytes to write
 * @retlen:	pointer to variable to store the number of write bytes
 * @buf:		the databuffer to put/get data
 *
 * Write user OTP area.
 */
static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
			size_t len, size_t *retlen, const u_char *buf)
{}

/**
 * onenand_lock_user_prot_reg - [MTD Interface] Lock user OTP area
 * @mtd:		MTD device structure
 * @from:		The offset to lock
 * @len:		number of bytes to unlock
 *
 * Write lock mark on spare area in page 0 in OTP block
 */
static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
			size_t len)
{}

#endif	/* CONFIG_MTD_ONENAND_OTP */

/**
 * onenand_check_features - Check and set OneNAND features
 * @mtd:		MTD data structure
 *
 * Check and set OneNAND features
 * - lock scheme
 * - two plane
 */
static void onenand_check_features(struct mtd_info *mtd)
{}

/**
 * onenand_print_device_info - Print device & version ID
 * @device:        device ID
 * @version:	version ID
 *
 * Print device & version ID
 */
static void onenand_print_device_info(int device, int version)
{}

static const struct onenand_manufacturers onenand_manuf_ids[] =;

/**
 * onenand_check_maf - Check manufacturer ID
 * @manuf:         manufacturer ID
 *
 * Check manufacturer ID
 */
static int onenand_check_maf(int manuf)
{}

/**
 * flexonenand_get_boundary	- Reads the SLC boundary
 * @mtd:		MTD data structure
 */
static int flexonenand_get_boundary(struct mtd_info *mtd)
{}

/**
 * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info
 * 			  boundary[], diesize[], mtd->size, mtd->erasesize
 * @mtd:		- MTD device structure
 */
static void flexonenand_get_size(struct mtd_info *mtd)
{}

/**
 * flexonenand_check_blocks_erased - Check if blocks are erased
 * @mtd:	mtd info structure
 * @start:	first erase block to check
 * @end:	last erase block to check
 *
 * Converting an unerased block from MLC to SLC
 * causes byte values to change. Since both data and its ECC
 * have changed, reads on the block give uncorrectable error.
 * This might lead to the block being detected as bad.
 *
 * Avoid this by ensuring that the block to be converted is
 * erased.
 */
static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end)
{}

/*
 * flexonenand_set_boundary	- Writes the SLC boundary
 */
static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
				    int boundary, int lock)
{}

/**
 * onenand_chip_probe - [OneNAND Interface] The generic chip probe
 * @mtd:		MTD device structure
 *
 * OneNAND detection method:
 *   Compare the values from command with ones from register
 */
static int onenand_chip_probe(struct mtd_info *mtd)
{}

/**
 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
 * @mtd:		MTD device structure
 */
static int onenand_probe(struct mtd_info *mtd)
{}

/**
 * onenand_suspend - [MTD Interface] Suspend the OneNAND flash
 * @mtd:		MTD device structure
 */
static int onenand_suspend(struct mtd_info *mtd)
{}

/**
 * onenand_resume - [MTD Interface] Resume the OneNAND flash
 * @mtd:		MTD device structure
 */
static void onenand_resume(struct mtd_info *mtd)
{}

/**
 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
 * @mtd:		MTD device structure
 * @maxchips:	Number of chips to scan for
 *
 * This fills out all the not initialized function pointers
 * with the defaults.
 * The flash ID is read and the mtd/chip structures are
 * filled with the appropriate values.
 */
int onenand_scan(struct mtd_info *mtd, int maxchips)
{}

/**
 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
 * @mtd:		MTD device structure
 */
void onenand_release(struct mtd_info *mtd)
{}

EXPORT_SYMBOL_GPL();
EXPORT_SYMBOL_GPL();

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();