// SPDX-License-Identifier: GPL-2.0 /* * Based on m25p80.c, by Mike Lavender ([email protected]), with * influence from lart.c (Abraham Van Der Merwe) and mtd_dataflash.c * * Copyright (C) 2005, Intec Automation Inc. * Copyright (C) 2014, Freescale Semiconductor, Inc. */ #include <linux/err.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/math64.h> #include <linux/module.h> #include <linux/mtd/mtd.h> #include <linux/mtd/spi-nor.h> #include <linux/mutex.h> #include <linux/of_platform.h> #include <linux/sched/task_stack.h> #include <linux/sizes.h> #include <linux/slab.h> #include <linux/spi/flash.h> #include "core.h" /* Define max times to check status register before we give up. */ /* * For everything but full-chip erase; probably could be much smaller, but kept * around for safety for now */ #define DEFAULT_READY_WAIT_JIFFIES … /* * For full-chip erase, calibrated to a 2MB flash (M25P16); should be scaled up * for larger flash */ #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES … #define SPI_NOR_MAX_ADDR_NBYTES … #define SPI_NOR_SRST_SLEEP_MIN … #define SPI_NOR_SRST_SLEEP_MAX … /** * spi_nor_get_cmd_ext() - Get the command opcode extension based on the * extension type. * @nor: pointer to a 'struct spi_nor' * @op: pointer to the 'struct spi_mem_op' whose properties * need to be initialized. * * Right now, only "repeat" and "invert" are supported. * * Return: The opcode extension. */ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor, const struct spi_mem_op *op) { … } /** * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem op. * @nor: pointer to a 'struct spi_nor' * @op: pointer to the 'struct spi_mem_op' whose properties * need to be initialized. * @proto: the protocol from which the properties need to be set. */ void spi_nor_spimem_setup_op(const struct spi_nor *nor, struct spi_mem_op *op, const enum spi_nor_protocol proto) { … } /** * spi_nor_spimem_bounce() - check if a bounce buffer is needed for the data * transfer * @nor: pointer to 'struct spi_nor' * @op: pointer to 'struct spi_mem_op' template for transfer * * If we have to use the bounce buffer, the data field in @op will be updated. * * Return: true if the bounce buffer is needed, false if not */ static bool spi_nor_spimem_bounce(struct spi_nor *nor, struct spi_mem_op *op) { … } /** * spi_nor_spimem_exec_op() - execute a memory operation * @nor: pointer to 'struct spi_nor' * @op: pointer to 'struct spi_mem_op' template for transfer * * Return: 0 on success, -error otherwise. */ static int spi_nor_spimem_exec_op(struct spi_nor *nor, struct spi_mem_op *op) { … } int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len) { … } int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, size_t len) { … } static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs) { … } /** * spi_nor_spimem_read_data() - read data from flash's memory region via * spi-mem * @nor: pointer to 'struct spi_nor' * @from: offset to read from * @len: number of bytes to read * @buf: pointer to dst buffer * * Return: number of bytes read successfully, -errno otherwise */ static ssize_t spi_nor_spimem_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf) { … } /** * spi_nor_read_data() - read data from flash memory * @nor: pointer to 'struct spi_nor' * @from: offset to read from * @len: number of bytes to read * @buf: pointer to dst buffer * * Return: number of bytes read successfully, -errno otherwise */ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf) { … } /** * spi_nor_spimem_write_data() - write data to flash memory via * spi-mem * @nor: pointer to 'struct spi_nor' * @to: offset to write to * @len: number of bytes to write * @buf: pointer to src buffer * * Return: number of bytes written successfully, -errno otherwise */ static ssize_t spi_nor_spimem_write_data(struct spi_nor *nor, loff_t to, size_t len, const u8 *buf) { … } /** * spi_nor_write_data() - write data to flash memory * @nor: pointer to 'struct spi_nor' * @to: offset to write to * @len: number of bytes to write * @buf: pointer to src buffer * * Return: number of bytes written successfully, -errno otherwise */ ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, const u8 *buf) { … } /** * spi_nor_read_any_reg() - read any register from flash memory, nonvolatile or * volatile. * @nor: pointer to 'struct spi_nor'. * @op: SPI memory operation. op->data.buf must be DMA-able. * @proto: SPI protocol to use for the register operation. * * Return: zero on success, -errno otherwise */ int spi_nor_read_any_reg(struct spi_nor *nor, struct spi_mem_op *op, enum spi_nor_protocol proto) { … } /** * spi_nor_write_any_volatile_reg() - write any volatile register to flash * memory. * @nor: pointer to 'struct spi_nor' * @op: SPI memory operation. op->data.buf must be DMA-able. * @proto: SPI protocol to use for the register operation. * * Writing volatile registers are instant according to some manufacturers * (Cypress, Micron) and do not need any status polling. * * Return: zero on success, -errno otherwise */ int spi_nor_write_any_volatile_reg(struct spi_nor *nor, struct spi_mem_op *op, enum spi_nor_protocol proto) { … } /** * spi_nor_write_enable() - Set write enable latch with Write Enable command. * @nor: pointer to 'struct spi_nor'. * * Return: 0 on success, -errno otherwise. */ int spi_nor_write_enable(struct spi_nor *nor) { … } /** * spi_nor_write_disable() - Send Write Disable instruction to the chip. * @nor: pointer to 'struct spi_nor'. * * Return: 0 on success, -errno otherwise. */ int spi_nor_write_disable(struct spi_nor *nor) { … } /** * spi_nor_read_id() - Read the JEDEC ID. * @nor: pointer to 'struct spi_nor'. * @naddr: number of address bytes to send. Can be zero if the operation * does not need to send an address. * @ndummy: number of dummy bytes to send after an opcode or address. Can * be zero if the operation does not require dummy bytes. * @id: pointer to a DMA-able buffer where the value of the JEDEC ID * will be written. * @proto: the SPI protocol for register operation. * * Return: 0 on success, -errno otherwise. */ int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id, enum spi_nor_protocol proto) { … } /** * spi_nor_read_sr() - Read the Status Register. * @nor: pointer to 'struct spi_nor'. * @sr: pointer to a DMA-able buffer where the value of the * Status Register will be written. Should be at least 2 bytes. * * Return: 0 on success, -errno otherwise. */ int spi_nor_read_sr(struct spi_nor *nor, u8 *sr) { … } /** * spi_nor_read_cr() - Read the Configuration Register using the * SPINOR_OP_RDCR (35h) command. * @nor: pointer to 'struct spi_nor' * @cr: pointer to a DMA-able buffer where the value of the * Configuration Register will be written. * * Return: 0 on success, -errno otherwise. */ int spi_nor_read_cr(struct spi_nor *nor, u8 *cr) { … } /** * spi_nor_set_4byte_addr_mode_en4b_ex4b() - Enter/Exit 4-byte address mode * using SPINOR_OP_EN4B/SPINOR_OP_EX4B. Typically used by * Winbond and Macronix. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * Return: 0 on success, -errno otherwise. */ int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable) { … } /** * spi_nor_set_4byte_addr_mode_wren_en4b_ex4b() - Set 4-byte address mode using * SPINOR_OP_WREN followed by SPINOR_OP_EN4B or SPINOR_OP_EX4B. Typically used * by ST and Micron flashes. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * Return: 0 on success, -errno otherwise. */ int spi_nor_set_4byte_addr_mode_wren_en4b_ex4b(struct spi_nor *nor, bool enable) { … } /** * spi_nor_set_4byte_addr_mode_brwr() - Set 4-byte address mode using * SPINOR_OP_BRWR. Typically used by Spansion flashes. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is * used to enable/disable 4-byte address mode. When MSB is set to ‘1’, 4-byte * address mode is active and A[30:24] bits are don’t care. Write instruction is * SPINOR_OP_BRWR(17h) with 1 byte of data. * * Return: 0 on success, -errno otherwise. */ int spi_nor_set_4byte_addr_mode_brwr(struct spi_nor *nor, bool enable) { … } /** * spi_nor_sr_ready() - Query the Status Register to see if the flash is ready * for new commands. * @nor: pointer to 'struct spi_nor'. * * Return: 1 if ready, 0 if not ready, -errno on errors. */ int spi_nor_sr_ready(struct spi_nor *nor) { … } /** * spi_nor_use_parallel_locking() - Checks if RWW locking scheme shall be used * @nor: pointer to 'struct spi_nor'. * * Return: true if parallel locking is enabled, false otherwise. */ static bool spi_nor_use_parallel_locking(struct spi_nor *nor) { … } /* Locking helpers for status read operations */ static int spi_nor_rww_start_rdst(struct spi_nor *nor) { … } static void spi_nor_rww_end_rdst(struct spi_nor *nor) { … } static int spi_nor_lock_rdst(struct spi_nor *nor) { … } static void spi_nor_unlock_rdst(struct spi_nor *nor) { … } /** * spi_nor_ready() - Query the flash to see if it is ready for new commands. * @nor: pointer to 'struct spi_nor'. * * Return: 1 if ready, 0 if not ready, -errno on errors. */ static int spi_nor_ready(struct spi_nor *nor) { … } /** * spi_nor_wait_till_ready_with_timeout() - Service routine to read the * Status Register until ready, or timeout occurs. * @nor: pointer to "struct spi_nor". * @timeout_jiffies: jiffies to wait until timeout. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor, unsigned long timeout_jiffies) { … } /** * spi_nor_wait_till_ready() - Wait for a predefined amount of time for the * flash to be ready, or timeout occurs. * @nor: pointer to "struct spi_nor". * * Return: 0 on success, -errno otherwise. */ int spi_nor_wait_till_ready(struct spi_nor *nor) { … } /** * spi_nor_global_block_unlock() - Unlock Global Block Protection. * @nor: pointer to 'struct spi_nor'. * * Return: 0 on success, -errno otherwise. */ int spi_nor_global_block_unlock(struct spi_nor *nor) { … } /** * spi_nor_write_sr() - Write the Status Register. * @nor: pointer to 'struct spi_nor'. * @sr: pointer to DMA-able buffer to write to the Status Register. * @len: number of bytes to write to the Status Register. * * Return: 0 on success, -errno otherwise. */ int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len) { … } /** * spi_nor_write_sr1_and_check() - Write one byte to the Status Register 1 and * ensure that the byte written match the received value. * @nor: pointer to a 'struct spi_nor'. * @sr1: byte value to be written to the Status Register. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_write_sr1_and_check(struct spi_nor *nor, u8 sr1) { … } /** * spi_nor_write_16bit_sr_and_check() - Write the Status Register 1 and the * Status Register 2 in one shot. Ensure that the byte written in the Status * Register 1 match the received value, and that the 16-bit Write did not * affect what was already in the Status Register 2. * @nor: pointer to a 'struct spi_nor'. * @sr1: byte value to be written to the Status Register 1. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1) { … } /** * spi_nor_write_16bit_cr_and_check() - Write the Status Register 1 and the * Configuration Register in one shot. Ensure that the byte written in the * Configuration Register match the received value, and that the 16-bit Write * did not affect what was already in the Status Register 1. * @nor: pointer to a 'struct spi_nor'. * @cr: byte value to be written to the Configuration Register. * * Return: 0 on success, -errno otherwise. */ int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr) { … } /** * spi_nor_write_sr_and_check() - Write the Status Register 1 and ensure that * the byte written match the received value without affecting other bits in the * Status Register 1 and 2. * @nor: pointer to a 'struct spi_nor'. * @sr1: byte value to be written to the Status Register. * * Return: 0 on success, -errno otherwise. */ int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1) { … } /** * spi_nor_write_sr2() - Write the Status Register 2 using the * SPINOR_OP_WRSR2 (3eh) command. * @nor: pointer to 'struct spi_nor'. * @sr2: pointer to DMA-able buffer to write to the Status Register 2. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2) { … } /** * spi_nor_read_sr2() - Read the Status Register 2 using the * SPINOR_OP_RDSR2 (3fh) command. * @nor: pointer to 'struct spi_nor'. * @sr2: pointer to DMA-able buffer where the value of the * Status Register 2 will be written. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2) { … } /** * spi_nor_erase_die() - Erase the entire die. * @nor: pointer to 'struct spi_nor'. * @addr: address of the die. * @die_size: size of the die. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_erase_die(struct spi_nor *nor, loff_t addr, size_t die_size) { … } static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size) { … } u8 spi_nor_convert_3to4_read(u8 opcode) { … } static u8 spi_nor_convert_3to4_program(u8 opcode) { … } static u8 spi_nor_convert_3to4_erase(u8 opcode) { … } static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) { … } static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) { … } static int spi_nor_prep(struct spi_nor *nor) { … } static void spi_nor_unprep(struct spi_nor *nor) { … } static void spi_nor_offset_to_banks(u64 bank_size, loff_t start, size_t len, u8 *first, u8 *last) { … } /* Generic helpers for internal locking and serialization */ static bool spi_nor_rww_start_io(struct spi_nor *nor) { … } static void spi_nor_rww_end_io(struct spi_nor *nor) { … } static int spi_nor_lock_device(struct spi_nor *nor) { … } static void spi_nor_unlock_device(struct spi_nor *nor) { … } /* Generic helpers for internal locking and serialization */ static bool spi_nor_rww_start_exclusive(struct spi_nor *nor) { … } static void spi_nor_rww_end_exclusive(struct spi_nor *nor) { … } int spi_nor_prep_and_lock(struct spi_nor *nor) { … } void spi_nor_unlock_and_unprep(struct spi_nor *nor) { … } /* Internal locking helpers for program and erase operations */ static bool spi_nor_rww_start_pe(struct spi_nor *nor, loff_t start, size_t len) { … } static void spi_nor_rww_end_pe(struct spi_nor *nor, loff_t start, size_t len) { … } static int spi_nor_prep_and_lock_pe(struct spi_nor *nor, loff_t start, size_t len) { … } static void spi_nor_unlock_and_unprep_pe(struct spi_nor *nor, loff_t start, size_t len) { … } /* Internal locking helpers for read operations */ static bool spi_nor_rww_start_rd(struct spi_nor *nor, loff_t start, size_t len) { … } static void spi_nor_rww_end_rd(struct spi_nor *nor, loff_t start, size_t len) { … } static int spi_nor_prep_and_lock_rd(struct spi_nor *nor, loff_t start, size_t len) { … } static void spi_nor_unlock_and_unprep_rd(struct spi_nor *nor, loff_t start, size_t len) { … } /* * Initiate the erasure of a single sector */ int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) { … } /** * spi_nor_div_by_erase_size() - calculate remainder and update new dividend * @erase: pointer to a structure that describes a SPI NOR erase type * @dividend: dividend value * @remainder: pointer to u32 remainder (will be updated) * * Return: the result of the division */ static u64 spi_nor_div_by_erase_size(const struct spi_nor_erase_type *erase, u64 dividend, u32 *remainder) { … } /** * spi_nor_find_best_erase_type() - find the best erase type for the given * offset in the serial flash memory and the * number of bytes to erase. The region in * which the address fits is expected to be * provided. * @map: the erase map of the SPI NOR * @region: pointer to a structure that describes a SPI NOR erase region * @addr: offset in the serial flash memory * @len: number of bytes to erase * * Return: a pointer to the best fitted erase type, NULL otherwise. */ static const struct spi_nor_erase_type * spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map, const struct spi_nor_erase_region *region, u64 addr, u32 len) { … } /** * spi_nor_init_erase_cmd() - initialize an erase command * @region: pointer to a structure that describes a SPI NOR erase region * @erase: pointer to a structure that describes a SPI NOR erase type * * Return: the pointer to the allocated erase command, ERR_PTR(-errno) * otherwise. */ static struct spi_nor_erase_command * spi_nor_init_erase_cmd(const struct spi_nor_erase_region *region, const struct spi_nor_erase_type *erase) { … } /** * spi_nor_destroy_erase_cmd_list() - destroy erase command list * @erase_list: list of erase commands */ static void spi_nor_destroy_erase_cmd_list(struct list_head *erase_list) { … } /** * spi_nor_init_erase_cmd_list() - initialize erase command list * @nor: pointer to a 'struct spi_nor' * @erase_list: list of erase commands to be executed once we validate that the * erase can be performed * @addr: offset in the serial flash memory * @len: number of bytes to erase * * Builds the list of best fitted erase commands and verifies if the erase can * be performed. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor, struct list_head *erase_list, u64 addr, u32 len) { … } /** * spi_nor_erase_multi_sectors() - perform a non-uniform erase * @nor: pointer to a 'struct spi_nor' * @addr: offset in the serial flash memory * @len: number of bytes to erase * * Build a list of best fitted erase commands and execute it once we validate * that the erase can be performed. * * Return: 0 on success, -errno otherwise. */ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len) { … } static int spi_nor_erase_dice(struct spi_nor *nor, loff_t addr, size_t len, size_t die_size) { … } /* * Erase an address range on the nor chip. The address range may extend * one or more erase sectors. Return an error if there is a problem erasing. */ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) { … } /** * spi_nor_sr1_bit6_quad_enable() - Set the Quad Enable BIT(6) in the Status * Register 1. * @nor: pointer to a 'struct spi_nor' * * Bit 6 of the Status Register 1 is the QE bit for Macronix like QSPI memories. * * Return: 0 on success, -errno otherwise. */ int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor) { … } /** * spi_nor_sr2_bit1_quad_enable() - set the Quad Enable BIT(1) in the Status * Register 2. * @nor: pointer to a 'struct spi_nor'. * * Bit 1 of the Status Register 2 is the QE bit for Spansion like QSPI memories. * * Return: 0 on success, -errno otherwise. */ int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor) { … } /** * spi_nor_sr2_bit7_quad_enable() - set QE bit in Status Register 2. * @nor: pointer to a 'struct spi_nor' * * Set the Quad Enable (QE) bit in the Status Register 2. * * This is one of the procedures to set the QE bit described in the SFDP * (JESD216 rev B) specification but no manufacturer using this procedure has * been identified yet, hence the name of the function. * * Return: 0 on success, -errno otherwise. */ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor) { … } static const struct spi_nor_manufacturer *manufacturers[] = …; static const struct flash_info spi_nor_generic_flash = …; static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, const u8 *id) { … } static const struct flash_info *spi_nor_detect(struct spi_nor *nor) { … } static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { … } /* * Write an address range to the nor chip. Data must be written in * FLASH_PAGESIZE chunks. The address range may be any size provided * it is within the physical boundaries. */ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { … } static int spi_nor_check(struct spi_nor *nor) { … } void spi_nor_set_read_settings(struct spi_nor_read_command *read, u8 num_mode_clocks, u8 num_wait_states, u8 opcode, enum spi_nor_protocol proto) { … } void spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, u8 opcode, enum spi_nor_protocol proto) { … } static int spi_nor_hwcaps2cmd(u32 hwcaps, const int table[][2], size_t size) { … } int spi_nor_hwcaps_read2cmd(u32 hwcaps) { … } int spi_nor_hwcaps_pp2cmd(u32 hwcaps) { … } /** * spi_nor_spimem_check_op - check if the operation is supported * by controller *@nor: pointer to a 'struct spi_nor' *@op: pointer to op template to be checked * * Returns 0 if operation is supported, -EOPNOTSUPP otherwise. */ static int spi_nor_spimem_check_op(struct spi_nor *nor, struct spi_mem_op *op) { … } /** * spi_nor_spimem_check_readop - check if the read op is supported * by controller *@nor: pointer to a 'struct spi_nor' *@read: pointer to op template to be checked * * Returns 0 if operation is supported, -EOPNOTSUPP otherwise. */ static int spi_nor_spimem_check_readop(struct spi_nor *nor, const struct spi_nor_read_command *read) { … } /** * spi_nor_spimem_check_pp - check if the page program op is supported * by controller *@nor: pointer to a 'struct spi_nor' *@pp: pointer to op template to be checked * * Returns 0 if operation is supported, -EOPNOTSUPP otherwise. */ static int spi_nor_spimem_check_pp(struct spi_nor *nor, const struct spi_nor_pp_command *pp) { … } /** * spi_nor_spimem_adjust_hwcaps - Find optimal Read/Write protocol * based on SPI controller capabilities * @nor: pointer to a 'struct spi_nor' * @hwcaps: pointer to resulting capabilities after adjusting * according to controller and flash's capability */ static void spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps) { … } /** * spi_nor_set_erase_type() - set a SPI NOR erase type * @erase: pointer to a structure that describes a SPI NOR erase type * @size: the size of the sector/block erased by the erase type * @opcode: the SPI command op code to erase the sector/block */ void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size, u8 opcode) { … } /** * spi_nor_mask_erase_type() - mask out a SPI NOR erase type * @erase: pointer to a structure that describes a SPI NOR erase type */ void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase) { … } /** * spi_nor_init_uniform_erase_map() - Initialize uniform erase map * @map: the erase map of the SPI NOR * @erase_mask: bitmask encoding erase types that can erase the entire * flash memory * @flash_size: the spi nor flash memory size */ void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, u8 erase_mask, u64 flash_size) { … } int spi_nor_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt) { … } static int spi_nor_select_read(struct spi_nor *nor, u32 shared_hwcaps) { … } static int spi_nor_select_pp(struct spi_nor *nor, u32 shared_hwcaps) { … } /** * spi_nor_select_uniform_erase() - select optimum uniform erase type * @map: the erase map of the SPI NOR * * Once the optimum uniform sector erase command is found, disable all the * other. * * Return: pointer to erase type on success, NULL otherwise. */ static const struct spi_nor_erase_type * spi_nor_select_uniform_erase(struct spi_nor_erase_map *map) { … } static int spi_nor_select_erase(struct spi_nor *nor) { … } static int spi_nor_set_addr_nbytes(struct spi_nor *nor) { … } static int spi_nor_setup(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps) { … } /** * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and * settings based on MFR register and ->default_init() hook. * @nor: pointer to a 'struct spi_nor'. */ static void spi_nor_manufacturer_init_params(struct spi_nor *nor) { … } /** * spi_nor_no_sfdp_init_params() - Initialize the flash's parameters and * settings based on nor->info->sfdp_flags. This method should be called only by * flashes that do not define SFDP tables. If the flash supports SFDP but the * information is wrong and the settings from this function can not be retrieved * by parsing SFDP, one should instead use the fixup hooks and update the wrong * bits. * @nor: pointer to a 'struct spi_nor'. */ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor) { … } /** * spi_nor_init_flags() - Initialize NOR flags for settings that are not defined * in the JESD216 SFDP standard, thus can not be retrieved when parsing SFDP. * @nor: pointer to a 'struct spi_nor' */ static void spi_nor_init_flags(struct spi_nor *nor) { … } /** * spi_nor_init_fixup_flags() - Initialize NOR flags for settings that can not * be discovered by SFDP for this particular flash because the SFDP table that * indicates this support is not defined in the flash. In case the table for * this support is defined but has wrong values, one should instead use a * post_sfdp() hook to set the SNOR_F equivalent flag. * @nor: pointer to a 'struct spi_nor' */ static void spi_nor_init_fixup_flags(struct spi_nor *nor) { … } /** * spi_nor_late_init_params() - Late initialization of default flash parameters. * @nor: pointer to a 'struct spi_nor' * * Used to initialize flash parameters that are not declared in the JESD216 * SFDP standard, or where SFDP tables are not defined at all. * Will replace the spi_nor_manufacturer_init_params() method. */ static int spi_nor_late_init_params(struct spi_nor *nor) { … } /** * spi_nor_sfdp_init_params_deprecated() - Deprecated way of initializing flash * parameters and settings based on JESD216 SFDP standard. * @nor: pointer to a 'struct spi_nor'. * * The method has a roll-back mechanism: in case the SFDP parsing fails, the * legacy flash parameters and settings will be restored. */ static void spi_nor_sfdp_init_params_deprecated(struct spi_nor *nor) { … } /** * spi_nor_init_params_deprecated() - Deprecated way of initializing flash * parameters and settings. * @nor: pointer to a 'struct spi_nor'. * * The method assumes that flash doesn't support SFDP so it initializes flash * parameters in spi_nor_no_sfdp_init_params() which later on can be overwritten * when parsing SFDP, if supported. */ static void spi_nor_init_params_deprecated(struct spi_nor *nor) { … } /** * spi_nor_init_default_params() - Default initialization of flash parameters * and settings. Done for all flashes, regardless is they define SFDP tables * or not. * @nor: pointer to a 'struct spi_nor'. */ static void spi_nor_init_default_params(struct spi_nor *nor) { … } /** * spi_nor_init_params() - Initialize the flash's parameters and settings. * @nor: pointer to a 'struct spi_nor'. * * The flash parameters and settings are initialized based on a sequence of * calls that are ordered by priority: * * 1/ Default flash parameters initialization. The initializations are done * based on nor->info data: * spi_nor_info_init_params() * * which can be overwritten by: * 2/ Manufacturer flash parameters initialization. The initializations are * done based on MFR register, or when the decisions can not be done solely * based on MFR, by using specific flash_info tweeks, ->default_init(): * spi_nor_manufacturer_init_params() * * which can be overwritten by: * 3/ SFDP flash parameters initialization. JESD216 SFDP is a standard and * should be more accurate that the above. * spi_nor_parse_sfdp() or spi_nor_no_sfdp_init_params() * * Please note that there is a ->post_bfpt() fixup hook that can overwrite * the flash parameters and settings immediately after parsing the Basic * Flash Parameter Table. * spi_nor_post_sfdp_fixups() is called after the SFDP tables are parsed. * It is used to tweak various flash parameters when information provided * by the SFDP tables are wrong. * * which can be overwritten by: * 4/ Late flash parameters initialization, used to initialize flash * parameters that are not declared in the JESD216 SFDP standard, or where SFDP * tables are not defined at all. * spi_nor_late_init_params() * * Return: 0 on success, -errno otherwise. */ static int spi_nor_init_params(struct spi_nor *nor) { … } /** spi_nor_set_octal_dtr() - enable or disable Octal DTR I/O. * @nor: pointer to a 'struct spi_nor' * @enable: whether to enable or disable Octal DTR * * Return: 0 on success, -errno otherwise. */ static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable) { … } /** * spi_nor_quad_enable() - enable Quad I/O if needed. * @nor: pointer to a 'struct spi_nor' * * Return: 0 on success, -errno otherwise. */ static int spi_nor_quad_enable(struct spi_nor *nor) { … } /** * spi_nor_set_4byte_addr_mode() - Set address mode. * @nor: pointer to a 'struct spi_nor'. * @enable: enable/disable 4 byte address mode. * * Return: 0 on success, -errno otherwise. */ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) { … } static int spi_nor_init(struct spi_nor *nor) { … } /** * spi_nor_soft_reset() - Perform a software reset * @nor: pointer to 'struct spi_nor' * * Performs a "Soft Reset and Enter Default Protocol Mode" sequence which resets * the device to its power-on-reset state. This is useful when the software has * made some changes to device (volatile) registers and needs to reset it before * shutting down, for example. * * Not every flash supports this sequence. The same set of opcodes might be used * for some other operation on a flash that does not support this. Support for * this sequence can be discovered via SFDP in the BFPT table. * * Return: 0 on success, -errno otherwise. */ static void spi_nor_soft_reset(struct spi_nor *nor) { … } /* mtd suspend handler */ static int spi_nor_suspend(struct mtd_info *mtd) { … } /* mtd resume handler */ static void spi_nor_resume(struct mtd_info *mtd) { … } static int spi_nor_get_device(struct mtd_info *mtd) { … } static void spi_nor_put_device(struct mtd_info *mtd) { … } static void spi_nor_restore(struct spi_nor *nor) { … } static const struct flash_info *spi_nor_match_name(struct spi_nor *nor, const char *name) { … } static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor, const char *name) { … } static u32 spi_nor_get_region_erasesize(const struct spi_nor_erase_region *region, const struct spi_nor_erase_type *erase_type) { … } static int spi_nor_set_mtd_eraseregions(struct spi_nor *nor) { … } static int spi_nor_set_mtd_info(struct spi_nor *nor) { … } static int spi_nor_hw_reset(struct spi_nor *nor) { … } int spi_nor_scan(struct spi_nor *nor, const char *name, const struct spi_nor_hwcaps *hwcaps) { … } EXPORT_SYMBOL_GPL(…); static int spi_nor_create_read_dirmap(struct spi_nor *nor) { … } static int spi_nor_create_write_dirmap(struct spi_nor *nor) { … } static int spi_nor_probe(struct spi_mem *spimem) { … } static int spi_nor_remove(struct spi_mem *spimem) { … } static void spi_nor_shutdown(struct spi_mem *spimem) { … } /* * Do NOT add to this array without reading the following: * * Historically, many flash devices are bound to this driver by their name. But * since most of these flash are compatible to some extent, and their * differences can often be differentiated by the JEDEC read-ID command, we * encourage new users to add support to the spi-nor library, and simply bind * against a generic string here (e.g., "jedec,spi-nor"). * * Many flash names are kept here in this list to keep them available * as module aliases for existing platforms. */ static const struct spi_device_id spi_nor_dev_ids[] = …; MODULE_DEVICE_TABLE(spi, spi_nor_dev_ids); static const struct of_device_id spi_nor_of_table[] = …; MODULE_DEVICE_TABLE(of, spi_nor_of_table); /* * REVISIT: many of these chips have deep power-down modes, which * should clearly be entered on suspend() to minimize power use. * And also when they're otherwise idle... */ static struct spi_mem_driver spi_nor_driver = …; static int __init spi_nor_module_init(void) { … } module_init(…) …; static void __exit spi_nor_module_exit(void) { … } module_exit(spi_nor_module_exit); MODULE_LICENSE(…) …; MODULE_AUTHOR(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …;