Unverified Commit 829ec640 authored by Tudor Ambarus's avatar Tudor Ambarus
Browse files

mtd: spi-nor: Trim what is exposed in spi-nor.h



The SPI NOR controllers drivers must not be able to use structures that
are meant just for the SPI NOR core.

struct spi_nor_flash_parameter is filled at run-time with info gathered
from flash_info, manufacturer and sfdp data. struct spi_nor_flash_parameter
should be opaque to the SPI NOR controller drivers, make sure it is.

spi_nor_option_flags, spi_nor_read_command, spi_nor_pp_command,
spi_nor_read_command_index and spi_nor_pp_command_index are defined for the
core use, make sure they are opaque to the SPI NOR controller drivers.

Signed-off-by: default avatarTudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
parent d3c4bb31
Loading
Loading
Loading
Loading
+54 −32
Original line number Original line Diff line number Diff line
@@ -778,7 +778,7 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
		ret = spi_nor_read_cr(nor, &sr_cr[1]);
		ret = spi_nor_read_cr(nor, &sr_cr[1]);
		if (ret)
		if (ret)
			return ret;
			return ret;
	} else if (nor->params.quad_enable) {
	} else if (nor->params->quad_enable) {
		/*
		/*
		 * If the Status Register 2 Read command (35h) is not
		 * If the Status Register 2 Read command (35h) is not
		 * supported, we should at least be sure we don't
		 * supported, we should at least be sure we don't
@@ -786,7 +786,7 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
		 *
		 *
		 * We can safely assume that when the Quad Enable method is
		 * We can safely assume that when the Quad Enable method is
		 * set, the value of the QE bit is one, as a consequence of the
		 * set, the value of the QE bit is one, as a consequence of the
		 * nor->params.quad_enable() call.
		 * nor->params->quad_enable() call.
		 *
		 *
		 * We can safely assume that the Quad Enable bit is present in
		 * We can safely assume that the Quad Enable bit is present in
		 * the Status Register 2 at BIT(1). According to the JESD216
		 * the Status Register 2 at BIT(1). According to the JESD216
@@ -1051,6 +1051,11 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
				      ARRAY_SIZE(spi_nor_3to4_erase));
				      ARRAY_SIZE(spi_nor_3to4_erase));
}
}


static bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
{
	return !!nor->params->erase_map.uniform_erase_type;
}

static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
{
{
	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
@@ -1058,7 +1063,7 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
	nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
	nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);


	if (!spi_nor_has_uniform_erase(nor)) {
	if (!spi_nor_has_uniform_erase(nor)) {
		struct spi_nor_erase_map *map = &nor->params.erase_map;
		struct spi_nor_erase_map *map = &nor->params->erase_map;
		struct spi_nor_erase_type *erase;
		struct spi_nor_erase_type *erase;
		int i;
		int i;


@@ -1095,10 +1100,10 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor)


static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr)
static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr)
{
{
	if (!nor->params.convert_addr)
	if (!nor->params->convert_addr)
		return addr;
		return addr;


	return nor->params.convert_addr(nor, addr);
	return nor->params->convert_addr(nor, addr);
}
}


/*
/*
@@ -1203,6 +1208,16 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
	return NULL;
	return NULL;
}
}


static u64 spi_nor_region_is_last(const struct spi_nor_erase_region *region)
{
	return region->offset & SNOR_LAST_REGION;
}

static u64 spi_nor_region_end(const struct spi_nor_erase_region *region)
{
	return (region->offset & ~SNOR_ERASE_FLAGS_MASK) + region->size;
}

/**
/**
 * spi_nor_region_next() - get the next spi nor region
 * spi_nor_region_next() - get the next spi nor region
 * @region:	pointer to a structure that describes a SPI NOR erase region
 * @region:	pointer to a structure that describes a SPI NOR erase region
@@ -1307,7 +1322,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor,
				       struct list_head *erase_list,
				       struct list_head *erase_list,
				       u64 addr, u32 len)
				       u64 addr, u32 len)
{
{
	const struct spi_nor_erase_map *map = &nor->params.erase_map;
	const struct spi_nor_erase_map *map = &nor->params->erase_map;
	const struct spi_nor_erase_type *erase, *prev_erase = NULL;
	const struct spi_nor_erase_type *erase, *prev_erase = NULL;
	struct spi_nor_erase_region *region;
	struct spi_nor_erase_region *region;
	struct spi_nor_erase_command *cmd = NULL;
	struct spi_nor_erase_command *cmd = NULL;
@@ -1793,7 +1808,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = nor->params.locking_ops->lock(nor, ofs, len);
	ret = nor->params->locking_ops->lock(nor, ofs, len);


	spi_nor_unlock_and_unprep(nor);
	spi_nor_unlock_and_unprep(nor);
	return ret;
	return ret;
@@ -1808,7 +1823,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = nor->params.locking_ops->unlock(nor, ofs, len);
	ret = nor->params->locking_ops->unlock(nor, ofs, len);


	spi_nor_unlock_and_unprep(nor);
	spi_nor_unlock_and_unprep(nor);
	return ret;
	return ret;
@@ -1823,7 +1838,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = nor->params.locking_ops->is_locked(nor, ofs, len);
	ret = nor->params->locking_ops->is_locked(nor, ofs, len);


	spi_nor_unlock_and_unprep(nor);
	spi_nor_unlock_and_unprep(nor);
	return ret;
	return ret;
@@ -2288,7 +2303,7 @@ static int spi_nor_spimem_check_pp(struct spi_nor *nor,
static void
static void
spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps)
spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps)
{
{
	struct spi_nor_flash_parameter *params =  &nor->params;
	struct spi_nor_flash_parameter *params = nor->params;
	unsigned int cap;
	unsigned int cap;


	/* DTR modes are not supported yet, mask them all. */
	/* DTR modes are not supported yet, mask them all. */
@@ -2387,7 +2402,7 @@ static int spi_nor_select_read(struct spi_nor *nor,
	if (cmd < 0)
	if (cmd < 0)
		return -EINVAL;
		return -EINVAL;


	read = &nor->params.reads[cmd];
	read = &nor->params->reads[cmd];
	nor->read_opcode = read->opcode;
	nor->read_opcode = read->opcode;
	nor->read_proto = read->proto;
	nor->read_proto = read->proto;


@@ -2418,7 +2433,7 @@ static int spi_nor_select_pp(struct spi_nor *nor,
	if (cmd < 0)
	if (cmd < 0)
		return -EINVAL;
		return -EINVAL;


	pp = &nor->params.page_programs[cmd];
	pp = &nor->params->page_programs[cmd];
	nor->program_opcode = pp->opcode;
	nor->program_opcode = pp->opcode;
	nor->write_proto = pp->proto;
	nor->write_proto = pp->proto;
	return 0;
	return 0;
@@ -2479,7 +2494,7 @@ 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_select_erase(struct spi_nor *nor)
{
{
	struct spi_nor_erase_map *map = &nor->params.erase_map;
	struct spi_nor_erase_map *map = &nor->params->erase_map;
	const struct spi_nor_erase_type *erase = NULL;
	const struct spi_nor_erase_type *erase = NULL;
	struct mtd_info *mtd = &nor->mtd;
	struct mtd_info *mtd = &nor->mtd;
	u32 wanted_size = nor->info->sector_size;
	u32 wanted_size = nor->info->sector_size;
@@ -2528,7 +2543,7 @@ static int spi_nor_select_erase(struct spi_nor *nor)
static int spi_nor_default_setup(struct spi_nor *nor,
static int spi_nor_default_setup(struct spi_nor *nor,
				 const struct spi_nor_hwcaps *hwcaps)
				 const struct spi_nor_hwcaps *hwcaps)
{
{
	struct spi_nor_flash_parameter *params = &nor->params;
	struct spi_nor_flash_parameter *params = nor->params;
	u32 ignored_mask, shared_mask;
	u32 ignored_mask, shared_mask;
	int err;
	int err;


@@ -2589,10 +2604,10 @@ static int spi_nor_default_setup(struct spi_nor *nor,
static int spi_nor_setup(struct spi_nor *nor,
static int spi_nor_setup(struct spi_nor *nor,
			 const struct spi_nor_hwcaps *hwcaps)
			 const struct spi_nor_hwcaps *hwcaps)
{
{
	if (!nor->params.setup)
	if (!nor->params->setup)
		return 0;
		return 0;


	return nor->params.setup(nor, hwcaps);
	return nor->params->setup(nor, hwcaps);
}
}


/**
/**
@@ -2622,13 +2637,13 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
{
{
	struct spi_nor_flash_parameter sfdp_params;
	struct spi_nor_flash_parameter sfdp_params;


	memcpy(&sfdp_params, &nor->params, sizeof(sfdp_params));
	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));


	if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
	if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
		nor->addr_width = 0;
		nor->addr_width = 0;
		nor->flags &= ~SNOR_F_4B_OPCODES;
		nor->flags &= ~SNOR_F_4B_OPCODES;
	} else {
	} else {
		memcpy(&nor->params, &sfdp_params, sizeof(nor->params));
		memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
	}
	}
}
}


@@ -2639,7 +2654,7 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
 */
 */
static void spi_nor_info_init_params(struct spi_nor *nor)
static void spi_nor_info_init_params(struct spi_nor *nor)
{
{
	struct spi_nor_flash_parameter *params = &nor->params;
	struct spi_nor_flash_parameter *params = nor->params;
	struct spi_nor_erase_map *map = &params->erase_map;
	struct spi_nor_erase_map *map = &params->erase_map;
	const struct flash_info *info = nor->info;
	const struct flash_info *info = nor->info;
	struct device_node *np = spi_nor_get_flash_node(nor);
	struct device_node *np = spi_nor_get_flash_node(nor);
@@ -2758,8 +2773,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
	 * NOR protection support. When locking_ops are not provided, we pick
	 * NOR protection support. When locking_ops are not provided, we pick
	 * the default ones.
	 * the default ones.
	 */
	 */
	if (nor->flags & SNOR_F_HAS_LOCK && !nor->params.locking_ops)
	if (nor->flags & SNOR_F_HAS_LOCK && !nor->params->locking_ops)
		nor->params.locking_ops = &spi_nor_sr_locking_ops;
		nor->params->locking_ops = &spi_nor_sr_locking_ops;
}
}


/**
/**
@@ -2799,8 +2814,12 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
 * ->default_init() hook or the SFDP parser do not set specific params.
 * ->default_init() hook or the SFDP parser do not set specific params.
 *		spi_nor_late_init_params()
 *		spi_nor_late_init_params()
 */
 */
static void spi_nor_init_params(struct spi_nor *nor)
static int spi_nor_init_params(struct spi_nor *nor)
{
{
	nor->params = devm_kzalloc(nor->dev, sizeof(*nor->params), GFP_KERNEL);
	if (!nor->params)
		return -ENOMEM;

	spi_nor_info_init_params(nor);
	spi_nor_info_init_params(nor);


	spi_nor_manufacturer_init_params(nor);
	spi_nor_manufacturer_init_params(nor);
@@ -2812,6 +2831,8 @@ static void spi_nor_init_params(struct spi_nor *nor)
	spi_nor_post_sfdp_fixups(nor);
	spi_nor_post_sfdp_fixups(nor);


	spi_nor_late_init_params(nor);
	spi_nor_late_init_params(nor);

	return 0;
}
}


/**
/**
@@ -2822,14 +2843,14 @@ static void spi_nor_init_params(struct spi_nor *nor)
 */
 */
static int spi_nor_quad_enable(struct spi_nor *nor)
static int spi_nor_quad_enable(struct spi_nor *nor)
{
{
	if (!nor->params.quad_enable)
	if (!nor->params->quad_enable)
		return 0;
		return 0;


	if (!(spi_nor_get_protocol_width(nor->read_proto) == 4 ||
	if (!(spi_nor_get_protocol_width(nor->read_proto) == 4 ||
	      spi_nor_get_protocol_width(nor->write_proto) == 4))
	      spi_nor_get_protocol_width(nor->write_proto) == 4))
		return 0;
		return 0;


	return nor->params.quad_enable(nor);
	return nor->params->quad_enable(nor);
}
}


/**
/**
@@ -2844,7 +2865,7 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
static int spi_nor_unlock_all(struct spi_nor *nor)
static int spi_nor_unlock_all(struct spi_nor *nor)
{
{
	if (nor->flags & SNOR_F_HAS_LOCK)
	if (nor->flags & SNOR_F_HAS_LOCK)
		return spi_nor_unlock(&nor->mtd, 0, nor->params.size);
		return spi_nor_unlock(&nor->mtd, 0, nor->params->size);


	return 0;
	return 0;
}
}
@@ -2875,7 +2896,7 @@ static int spi_nor_init(struct spi_nor *nor)
		 */
		 */
		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
			  "enabling reset hack; may not recover from unexpected reboots\n");
			  "enabling reset hack; may not recover from unexpected reboots\n");
		nor->params.set_4byte_addr_mode(nor, true);
		nor->params->set_4byte_addr_mode(nor, true);
	}
	}


	return 0;
	return 0;
@@ -2899,7 +2920,7 @@ void spi_nor_restore(struct spi_nor *nor)
	/* restore the addressing mode */
	/* restore the addressing mode */
	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
	    nor->flags & SNOR_F_BROKEN_RESET)
	    nor->flags & SNOR_F_BROKEN_RESET)
		nor->params.set_4byte_addr_mode(nor, false);
		nor->params->set_4byte_addr_mode(nor, false);
}
}
EXPORT_SYMBOL_GPL(spi_nor_restore);
EXPORT_SYMBOL_GPL(spi_nor_restore);


