// SPDX-License-Identifier: GPL-2.0-only /* * Overview: * This is the generic MTD driver for NAND flash devices. It should be * capable of working with almost all NAND chips currently available. * * Additional technical information is available on * http://www.linux-mtd.infradead.org/doc/nand.html * * Copyright (C) 2000 Steven J. Hill ([email protected]) * 2002-2006 Thomas Gleixner ([email protected]) * * Credits: * David Woodhouse for adding multichip support * * Aleph One Ltd. and Toby Churchill Ltd. for supporting the * rework for 2K page size chips * * TODO: * Enable cached programming for 2k page size chips * Check, if mtd->ecctype should be set to MTD_ECC_HW * if we have HW ECC support. * BBT table is not serialized, has to be fixed */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/delay.h> #include <linux/errno.h> #include <linux/err.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/mm.h> #include <linux/types.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/nand-ecc-sw-hamming.h> #include <linux/mtd/nand-ecc-sw-bch.h> #include <linux/interrupt.h> #include <linux/bitops.h> #include <linux/io.h> #include <linux/mtd/partitions.h> #include <linux/of.h> #include <linux/gpio/consumer.h> #include "internals.h" static int nand_pairing_dist3_get_info(struct mtd_info *mtd, int page, struct mtd_pairing_info *info) { … } static int nand_pairing_dist3_get_wunit(struct mtd_info *mtd, const struct mtd_pairing_info *info) { … } const struct mtd_pairing_scheme dist3_pairing_scheme = …; static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len) { … } /** * nand_extract_bits - Copy unaligned bits from one buffer to another one * @dst: destination buffer * @dst_off: bit offset at which the writing starts * @src: source buffer * @src_off: bit offset at which the reading starts * @nbits: number of bits to copy from @src to @dst * * Copy bits from one memory region to another (overlap authorized). */ void nand_extract_bits(u8 *dst, unsigned int dst_off, const u8 *src, unsigned int src_off, unsigned int nbits) { … } EXPORT_SYMBOL_GPL(…); /** * nand_select_target() - Select a NAND target (A.K.A. die) * @chip: NAND chip object * @cs: the CS line to select. Note that this CS id is always from the chip * PoV, not the controller one * * Select a NAND target so that further operations executed on @chip go to the * selected NAND target. */ void nand_select_target(struct nand_chip *chip, unsigned int cs) { … } EXPORT_SYMBOL_GPL(…); /** * nand_deselect_target() - Deselect the currently selected target * @chip: NAND chip object * * Deselect the currently selected NAND target. The result of operations * executed on @chip after the target has been deselected is undefined. */ void nand_deselect_target(struct nand_chip *chip) { … } EXPORT_SYMBOL_GPL(…); /** * nand_release_device - [GENERIC] release chip * @chip: NAND chip object * * Release chip lock and wake up anyone waiting on the device. */ static void nand_release_device(struct nand_chip *chip) { … } /** * nand_bbm_get_next_page - Get the next page for bad block markers * @chip: NAND chip object * @page: First page to start checking for bad block marker usage * * Returns an integer that corresponds to the page offset within a block, for * a page that is used to store bad block markers. If no more pages are * available, -EINVAL is returned. */ int nand_bbm_get_next_page(struct nand_chip *chip, int page) { … } /** * nand_block_bad - [DEFAULT] Read bad block marker from the chip * @chip: NAND chip object * @ofs: offset from device start * * Check, if the block is bad. */ static int nand_block_bad(struct nand_chip *chip, loff_t ofs) { … } /** * nand_region_is_secured() - Check if the region is secured * @chip: NAND chip object * @offset: Offset of the region to check * @size: Size of the region to check * * Checks if the region is secured by comparing the offset and size with the * list of secure regions obtained from DT. Returns true if the region is * secured else false. */ static bool nand_region_is_secured(struct nand_chip *chip, loff_t offset, u64 size) { … } static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs) { … } /** * nand_get_device - [GENERIC] Get chip for selected access * @chip: NAND chip structure * * Lock the device and its controller for exclusive access */ static void nand_get_device(struct nand_chip *chip) { … } /** * nand_check_wp - [GENERIC] check if the chip is write protected * @chip: NAND chip object * * Check, if the device is write protected. The function expects, that the * device is already selected. */ static int nand_check_wp(struct nand_chip *chip) { … } /** * nand_fill_oob - [INTERN] Transfer client buffer to oob * @chip: NAND chip object * @oob: oob data buffer * @len: oob data write length * @ops: oob ops structure */ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, struct mtd_oob_ops *ops) { … } /** * nand_do_write_oob - [MTD Interface] NAND write out-of-band * @chip: NAND chip object * @to: offset to write to * @ops: oob operation description structure * * NAND write out-of-band. */ static int nand_do_write_oob(struct nand_chip *chip, loff_t to, struct mtd_oob_ops *ops) { … } /** * nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker * @chip: NAND chip object * @ofs: offset from device start * * This is the default implementation, which can be overridden by a hardware * specific driver. It provides the details for writing a bad block marker to a * block. */ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs) { … } /** * nand_markbad_bbm - mark a block by updating the BBM * @chip: NAND chip object * @ofs: offset of the block to mark bad */ int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs) { … } /** * nand_block_markbad_lowlevel - mark a block bad * @chip: NAND chip object * @ofs: offset from device start * * This function performs the generic NAND bad block marking steps (i.e., bad * block table(s) and/or marker(s)). We only allow the hardware driver to * specify how to write bad block markers to OOB (chip->legacy.block_markbad). * * We try operations in the following order: * * (1) erase the affected block, to allow OOB marker to be written cleanly * (2) write bad block marker to OOB area of affected block (unless flag * NAND_BBT_NO_OOB_BBM is present) * (3) update the BBT * * Note that we retain the first error encountered in (2) or (3), finish the * procedures, and dump the error in the end. */ static int nand_block_markbad_lowlevel(struct nand_chip *chip, loff_t ofs) { … } /** * nand_block_isreserved - [GENERIC] Check if a block is marked reserved. * @mtd: MTD device structure * @ofs: offset from device start * * Check if the block is marked as reserved. */ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) { … } /** * nand_block_checkbad - [GENERIC] Check if a block is marked bad * @chip: NAND chip object * @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 nand_block_checkbad(struct nand_chip *chip, loff_t ofs, int allowbbt) { … } /** * nand_soft_waitrdy - Poll STATUS reg until RDY bit is set to 1 * @chip: NAND chip structure * @timeout_ms: Timeout in ms * * Poll the STATUS register using ->exec_op() until the RDY bit becomes 1. * If that does not happen whitin the specified timeout, -ETIMEDOUT is * returned. * * This helper is intended to be used when the controller does not have access * to the NAND R/B pin. * * Be aware that calling this helper from an ->exec_op() implementation means * ->exec_op() must be re-entrant. * * Return 0 if the NAND chip is ready, a negative error otherwise. */ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) { const struct nand_interface_config *conf; u8 status = 0; int ret; if (!nand_has_exec_op(chip)) return -ENOTSUPP; /* Wait tWB before polling the STATUS reg. */ conf = nand_get_interface_config(chip); ndelay(NAND_COMMON_TIMING_NS(conf, tWB_max)); ret = nand_status_op(chip, NULL); if (ret) return ret; /* * +1 below is necessary because if we are now in the last fraction * of jiffy and msecs_to_jiffies is 1 then we will wait only that * small jiffy fraction - possibly leading to false timeout */ timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1; do { ret = nand_read_data_op(chip, &status, sizeof(status), true, false); if (ret) break; if (status & NAND_STATUS_READY) break; /* * Typical lowest execution time for a tR on most NANDs is 10us, * use this as polling delay before doing something smarter (ie. * deriving a delay from the timeout value, timeout_ms/ratio). */ udelay(10); } while (time_before(jiffies, timeout_ms)); /* * We have to exit READ_STATUS mode in order to read real data on the * bus in case the WAITRDY instruction is preceding a DATA_IN * instruction. */ nand_exit_status_op(chip); if (ret) return ret; return status & NAND_STATUS_READY ? 0 : -ETIMEDOUT; }; EXPORT_SYMBOL_GPL(…); /** * nand_gpio_waitrdy - Poll R/B GPIO pin until ready * @chip: NAND chip structure * @gpiod: GPIO descriptor of R/B pin * @timeout_ms: Timeout in ms * * Poll the R/B GPIO pin until it becomes ready. If that does not happen * whitin the specified timeout, -ETIMEDOUT is returned. * * This helper is intended to be used when the controller has access to the * NAND R/B pin over GPIO. * * Return 0 if the R/B pin indicates chip is ready, a negative error otherwise. */ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod, unsigned long timeout_ms) { /* * Wait until R/B pin indicates chip is ready or timeout occurs. * +1 below is necessary because if we are now in the last fraction * of jiffy and msecs_to_jiffies is 1 then we will wait only that * small jiffy fraction - possibly leading to false timeout. */ timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1; do { if (gpiod_get_value_cansleep(gpiod)) return 0; cond_resched(); } while (time_before(jiffies, timeout_ms)); return gpiod_get_value_cansleep(gpiod) ? 0 : -ETIMEDOUT; }; EXPORT_SYMBOL_GPL(…); /** * panic_nand_wait - [GENERIC] wait until the command is done * @chip: NAND chip structure * @timeo: timeout * * Wait for command done. This is a helper function for nand_wait used when * we are in interrupt context. May happen when in panic and trying to write * an oops through mtdoops. */ void panic_nand_wait(struct nand_chip *chip, unsigned long timeo) { … } static bool nand_supports_get_features(struct nand_chip *chip, int addr) { … } static bool nand_supports_set_features(struct nand_chip *chip, int addr) { … } /** * nand_reset_interface - Reset data interface and timings * @chip: The NAND chip * @chipnr: Internal die id * * Reset the Data interface and timings to ONFI mode 0. * * Returns 0 for success or negative error code otherwise. */ static int nand_reset_interface(struct nand_chip *chip, int chipnr) { … } /** * nand_setup_interface - Setup the best data interface and timings * @chip: The NAND chip * @chipnr: Internal die id * * Configure what has been reported to be the best data interface and NAND * timings supported by the chip and the driver. * * Returns 0 for success or negative error code otherwise. */ static int nand_setup_interface(struct nand_chip *chip, int chipnr) { … } /** * nand_choose_best_sdr_timings - Pick up the best SDR timings that both the * NAND controller and the NAND chip support * @chip: the NAND chip * @iface: the interface configuration (can eventually be updated) * @spec_timings: specific timings, when not fitting the ONFI specification * * If specific timings are provided, use them. Otherwise, retrieve supported * timing modes from ONFI information. */ int nand_choose_best_sdr_timings(struct nand_chip *chip, struct nand_interface_config *iface, struct nand_sdr_timings *spec_timings) { … } /** * nand_choose_best_nvddr_timings - Pick up the best NVDDR timings that both the * NAND controller and the NAND chip support * @chip: the NAND chip * @iface: the interface configuration (can eventually be updated) * @spec_timings: specific timings, when not fitting the ONFI specification * * If specific timings are provided, use them. Otherwise, retrieve supported * timing modes from ONFI information. */ int nand_choose_best_nvddr_timings(struct nand_chip *chip, struct nand_interface_config *iface, struct nand_nvddr_timings *spec_timings) { … } /** * nand_choose_best_timings - Pick up the best NVDDR or SDR timings that both * NAND controller and the NAND chip support * @chip: the NAND chip * @iface: the interface configuration (can eventually be updated) * * If specific timings are provided, use them. Otherwise, retrieve supported * timing modes from ONFI information. */ static int nand_choose_best_timings(struct nand_chip *chip, struct nand_interface_config *iface) { … } /** * nand_choose_interface_config - find the best data interface and timings * @chip: The NAND chip * * Find the best data interface and NAND timings supported by the chip * and the driver. Eventually let the NAND manufacturer driver propose his own * set of timings. * * After this function nand_chip->interface_config is initialized with the best * timing mode available. * * Returns 0 for success or negative error code otherwise. */ static int nand_choose_interface_config(struct nand_chip *chip) { … } /** * nand_fill_column_cycles - fill the column cycles of an address * @chip: The NAND chip * @addrs: Array of address cycles to fill * @offset_in_page: The offset in the page * * Fills the first or the first two bytes of the @addrs field depending * on the NAND bus width and the page size. * * Returns the number of cycles needed to encode the column, or a negative * error code in case one of the arguments is invalid. */ static int nand_fill_column_cycles(struct nand_chip *chip, u8 *addrs, unsigned int offset_in_page) { … } static int nand_sp_exec_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len) { … } static int nand_lp_exec_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len) { … } static unsigned int rawnand_last_page_of_lun(unsigned int pages_per_lun, unsigned int lun) { … } static void rawnand_cap_cont_reads(struct nand_chip *chip) { … } static int nand_lp_exec_cont_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len, bool check_only) { … } static bool rawnand_cont_read_ongoing(struct nand_chip *chip, unsigned int page) { … } /** * nand_read_page_op - Do a READ PAGE operation * @chip: The NAND chip * @page: page to read * @offset_in_page: offset within the page * @buf: buffer used to store the data * @len: length of the buffer * * This function issues a READ PAGE operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len) { … } EXPORT_SYMBOL_GPL(…); /** * nand_read_param_page_op - Do a READ PARAMETER PAGE operation * @chip: The NAND chip * @page: parameter page to read * @buf: buffer used to store the data * @len: length of the buffer * * This function issues a READ PARAMETER PAGE operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf, unsigned int len) { … } /** * nand_change_read_column_op - Do a CHANGE READ COLUMN operation * @chip: The NAND chip * @offset_in_page: offset within the page * @buf: buffer used to store the data * @len: length of the buffer * @force_8bit: force 8-bit bus access * * This function issues a CHANGE READ COLUMN operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_change_read_column_op(struct nand_chip *chip, unsigned int offset_in_page, void *buf, unsigned int len, bool force_8bit) { … } EXPORT_SYMBOL_GPL(…); /** * nand_read_oob_op - Do a READ OOB operation * @chip: The NAND chip * @page: page to read * @offset_in_oob: offset within the OOB area * @buf: buffer used to store the data * @len: length of the buffer * * This function issues a READ OOB operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_read_oob_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_oob, void *buf, unsigned int len) { … } EXPORT_SYMBOL_GPL(…); static int nand_exec_prog_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, const void *buf, unsigned int len, bool prog) { … } /** * nand_prog_page_begin_op - starts a PROG PAGE operation * @chip: The NAND chip * @page: page to write * @offset_in_page: offset within the page * @buf: buffer containing the data to write to the page * @len: length of the buffer * * This function issues the first half of a PROG PAGE operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, const void *buf, unsigned int len) { … } EXPORT_SYMBOL_GPL(…); /** * nand_prog_page_end_op - ends a PROG PAGE operation * @chip: The NAND chip * * This function issues the second half of a PROG PAGE operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_prog_page_end_op(struct nand_chip *chip) { … } EXPORT_SYMBOL_GPL(…); /** * nand_prog_page_op - Do a full PROG PAGE operation * @chip: The NAND chip * @page: page to write * @offset_in_page: offset within the page * @buf: buffer containing the data to write to the page * @len: length of the buffer * * This function issues a full PROG PAGE operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_prog_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, const void *buf, unsigned int len) { … } EXPORT_SYMBOL_GPL(…); /** * nand_change_write_column_op - Do a CHANGE WRITE COLUMN operation * @chip: The NAND chip * @offset_in_page: offset within the page * @buf: buffer containing the data to send to the NAND * @len: length of the buffer * @force_8bit: force 8-bit bus access * * This function issues a CHANGE WRITE COLUMN operation. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_change_write_column_op(struct nand_chip *chip, unsigned int offset_in_page, const void *buf, unsigned int len, bool force_8bit) { … } EXPORT_SYMBOL_GPL(…); /** * nand_readid_op - Do a READID operation * @chip: The NAND chip * @addr: address cycle to pass after the READID command * @buf: buffer used to store the ID * @len: length of the buffer * * This function sends a READID command and reads back the ID returned by the * NAND. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf, unsigned int len) { … } EXPORT_SYMBOL_GPL(…); /** * nand_status_op - Do a STATUS operation * @chip: The NAND chip * @status: out variable to store the NAND status * * This function sends a STATUS command and reads back the status returned by * the NAND. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_status_op(struct nand_chip *chip, u8 *status) { … } EXPORT_SYMBOL_GPL(…); /** * nand_exit_status_op - Exit a STATUS operation * @chip: The NAND chip * * This function sends a READ0 command to cancel the effect of the STATUS * command to avoid reading only the status until a new read command is sent. * * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_exit_status_op(struct nand_chip *chip) { … } EXPORT_SYMBOL_GPL(…); /** * nand_erase_op - Do an erase operation * @chip: The NAND chip * @eraseblock: block to erase * * This function sends an ERASE command and waits for the NAND to be ready * before returning. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock) { … } EXPORT_SYMBOL_GPL(…); /** * nand_set_features_op - Do a SET FEATURES operation * @chip: The NAND chip * @feature: feature id * @data: 4 bytes of data * * This function sends a SET FEATURES command and waits for the NAND to be * ready before returning. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ static int nand_set_features_op(struct nand_chip *chip, u8 feature, const void *data) { … } /** * nand_get_features_op - Do a GET FEATURES operation * @chip: The NAND chip * @feature: feature id * @data: 4 bytes of data * * This function sends a GET FEATURES command and waits for the NAND to be * ready before returning. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ static int nand_get_features_op(struct nand_chip *chip, u8 feature, void *data) { … } static int nand_wait_rdy_op(struct nand_chip *chip, unsigned int timeout_ms, unsigned int delay_ns) { … } /** * nand_reset_op - Do a reset operation * @chip: The NAND chip * * This function sends a RESET command and waits for the NAND to be ready * before returning. * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_reset_op(struct nand_chip *chip) { … } EXPORT_SYMBOL_GPL(…); /** * nand_read_data_op - Read data from the NAND * @chip: The NAND chip * @buf: buffer used to store the data * @len: length of the buffer * @force_8bit: force 8-bit bus access * @check_only: do not actually run the command, only checks if the * controller driver supports it * * This function does a raw data read on the bus. Usually used after launching * another NAND operation like nand_read_page_op(). * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, bool force_8bit, bool check_only) { … } EXPORT_SYMBOL_GPL(…); /** * nand_write_data_op - Write data from the NAND * @chip: The NAND chip * @buf: buffer containing the data to send on the bus * @len: length of the buffer * @force_8bit: force 8-bit bus access * * This function does a raw data write on the bus. Usually used after launching * another NAND operation like nand_write_page_begin_op(). * This function does not select/unselect the CS line. * * Returns 0 on success, a negative error code otherwise. */ int nand_write_data_op(struct nand_chip *chip, const void *buf, unsigned int len, bool force_8bit) { … } EXPORT_SYMBOL_GPL(…); /** * struct nand_op_parser_ctx - Context used by the parser * @instrs: array of all the instructions that must be addressed * @ninstrs: length of the @instrs array * @subop: Sub-operation to be passed to the NAND controller * * This structure is used by the core to split NAND operations into * sub-operations that can be handled by the NAND controller. */ struct nand_op_parser_ctx { … }; /** * nand_op_parser_must_split_instr - Checks if an instruction must be split * @pat: the parser pattern element that matches @instr * @instr: pointer to the instruction to check * @start_offset: this is an in/out parameter. If @instr has already been * split, then @start_offset is the offset from which to start * (either an address cycle or an offset in the data buffer). * Conversely, if the function returns true (ie. instr must be * split), this parameter is updated to point to the first * data/address cycle that has not been taken care of. * * Some NAND controllers are limited and cannot send X address cycles with a * unique operation, or cannot read/write more than Y bytes at the same time. * In this case, split the instruction that does not fit in a single * controller-operation into two or more chunks. * * Returns true if the instruction must be split, false otherwise. * The @start_offset parameter is also updated to the offset at which the next * bundle of instruction must start (if an address or a data instruction). */ static bool nand_op_parser_must_split_instr(const struct nand_op_parser_pattern_elem *pat, const struct nand_op_instr *instr, unsigned int *start_offset) { … } /** * nand_op_parser_match_pat - Checks if a pattern matches the instructions * remaining in the parser context * @pat: the pattern to test * @ctx: the parser context structure to match with the pattern @pat * * Check if @pat matches the set or a sub-set of instructions remaining in @ctx. * Returns true if this is the case, false ortherwise. When true is returned, * @ctx->subop is updated with the set of instructions to be passed to the * controller driver. */ static bool nand_op_parser_match_pat(const struct nand_op_parser_pattern *pat, struct nand_op_parser_ctx *ctx) { … } #if IS_ENABLED(CONFIG_DYNAMIC_DEBUG) || defined(DEBUG) static void nand_op_parser_trace(const struct nand_op_parser_ctx *ctx) { … } #else static void nand_op_parser_trace(const struct nand_op_parser_ctx *ctx) { /* NOP */ } #endif static int nand_op_parser_cmp_ctx(const struct nand_op_parser_ctx *a, const struct nand_op_parser_ctx *b) { … } /** * nand_op_parser_exec_op - exec_op parser * @chip: the NAND chip * @parser: patterns description provided by the controller driver * @op: the NAND operation to address * @check_only: when true, the function only checks if @op can be handled but * does not execute the operation * * Helper function designed to ease integration of NAND controller drivers that * only support a limited set of instruction sequences. The supported sequences * are described in @parser, and the framework takes care of splitting @op into * multiple sub-operations (if required) and pass them back to the ->exec() * callback of the matching pattern if @check_only is set to false. * * NAND controller drivers should call this function from their own ->exec_op() * implementation. * * Returns 0 on success, a negative error code otherwise. A failure can be * caused by an unsupported operation (none of the supported patterns is able * to handle the requested operation), or an error returned by one of the * matching pattern->exec() hook. */ int nand_op_parser_exec_op(struct nand_chip *chip, const struct nand_op_parser *parser, const struct nand_operation *op, bool check_only) { … } EXPORT_SYMBOL_GPL(…); static bool nand_instr_is_data(const struct nand_op_instr *instr) { … } static bool nand_subop_instr_is_valid(const struct nand_subop *subop, unsigned int instr_idx) { … } static unsigned int nand_subop_get_start_off(const struct nand_subop *subop, unsigned int instr_idx) { … } /** * nand_subop_get_addr_start_off - Get the start offset in an address array * @subop: The entire sub-operation * @instr_idx: Index of the instruction inside the sub-operation * * During driver development, one could be tempted to directly use the * ->addr.addrs field of address instructions. This is wrong as address * instructions might be split. * * Given an address instruction, returns the offset of the first cycle to issue. */ unsigned int nand_subop_get_addr_start_off(const struct nand_subop *subop, unsigned int instr_idx) { … } EXPORT_SYMBOL_GPL(…); /** * nand_subop_get_num_addr_cyc - Get the remaining address cycles to assert * @subop: The entire sub-operation * @instr_idx: Index of the instruction inside the sub-operation * * During driver development, one could be tempted to directly use the * ->addr->naddrs field of a data instruction. This is wrong as instructions * might be split. * * Given an address instruction, returns the number of address cycle to issue. */ unsigned int nand_subop_get_num_addr_cyc(const struct nand_subop *subop, unsigned int instr_idx) { … } EXPORT_SYMBOL_GPL(…); /** * nand_subop_get_data_start_off - Get the start offset in a data array * @subop: The entire sub-operation * @instr_idx: Index of the instruction inside the sub-operation * * During driver development, one could be tempted to directly use the * ->data->buf.{in,out} field of data instructions. This is wrong as data * instructions might be split. * * Given a data instruction, returns the offset to start from. */ unsigned int nand_subop_get_data_start_off(const struct nand_subop *subop, unsigned int instr_idx) { … } EXPORT_SYMBOL_GPL(…); /** * nand_subop_get_data_len - Get the number of bytes to retrieve * @subop: The entire sub-operation * @instr_idx: Index of the instruction inside the sub-operation * * During driver development, one could be tempted to directly use the * ->data->len field of a data instruction. This is wrong as data instructions * might be split. * * Returns the length of the chunk of data to send/receive. */ unsigned int nand_subop_get_data_len(const struct nand_subop *subop, unsigned int instr_idx) { … } EXPORT_SYMBOL_GPL(…); /** * nand_reset - Reset and initialize a NAND device * @chip: The NAND chip * @chipnr: Internal die id * * Save the timings data structure, then apply SDR timings mode 0 (see * nand_reset_interface for details), do the reset operation, and apply * back the previous timings. * * Returns 0 on success, a negative error code otherwise. */ int nand_reset(struct nand_chip *chip, int chipnr) { … } EXPORT_SYMBOL_GPL(…); /** * nand_get_features - wrapper to perform a GET_FEATURE * @chip: NAND chip info structure * @addr: feature address * @subfeature_param: the subfeature parameters, a four bytes array * * Returns 0 for success, a negative error otherwise. Returns -ENOTSUPP if the * operation cannot be handled. */ int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param) { … } /** * nand_set_features - wrapper to perform a SET_FEATURE * @chip: NAND chip info structure * @addr: feature address * @subfeature_param: the subfeature parameters, a four bytes array * * Returns 0 for success, a negative error otherwise. Returns -ENOTSUPP if the * operation cannot be handled. */ int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param) { … } /** * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data * @buf: buffer to test * @len: buffer length * @bitflips_threshold: maximum number of bitflips * * Check if a buffer contains only 0xff, which means the underlying region * has been erased and is ready to be programmed. * The bitflips_threshold specify the maximum number of bitflips before * considering the region is not erased. * Note: The logic of this function has been extracted from the memweight * implementation, except that nand_check_erased_buf function exit before * testing the whole buffer if the number of bitflips exceed the * bitflips_threshold value. * * Returns a positive number of bitflips less than or equal to * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the * threshold. */ static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold) { … } /** * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only * 0xff data * @data: data buffer to test * @datalen: data length * @ecc: ECC buffer * @ecclen: ECC length * @extraoob: extra OOB buffer * @extraooblen: extra OOB length * @bitflips_threshold: maximum number of bitflips * * Check if a data buffer and its associated ECC and OOB data contains only * 0xff pattern, which means the underlying region has been erased and is * ready to be programmed. * The bitflips_threshold specify the maximum number of bitflips before * considering the region as not erased. * * Note: * 1/ ECC algorithms are working on pre-defined block sizes which are usually * different from the NAND page size. When fixing bitflips, ECC engines will * report the number of errors per chunk, and the NAND core infrastructure * expect you to return the maximum number of bitflips for the whole page. * This is why you should always use this function on a single chunk and * not on the whole page. After checking each chunk you should update your * max_bitflips value accordingly. * 2/ When checking for bitflips in erased pages you should not only check * the payload data but also their associated ECC data, because a user might * have programmed almost all bits to 1 but a few. In this case, we * shouldn't consider the chunk as erased, and checking ECC bytes prevent * this case. * 3/ The extraoob argument is optional, and should be used if some of your OOB * data are protected by the ECC engine. * It could also be used if you support subpages and want to attach some * extra OOB data to an ECC chunk. * * Returns a positive number of bitflips less than or equal to * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the * threshold. In case of success, the passed buffers are filled with 0xff. */ int nand_check_erased_ecc_chunk(void *data, int datalen, void *ecc, int ecclen, void *extraoob, int extraooblen, int bitflips_threshold) { … } EXPORT_SYMBOL(…); /** * nand_read_page_raw_notsupp - dummy read raw page function * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * Returns -ENOTSUPP unconditionally. */ int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf, int oob_required, int page) { … } /** * nand_read_page_raw - [INTERN] read raw page data without ecc * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * Not for syndrome calculating ECC controllers, which use a special oob layout. */ int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { … } EXPORT_SYMBOL(…); /** * nand_monolithic_read_page_raw - Monolithic page read in raw mode * @chip: NAND chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * This is a raw page read, ie. without any error detection/correction. * Monolithic means we are requesting all the relevant data (main plus * eventually OOB) to be loaded in the NAND cache and sent over the * bus (from the NAND chip to the NAND controller) in a single * operation. This is an alternative to nand_read_page_raw(), which * first reads the main data, and if the OOB data is requested too, * then reads more data on the bus. */ int nand_monolithic_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_required, int page) { … } EXPORT_SYMBOL(…); /** * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * We need a special oob layout and handling even when OOB isn't used. */ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { … } /** * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read */ static int nand_read_page_swecc(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { … } /** * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function * @chip: nand chip info structure * @data_offs: offset of requested data within the page * @readlen: data length * @bufpoi: buffer to store read data * @page: page number to read */ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, int page) { … } /** * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * Not for syndrome calculating ECC controllers which need a special oob layout. */ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { … } /** * nand_read_page_hwecc_oob_first - Hardware ECC page read with ECC * data read from OOB area * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * Hardware ECC for large page chips, which requires the ECC data to be * extracted from the OOB before the actual data is read. */ int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { … } EXPORT_SYMBOL_GPL(…); /** * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read * @chip: nand chip info structure * @buf: buffer to store read data * @oob_required: caller requires OOB data read to chip->oob_poi * @page: page number to read * * The hw generator calculates the error syndrome automatically. Therefore we * need a special oob layout and handling. */ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { … } /** * nand_transfer_oob - [INTERN] Transfer oob to client buffer * @chip: NAND chip object * @oob: oob destination address * @ops: oob ops structure * @len: size of oob to transfer */ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, struct mtd_oob_ops *ops, size_t len) { … } static void rawnand_enable_cont_reads(struct nand_chip *chip, unsigned int page, u32 readlen, int col) { … } static void rawnand_cont_read_skip_first_page(struct nand_chip *chip, unsigned int page) { … } /** * nand_setup_read_retry - [INTERN] Set the READ RETRY mode * @chip: NAND chip object * @retry_mode: the retry mode to use * * Some vendors supply a special command to shift the Vt threshold, to be used * when there are too many bitflips in a page (i.e., ECC error). After setting * a new threshold, the host should retry reading the page. */ static int nand_setup_read_retry(struct nand_chip *chip, int retry_mode) { … } static void nand_wait_readrdy(struct nand_chip *chip) { … } /** * nand_do_read_ops - [INTERN] Read data with ECC * @chip: NAND chip object * @from: offset to read from * @ops: oob ops structure * * Internal function. Called with chip held. */ static int nand_do_read_ops(struct nand_chip *chip, loff_t from, struct mtd_oob_ops *ops) { … } /** * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function * @chip: nand chip info structure * @page: page number to read */ int nand_read_oob_std(struct nand_chip *chip, int page) { … } EXPORT_SYMBOL(…); /** * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC * with syndromes * @chip: nand chip info structure * @page: page number to read */ static int nand_read_oob_syndrome(struct nand_chip *chip, int page) { … } /** * nand_write_oob_std - [REPLACEABLE] the most common OOB data write function * @chip: nand chip info structure * @page: page number to write */ int nand_write_oob_std(struct nand_chip *chip, int page) { … } EXPORT_SYMBOL(…); /** * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC * with syndrome - only for large page flash * @chip: nand chip info structure * @page: page number to write */ static int nand_write_oob_syndrome(struct nand_chip *chip, int page) { … } /** * nand_do_read_oob - [INTERN] NAND read out-of-band * @chip: NAND chip object * @from: offset to read from * @ops: oob operations description structure * * NAND read out-of-band data from the spare area. */ static int nand_do_read_oob(struct nand_chip *chip, loff_t from, struct mtd_oob_ops *ops) { … } /** * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band * @mtd: MTD device structure * @from: offset to read from * @ops: oob operation description structure * * 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) { … } /** * nand_write_page_raw_notsupp - dummy raw page write function * @chip: nand chip info structure * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write * * Returns -ENOTSUPP unconditionally. */ int nand_write_page_raw_notsupp(struct nand_chip *chip, const u8 *buf, int oob_required, int page) { … } /** * nand_write_page_raw - [INTERN] raw page write function * @chip: nand chip info structure * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write * * Not for syndrome calculating ECC controllers, which use a special oob layout. */ int nand_write_page_raw(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { … } EXPORT_SYMBOL(…); /** * nand_monolithic_write_page_raw - Monolithic page write in raw mode * @chip: NAND chip info structure * @buf: data buffer to write * @oob_required: must write chip->oob_poi to OOB * @page: page number to write * * This is a raw page write, ie. without any error detection/correction. * Monolithic means we are requesting all the relevant data (main plus * eventually OOB) to be sent over the bus and effectively programmed * into the NAND chip arrays in a single operation. This is an * alternative to nand_write_page_raw(), which first sends the main * data, then eventually send the OOB data by latching more data * cycles on the NAND bus, and finally sends the program command to * synchronyze the NAND chip cache. */ int nand_monolithic_write_page_raw(struct nand_chip *chip, const u8 *buf, int oob_required, int page) { … } EXPORT_SYMBOL(…); /** * nand_write_page_raw_syndrome - [INTERN] raw page write function * @chip: nand chip info structure * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write * * We need a special oob layout and handling even when ECC isn't checked. */ static int nand_write_page_raw_syndrome(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { … } /** * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function * @chip: nand chip info structure * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write */ static int nand_write_page_swecc(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { … } /** * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function * @chip: nand chip info structure * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write */ static int nand_write_page_hwecc(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { … } /** * nand_write_subpage_hwecc - [REPLACEABLE] hardware ECC based subpage write * @chip: nand chip info structure * @offset: column address of subpage within the page * @data_len: data length * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write */ static int nand_write_subpage_hwecc(struct nand_chip *chip, uint32_t offset, uint32_t data_len, const uint8_t *buf, int oob_required, int page) { … } /** * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write * @chip: nand chip info structure * @buf: data buffer * @oob_required: must write chip->oob_poi to OOB * @page: page number to write * * The hw generator calculates the error syndrome automatically. Therefore we * need a special oob layout and handling. */ static int nand_write_page_syndrome(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { … } /** * nand_write_page - write one page * @chip: NAND chip descriptor * @offset: address offset within the page * @data_len: length of actual data to be written * @buf: the data to write * @oob_required: must write chip->oob_poi to OOB * @page: page number to write * @raw: use _raw version of write_page */ static int nand_write_page(struct nand_chip *chip, uint32_t offset, int data_len, const uint8_t *buf, int oob_required, int page, int raw) { … } #define NOTALIGNED(x) … /** * nand_do_write_ops - [INTERN] NAND write with ECC * @chip: NAND chip object * @to: offset to write to * @ops: oob operations description structure * * NAND write with ECC. */ static int nand_do_write_ops(struct nand_chip *chip, loff_t to, struct mtd_oob_ops *ops) { … } /** * panic_nand_write - [MTD Interface] NAND write with ECC * @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 * * NAND write with ECC. Used when performing writes in interrupt context, this * may for example be called by mtdoops when writing an oops while in panic. */ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf) { … } /** * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band * @mtd: MTD device structure * @to: offset to write to * @ops: oob operation description structure */ static int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { … } /** * nand_erase - [MTD Interface] erase block(s) * @mtd: MTD device structure * @instr: erase instruction * * Erase one ore more blocks. */ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) { … } /** * nand_erase_nand - [INTERN] erase block(s) * @chip: NAND chip object * @instr: erase instruction * @allowbbt: allow erasing the bbt area * * Erase one ore more blocks. */ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, int allowbbt) { … } /** * nand_sync - [MTD Interface] sync * @mtd: MTD device structure * * Sync is actually a wait for chip ready function. */ static void nand_sync(struct mtd_info *mtd) { … } /** * nand_block_isbad - [MTD Interface] Check if block at offset is bad * @mtd: MTD device structure * @offs: offset relative to mtd start */ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) { … } /** * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad * @mtd: MTD device structure * @ofs: offset relative to mtd start */ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) { … } /** * nand_suspend - [MTD Interface] Suspend the NAND flash * @mtd: MTD device structure * * Returns 0 for success or negative error code otherwise. */ static int nand_suspend(struct mtd_info *mtd) { … } /** * nand_resume - [MTD Interface] Resume the NAND flash * @mtd: MTD device structure */ static void nand_resume(struct mtd_info *mtd) { … } /** * nand_shutdown - [MTD Interface] Finish the current NAND operation and * prevent further operations * @mtd: MTD device structure */ static void nand_shutdown(struct mtd_info *mtd) { … } /** * nand_lock - [MTD Interface] Lock the NAND flash * @mtd: MTD device structure * @ofs: offset byte address * @len: number of bytes to lock (must be a multiple of block/page size) */ static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { … } /** * nand_unlock - [MTD Interface] Unlock the NAND flash * @mtd: MTD device structure * @ofs: offset byte address * @len: number of bytes to unlock (must be a multiple of block/page size) */ static int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { … } /* Set default functions */ static void nand_set_defaults(struct nand_chip *chip) { … } /* Sanitize ONFI strings so we can safely print them */ void sanitize_string(uint8_t *s, size_t len) { … } /* * nand_id_has_period - Check if an ID string has a given wraparound period * @id_data: the ID string * @arrlen: the length of the @id_data array * @period: the period of repitition * * Check if an ID string is repeated within a given sequence of bytes at * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a * period of 3). This is a helper function for nand_id_len(). Returns non-zero * if the repetition has a period of @period; otherwise, returns zero. */ static int nand_id_has_period(u8 *id_data, int arrlen, int period) { … } /* * nand_id_len - Get the length of an ID string returned by CMD_READID * @id_data: the ID string * @arrlen: the length of the @id_data array * Returns the length of the ID string, according to known wraparound/trailing * zero patterns. If no pattern exists, returns the length of the array. */ static int nand_id_len(u8 *id_data, int arrlen) { … } /* Extract the bits of per cell from the 3rd byte of the extended ID */ static int nand_get_bits_per_cell(u8 cellinfo) { … } /* * Many new NAND share similar device ID codes, which represent the size of the * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ void nand_decode_ext_id(struct nand_chip *chip) { … } EXPORT_SYMBOL_GPL(…); /* * Old devices have chip data hardcoded in the device ID table. nand_decode_id * decodes a matching ID table entry and assigns the MTD size parameters for * the chip. */ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) { … } /* * Set the bad block marker/indicator (BBM/BBI) patterns according to some * heuristic patterns using various detected parameters (e.g., manufacturer, * page size, cell-type information). */ static void nand_decode_bbm_options(struct nand_chip *chip) { … } static inline bool is_full_id_nand(struct nand_flash_dev *type) { … } static bool find_full_id_nand(struct nand_chip *chip, struct nand_flash_dev *type) { … } /* * Manufacturer detection. Only used when the NAND is not ONFI or JEDEC * compliant and does not have a full-id or legacy-id entry in the nand_ids * table. */ static void nand_manufacturer_detect(struct nand_chip *chip) { … } /* * Manufacturer initialization. This function is called for all NANDs including * ONFI and JEDEC compliant ones. * Manufacturer drivers should put all their specific initialization code in * their ->init() hook. */ static int nand_manufacturer_init(struct nand_chip *chip) { … } /* * Manufacturer cleanup. This function is called for all NANDs including * ONFI and JEDEC compliant ones. * Manufacturer drivers should put all their specific cleanup code in their * ->cleanup() hook. */ static void nand_manufacturer_cleanup(struct nand_chip *chip) { … } static const char * nand_manufacturer_name(const struct nand_manufacturer_desc *manufacturer_desc) { … } static void rawnand_check_data_only_read_support(struct nand_chip *chip) { … } static void rawnand_early_check_supported_ops(struct nand_chip *chip) { … } static void rawnand_check_cont_read_support(struct nand_chip *chip) { … } static void rawnand_late_check_supported_ops(struct nand_chip *chip) { … } /* * Get the flash and manufacturer id and lookup if the type is supported. */ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) { … } static enum nand_ecc_engine_type of_get_rawnand_ecc_engine_type_legacy(struct device_node *np) { … } static enum nand_ecc_placement of_get_rawnand_ecc_placement_legacy(struct device_node *np) { … } static enum nand_ecc_algo of_get_rawnand_ecc_algo_legacy(struct device_node *np) { … } static void of_get_nand_ecc_legacy_user_config(struct nand_chip *chip) { … } static int of_get_nand_bus_width(struct nand_chip *chip) { … } static int of_get_nand_secure_regions(struct nand_chip *chip) { … } /** * rawnand_dt_parse_gpio_cs - Parse the gpio-cs property of a controller * @dev: Device that will be parsed. Also used for managed allocations. * @cs_array: Array of GPIO desc pointers allocated on success * @ncs_array: Number of entries in @cs_array updated on success. * @return 0 on success, an error otherwise. */ int rawnand_dt_parse_gpio_cs(struct device *dev, struct gpio_desc ***cs_array, unsigned int *ncs_array) { … } EXPORT_SYMBOL(…); static int rawnand_dt_init(struct nand_chip *chip) { … } /** * nand_scan_ident - Scan for the NAND device * @chip: NAND chip object * @maxchips: number of chips to scan for * @table: alternative NAND ID table * * This is the first phase of the normal nand_scan() function. It reads the * flash ID and sets up MTD fields accordingly. * * This helper used to be called directly from controller drivers that needed * to tweak some ECC-related parameters before nand_scan_tail(). This separation * prevented dynamic allocations during this phase which was unconvenient and * as been banned for the benefit of the ->init_ecc()/cleanup_ecc() hooks. */ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, struct nand_flash_dev *table) { … } static void nand_scan_ident_cleanup(struct nand_chip *chip) { … } int rawnand_sw_hamming_init(struct nand_chip *chip) { … } EXPORT_SYMBOL(…); int rawnand_sw_hamming_calculate(struct nand_chip *chip, const unsigned char *buf, unsigned char *code) { … } EXPORT_SYMBOL(…); int rawnand_sw_hamming_correct(struct nand_chip *chip, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { … } EXPORT_SYMBOL(…); void rawnand_sw_hamming_cleanup(struct nand_chip *chip) { … } EXPORT_SYMBOL(…); int rawnand_sw_bch_init(struct nand_chip *chip) { … } EXPORT_SYMBOL(…); static int rawnand_sw_bch_calculate(struct nand_chip *chip, const unsigned char *buf, unsigned char *code) { … } int rawnand_sw_bch_correct(struct nand_chip *chip, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { … } EXPORT_SYMBOL(…); void rawnand_sw_bch_cleanup(struct nand_chip *chip) { … } EXPORT_SYMBOL(…); static int nand_set_ecc_on_host_ops(struct nand_chip *chip) { … } static int nand_set_ecc_soft_ops(struct nand_chip *chip) { … } /** * nand_check_ecc_caps - check the sanity of preset ECC settings * @chip: nand chip info structure * @caps: ECC caps info structure * @oobavail: OOB size that the ECC engine can use * * When ECC step size and strength are already set, check if they are supported * by the controller and the calculated ECC bytes fit within the chip's OOB. * On success, the calculated ECC bytes is set. */ static int nand_check_ecc_caps(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail) { … } /** * nand_match_ecc_req - meet the chip's requirement with least ECC bytes * @chip: nand chip info structure * @caps: ECC engine caps info structure * @oobavail: OOB size that the ECC engine can use * * If a chip's ECC requirement is provided, try to meet it with the least * number of ECC bytes (i.e. with the largest number of OOB-free bytes). * On success, the chosen ECC settings are set. */ static int nand_match_ecc_req(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail) { … } /** * nand_maximize_ecc - choose the max ECC strength available * @chip: nand chip info structure * @caps: ECC engine caps info structure * @oobavail: OOB size that the ECC engine can use * * Choose the max ECC strength that is supported on the controller, and can fit * within the chip's OOB. On success, the chosen ECC settings are set. */ static int nand_maximize_ecc(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail) { … } /** * nand_ecc_choose_conf - Set the ECC strength and ECC step size * @chip: nand chip info structure * @caps: ECC engine caps info structure * @oobavail: OOB size that the ECC engine can use * * Choose the ECC configuration according to following logic. * * 1. If both ECC step size and ECC strength are already set (usually by DT) * then check if it is supported by this controller. * 2. If the user provided the nand-ecc-maximize property, then select maximum * ECC strength. * 3. Otherwise, try to match the ECC step size and ECC strength closest * to the chip's requirement. If available OOB size can't fit the chip * requirement then fallback to the maximum ECC step size and ECC strength. * * On success, the chosen ECC settings are set. */ int nand_ecc_choose_conf(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail) { … } EXPORT_SYMBOL_GPL(…); static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos) { … } static int rawnand_markbad(struct nand_device *nand, const struct nand_pos *pos) { … } static bool rawnand_isbad(struct nand_device *nand, const struct nand_pos *pos) { … } static const struct nand_ops rawnand_ops = …; /** * nand_scan_tail - Scan for the NAND device * @chip: NAND chip object * * This is the second phase of the normal nand_scan() function. It fills out * all the uninitialized function pointers with the defaults and scans for a * bad block table if appropriate. */ static int nand_scan_tail(struct nand_chip *chip) { … } static int nand_attach(struct nand_chip *chip) { … } static void nand_detach(struct nand_chip *chip) { … } /** * nand_scan_with_ids - [NAND Interface] Scan for the NAND device * @chip: NAND chip object * @maxchips: number of chips to scan for. * @ids: optional flash IDs table * * This fills out all the uninitialized function pointers with the defaults. * The flash ID is read and the mtd/chip structures are filled with the * appropriate values. */ int nand_scan_with_ids(struct nand_chip *chip, unsigned int maxchips, struct nand_flash_dev *ids) { … } EXPORT_SYMBOL(…); /** * nand_cleanup - [NAND Interface] Free resources held by the NAND device * @chip: NAND chip object */ void nand_cleanup(struct nand_chip *chip) { … } EXPORT_SYMBOL_GPL(…); MODULE_LICENSE(…) …; MODULE_AUTHOR(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …;