// 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(…) …;