@@ -3004,7 +3025,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
	struct device *dev = nor->dev;
	struct device *dev = nor->dev;
	struct mtd_info *mtd = &nor->mtd;
	struct mtd_info *mtd = &nor->mtd;
	struct device_node *np = spi_nor_get_flash_node(nor);
	struct device_node *np = spi_nor_get_flash_node(nor);
	struct spi_nor_flash_parameter *params = &nor->params;
	int ret;
	int ret;
	int i;
	int i;


@@ -3055,7 +3075,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
	mtd->_write = spi_nor_write;
	mtd->_write = spi_nor_write;


	/* Init flash parameters based on flash_info struct and SFDP */
	/* Init flash parameters based on flash_info struct and SFDP */
	spi_nor_init_params(nor);
	ret = spi_nor_init_params(nor);
	if (ret)
		return ret;


	if (!mtd->name)
	if (!mtd->name)
		mtd->name = dev_name(dev);
		mtd->name = dev_name(dev);
@@ -3063,12 +3085,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
	mtd->type = MTD_NORFLASH;
	mtd->type = MTD_NORFLASH;
	mtd->writesize = 1;
	mtd->writesize = 1;
	mtd->flags = MTD_CAP_NORFLASH;
	mtd->flags = MTD_CAP_NORFLASH;
	mtd->size = params->size;
	mtd->size = nor->params->size;
	mtd->_erase = spi_nor_erase;
	mtd->_erase = spi_nor_erase;
	mtd->_read = spi_nor_read;
	mtd->_read = spi_nor_read;
	mtd->_resume = spi_nor_resume;
	mtd->_resume = spi_nor_resume;


	if (nor->params.locking_ops) {
	if (nor->params->locking_ops) {
		mtd->_lock = spi_nor_lock;
		mtd->_lock = spi_nor_lock;
		mtd->_unlock = spi_nor_unlock;
		mtd->_unlock = spi_nor_unlock;
		mtd->_is_locked = spi_nor_is_locked;
		mtd->_is_locked = spi_nor_is_locked;
@@ -3091,7 +3113,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
		mtd->flags |= MTD_NO_ERASE;
		mtd->flags |= MTD_NO_ERASE;


	mtd->dev.parent = dev;
	mtd->dev.parent = dev;
	nor->page_size = params->page_size;
	nor->page_size = nor->params->page_size;
	mtd->writebufsize = nor->page_size;
	mtd->writebufsize = nor->page_size;


	if (of_property_read_bool(np, "broken-flash-reset"))
	if (of_property_read_bool(np, "broken-flash-reset"))
+214 −0
Original line number Original line Diff line number Diff line
@@ -11,6 +11,220 @@


#define SPI_NOR_MAX_ID_LEN	6
#define SPI_NOR_MAX_ID_LEN	6


enum spi_nor_option_flags {
	SNOR_F_USE_FSR		= BIT(0),
	SNOR_F_HAS_SR_TB	= BIT(1),
	SNOR_F_NO_OP_CHIP_ERASE	= BIT(2),
	SNOR_F_READY_XSR_RDY	= BIT(3),
	SNOR_F_USE_CLSR		= BIT(4),
	SNOR_F_BROKEN_RESET	= BIT(5),
	SNOR_F_4B_OPCODES	= BIT(6),
	SNOR_F_HAS_4BAIT	= BIT(7),
	SNOR_F_HAS_LOCK		= BIT(8),
	SNOR_F_HAS_16BIT_SR	= BIT(9),
	SNOR_F_NO_READ_CR	= BIT(10),
	SNOR_F_HAS_SR_TB_BIT6	= BIT(11),
};

struct spi_nor_read_command {
	u8			num_mode_clocks;
	u8			num_wait_states;
	u8			opcode;
	enum spi_nor_protocol	proto;
};

struct spi_nor_pp_command {
	u8			opcode;
	enum spi_nor_protocol	proto;
};

enum spi_nor_read_command_index {
	SNOR_CMD_READ,
	SNOR_CMD_READ_FAST,
	SNOR_CMD_READ_1_1_1_DTR,

	/* Dual SPI */
	SNOR_CMD_READ_1_1_2,
	SNOR_CMD_READ_1_2_2,
	SNOR_CMD_READ_2_2_2,
	SNOR_CMD_READ_1_2_2_DTR,

	/* Quad SPI */
	SNOR_CMD_READ_1_1_4,
	SNOR_CMD_READ_1_4_4,
	SNOR_CMD_READ_4_4_4,
	SNOR_CMD_READ_1_4_4_DTR,

	/* Octal SPI */
	SNOR_CMD_READ_1_1_8,
	SNOR_CMD_READ_1_8_8,
	SNOR_CMD_READ_8_8_8,
	SNOR_CMD_READ_1_8_8_DTR,

	SNOR_CMD_READ_MAX
};

enum spi_nor_pp_command_index {
	SNOR_CMD_PP,

	/* Quad SPI */
	SNOR_CMD_PP_1_1_4,
	SNOR_CMD_PP_1_4_4,
	SNOR_CMD_PP_4_4_4,

	/* Octal SPI */
	SNOR_CMD_PP_1_1_8,
	SNOR_CMD_PP_1_8_8,
	SNOR_CMD_PP_8_8_8,

	SNOR_CMD_PP_MAX
};

/**
 * struct spi_nor_erase_type - Structure to describe a SPI NOR erase type
 * @size:		the size of the sector/block erased by the erase type.
 *			JEDEC JESD216B imposes erase sizes to be a power of 2.
 * @size_shift:		@size is a power of 2, the shift is stored in
 *			@size_shift.
 * @size_mask:		the size mask based on @size_shift.
 * @opcode:		the SPI command op code to erase the sector/block.
 * @idx:		Erase Type index as sorted in the Basic Flash Parameter
 *			Table. It will be used to synchronize the supported
 *			Erase Types with the ones identified in the SFDP
 *			optional tables.
 */
struct spi_nor_erase_type {
	u32	size;
	u32	size_shift;
	u32	size_mask;
	u8	opcode;
	u8	idx;
};

/**
 * struct spi_nor_erase_command - Used for non-uniform erases
 * The structure is used to describe a list of erase commands to be executed
 * once we validate that the erase can be performed. The elements in the list
 * are run-length encoded.
 * @list:		for inclusion into the list of erase commands.
 * @count:		how many times the same erase command should be
 *			consecutively used.
 * @size:		the size of the sector/block erased by the command.
 * @opcode:		the SPI command op code to erase the sector/block.
 */
struct spi_nor_erase_command {
	struct list_head	list;
	u32			count;
	u32			size;
	u8			opcode;
};

/**
 * struct spi_nor_erase_region - Structure to describe a SPI NOR erase region
 * @offset:		the offset in the data array of erase region start.
 *			LSB bits are used as a bitmask encoding flags to
 *			determine if this region is overlaid, if this region is
 *			the last in the SPI NOR flash memory and to indicate
 *			all the supported erase commands inside this region.
 *			The erase types are sorted in ascending order with the
 *			smallest Erase Type size being at BIT(0).
 * @size:		the size of the region in bytes.
 */
struct spi_nor_erase_region {
	u64		offset;
	u64		size;
};

#define SNOR_ERASE_TYPE_MAX	4
#define SNOR_ERASE_TYPE_MASK	GENMASK_ULL(SNOR_ERASE_TYPE_MAX - 1, 0)

#define SNOR_LAST_REGION	BIT(4)
#define SNOR_OVERLAID_REGION	BIT(5)

#define SNOR_ERASE_FLAGS_MAX	6
#define SNOR_ERASE_FLAGS_MASK	GENMASK_ULL(SNOR_ERASE_FLAGS_MAX - 1, 0)

/**
 * struct spi_nor_erase_map - Structure to describe the SPI NOR erase map
 * @regions:		array of erase regions. The regions are consecutive in
 *			address space. Walking through the regions is done
 *			incrementally.
 * @uniform_region:	a pre-allocated erase region for SPI NOR with a uniform
 *			sector size (legacy implementation).
 * @erase_type:		an array of erase types shared by all the regions.
 *			The erase types are sorted in ascending order, with the
 *			smallest Erase Type size being the first member in the
 *			erase_type array.
 * @uniform_erase_type:	bitmask encoding erase types that can erase the
 *			entire memory. This member is completed at init by
 *			uniform and non-uniform SPI NOR flash memories if they
 *			support at least one erase type that can erase the
 *			entire memory.
 */
struct spi_nor_erase_map {
	struct spi_nor_erase_region	*regions;
	struct spi_nor_erase_region	uniform_region;
	struct spi_nor_erase_type	erase_type[SNOR_ERASE_TYPE_MAX];
	u8				uniform_erase_type;
};

/**
 * struct spi_nor_locking_ops - SPI NOR locking methods
 * @lock:	lock a region of the SPI NOR.
 * @unlock:	unlock a region of the SPI NOR.
 * @is_locked:	check if a region of the SPI NOR is completely locked
 */
struct spi_nor_locking_ops {
	int (*lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
	int (*unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
	int (*is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
};

/**
 * struct spi_nor_flash_parameter - SPI NOR flash parameters and settings.
 * Includes legacy flash parameters and settings that can be overwritten
 * by the spi_nor_fixups hooks, or dynamically when parsing the JESD216
 * Serial Flash Discoverable Parameters (SFDP) tables.
 *
 * @size:		the flash memory density in bytes.
 * @page_size:		the page size of the SPI NOR flash memory.
 * @hwcaps:		describes the read and page program hardware
 *			capabilities.
 * @reads:		read capabilities ordered by priority: the higher index
 *                      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.
 * @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
 * @convert_addr:	converts an absolute address into something the flash
 *                      will understand. Particularly useful when pagesize is
 *                      not a power-of-2.
 * @setup:              configures the SPI NOR memory. Useful for SPI NOR
 *                      flashes that have peculiarities to the SPI NOR standard
 *                      e.g. different opcodes, specific address calculation,
 *                      page size, etc.
 * @locking_ops:	SPI NOR locking methods.
 */
struct spi_nor_flash_parameter {
	u64				size;
	u32				page_size;

	struct spi_nor_hwcaps		hwcaps;
	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);
	int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);
	u32 (*convert_addr)(struct spi_nor *nor, u32 addr);
	int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps);

	const struct spi_nor_locking_ops *locking_ops;
};

/**
/**
 * struct spi_nor_fixups - SPI NOR fixup hooks
 * struct spi_nor_fixups - SPI NOR fixup hooks
 * @default_init: called after default flash parameters init. Used to tweak
 * @default_init: called after default flash parameters init. Used to tweak
+1 −1
Original line number Original line Diff line number Diff line
@@ -16,7 +16,7 @@ static void gd25q256_default_init(struct spi_nor *nor)
	 * indicate the quad_enable method for this case, we need
	 * indicate the quad_enable method for this case, we need
	 * to set it in the default_init fixup hook.
	 * to set it in the default_init fixup hook.
	 */
	 */
	nor->params.quad_enable = spi_nor_sr1_bit6_quad_enable;
	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
}
}


static struct spi_nor_fixups gd25q256_fixups = {
static struct spi_nor_fixups gd25q256_fixups = {
+1 −1
Original line number Original line Diff line number Diff line
@@ -68,7 +68,7 @@ static const struct flash_info issi_parts[] = {


static void issi_default_init(struct spi_nor *nor)
static void issi_default_init(struct spi_nor *nor)
{
{
	nor->params.quad_enable = spi_nor_sr1_bit6_quad_enable;
	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
}
}


static const struct spi_nor_fixups issi_fixups = {
static const struct spi_nor_fixups issi_fixups = {
+2 −2
Original line number Original line Diff line number Diff line
@@ -82,8 +82,8 @@ static const struct flash_info macronix_parts[] = {


static void macronix_default_init(struct spi_nor *nor)
static void macronix_default_init(struct spi_nor *nor)
{
{
	nor->params.quad_enable = spi_nor_sr1_bit6_quad_enable;
	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
	nor->params.set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
	nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
}
}


static const struct spi_nor_fixups macronix_fixups = {
static const struct spi_nor_fixups macronix_fixups = {
Loading