nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
if (!spi_nor_has_uniform_erase(nor)) {
- struct spi_nor_erase_map *map = &nor->erase_map;
+ struct spi_nor_erase_map *map = &nor->params.erase_map;
struct spi_nor_erase_type *erase;
int i;
struct list_head *erase_list,
u64 addr, u32 len)
{
- const struct spi_nor_erase_map *map = &nor->erase_map;
+ const struct spi_nor_erase_map *map = &nor->params.erase_map;
const struct spi_nor_erase_type *erase, *prev_erase = NULL;
struct spi_nor_erase_region *region;
struct spi_nor_erase_command *cmd = NULL;
const struct sfdp_parameter_header *bfpt_header,
struct spi_nor_flash_parameter *params)
{
- struct spi_nor_erase_map *map = &nor->erase_map;
+ struct spi_nor_erase_map *map = ¶ms->erase_map;
struct spi_nor_erase_type *erase_type = map->erase_type;
struct sfdp_bfpt bfpt;
size_t len;
* Erase Types defined in the bfpt table.
*/
erase_mask = 0;
- memset(&nor->erase_map, 0, sizeof(nor->erase_map));
+ memset(¶ms->erase_map, 0, sizeof(params->erase_map));
for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) {
const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i];
u32 erasesize;
/**
* spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map
* @nor: pointer to a 'struct spi_nor'
+ * @params: pointer to a duplicate 'struct spi_nor_flash_parameter' that is
+ * used for storing SFDP parsed data
* @smpt: pointer to the sector map parameter table
*
* Return: 0 on success, -errno otherwise.
*/
-static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
- const u32 *smpt)
+static int
+spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
+ struct spi_nor_flash_parameter *params,
+ const u32 *smpt)
{
- struct spi_nor_erase_map *map = &nor->erase_map;
+ struct spi_nor_erase_map *map = ¶ms->erase_map;
struct spi_nor_erase_type *erase = map->erase_type;
struct spi_nor_erase_region *region;
u64 offset;
* spi_nor_parse_smpt() - parse Sector Map Parameter Table
* @nor: pointer to a 'struct spi_nor'
* @smpt_header: sector map parameter table header
+ * @params: pointer to a duplicate 'struct spi_nor_flash_parameter'
+ * that is used for storing SFDP parsed data
*
* This table is optional, but when available, we parse it to identify the
* location and size of sectors within the main data array of the flash memory
* Return: 0 on success, -errno otherwise.
*/
static int spi_nor_parse_smpt(struct spi_nor *nor,
- const struct sfdp_parameter_header *smpt_header)
+ const struct sfdp_parameter_header *smpt_header,
+ struct spi_nor_flash_parameter *params)
{
const u32 *sector_map;
u32 *smpt;
goto out;
}
- ret = spi_nor_init_non_uniform_erase_map(nor, sector_map);
+ ret = spi_nor_init_non_uniform_erase_map(nor, params, sector_map);
if (ret)
goto out;
- spi_nor_regions_sort_erase_types(&nor->erase_map);
+ spi_nor_regions_sort_erase_types(¶ms->erase_map);
/* fall through */
out:
kfree(smpt);
{ 0u /* not used */, BIT(12) },
};
struct spi_nor_pp_command *params_pp = params->page_programs;
- struct spi_nor_erase_map *map = &nor->erase_map;
+ struct spi_nor_erase_map *map = ¶ms->erase_map;
struct spi_nor_erase_type *erase_type = map->erase_type;
u32 *dwords;
size_t len;
switch (SFDP_PARAM_HEADER_ID(param_header)) {
case SFDP_SECTOR_MAP_ID:
- err = spi_nor_parse_smpt(nor, param_header);
+ err = spi_nor_parse_smpt(nor, param_header, params);
break;
case SFDP_4BAIT_ID:
static int spi_nor_init_params(struct spi_nor *nor)
{
struct spi_nor_flash_parameter *params = &nor->params;
- struct spi_nor_erase_map *map = &nor->erase_map;
+ struct spi_nor_erase_map *map = ¶ms->erase_map;
const struct flash_info *info = nor->info;
u8 i, erase_mask;
if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
!(info->flags & SPI_NOR_SKIP_SFDP)) {
struct spi_nor_flash_parameter sfdp_params;
- struct spi_nor_erase_map prev_map;
memcpy(&sfdp_params, params, sizeof(sfdp_params));
- memcpy(&prev_map, &nor->erase_map, sizeof(prev_map));
if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
nor->addr_width = 0;
nor->flags &= ~SNOR_F_4B_OPCODES;
- /* restore previous erase map */
- memcpy(&nor->erase_map, &prev_map,
- sizeof(nor->erase_map));
} else {
memcpy(params, &sfdp_params, sizeof(*params));
}
static int spi_nor_select_erase(struct spi_nor *nor, u32 wanted_size)
{
- struct spi_nor_erase_map *map = &nor->erase_map;
+ struct spi_nor_erase_map *map = &nor->params.erase_map;
const struct spi_nor_erase_type *erase = NULL;
struct mtd_info *mtd = &nor->mtd;
int i;
* in the array, the higher priority.
* @page_programs: page program capabilities ordered by priority: the
* higher index in the array, the higher priority.
+ * @erase_map: the erase map parsed from the SFDP Sector Map Parameter
+ * Table.
* @quad_enable: enables SPI NOR quad mode.
*/
struct spi_nor_flash_parameter {
struct spi_nor_read_command reads[SNOR_CMD_READ_MAX];
struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX];
+ struct spi_nor_erase_map erase_map;
+
int (*quad_enable)(struct spi_nor *nor);
};
* @read_proto: the SPI protocol for read operations
* @write_proto: the SPI protocol for write operations
* @reg_proto the SPI protocol for read_reg/write_reg/erase operations
- * @erase_map: the erase map of the SPI NOR
* @prepare: [OPTIONAL] do some preparations for the
* read/write/erase/lock/unlock operations
* @unprepare: [OPTIONAL] do some post work after the
enum spi_nor_protocol reg_proto;
bool sst_write_second;
u32 flags;
- struct spi_nor_erase_map erase_map;
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
static bool __maybe_unused spi_nor_has_uniform_erase(const struct spi_nor *nor)
{
- return !!nor->erase_map.uniform_erase_type;
+ return !!nor->params.erase_map.uniform_erase_type;
}
static inline void spi_nor_set_flash_node(struct spi_nor *nor,