Unverified Commit d534fd97 authored by Takahiro Kuwano's avatar Takahiro Kuwano Committed by Tudor Ambarus
Browse files

mtd: spi-nor: spansion: use CLPEF as an alternative to CLSR



Infineon S28Hx (SEMPER Octal) and S25FS256T (SEMPER Nano) support Clear
Program and Erase Failure Flags (CLPEF, 82h) instead of CLSR(30h).
Introduce a new mfr_flag together with the infrastructure to allow
manufacturer private data in the core. With this we remove the need
to have if checks in the code at runtime and instead set the correct
opcodes at probe time. S25Hx (SEMPER QSPI) supports CLSR but it may
be disabled by CFR3x[2] while CLPEF is always available. Therefore,
the mfr_flag is also applied to S25Hx for safety.

Signed-off-by: default avatarTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Link: https://lore.kernel.org/r/20230726075257.12985-2-tudor.ambarus@linaro.org


Signed-off-by: default avatarTudor Ambarus <tudor.ambarus@linaro.org>
parent abfac0f3
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -48,9 +48,11 @@ static const struct spi_nor_locking_ops at25fs_nor_locking_ops = {
	.is_locked = at25fs_nor_is_locked,
};

static void at25fs_nor_late_init(struct spi_nor *nor)
static int at25fs_nor_late_init(struct spi_nor *nor)
{
	nor->params->locking_ops = &at25fs_nor_locking_ops;

	return 0;
}

static const struct spi_nor_fixups at25fs_nor_fixups = {
@@ -149,9 +151,11 @@ static const struct spi_nor_locking_ops atmel_nor_global_protection_ops = {
	.is_locked = atmel_nor_is_global_protected,
};

static void atmel_nor_global_protection_late_init(struct spi_nor *nor)
static int atmel_nor_global_protection_late_init(struct spi_nor *nor)
{
	nor->params->locking_ops = &atmel_nor_global_protection_ops;

	return 0;
}

static const struct spi_nor_fixups atmel_nor_global_protection_fixups = {
+15 −8
Original line number Diff line number Diff line
@@ -2900,16 +2900,23 @@ static void spi_nor_init_fixup_flags(struct spi_nor *nor)
 * SFDP standard, or where SFDP tables are not defined at all.
 * Will replace the spi_nor_manufacturer_init_params() method.
 */
static void spi_nor_late_init_params(struct spi_nor *nor)
static int spi_nor_late_init_params(struct spi_nor *nor)
{
	struct spi_nor_flash_parameter *params = nor->params;
	int ret;

	if (nor->manufacturer && nor->manufacturer->fixups &&
	    nor->manufacturer->fixups->late_init)
		nor->manufacturer->fixups->late_init(nor);
	    nor->manufacturer->fixups->late_init) {
		ret = nor->manufacturer->fixups->late_init(nor);
		if (ret)
			return ret;
	}

	if (nor->info->fixups && nor->info->fixups->late_init)
		nor->info->fixups->late_init(nor);
	if (nor->info->fixups && nor->info->fixups->late_init) {
		ret = nor->info->fixups->late_init(nor);
		if (ret)
			return ret;
	}

	/* Default method kept for backward compatibility. */
	if (!params->set_4byte_addr_mode)
@@ -2927,6 +2934,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)

	if (nor->info->n_banks > 1)
		params->bank_size = div64_u64(params->size, nor->info->n_banks);

	return 0;
}

/**
@@ -3085,9 +3094,7 @@ static int spi_nor_init_params(struct spi_nor *nor)
		spi_nor_init_params_deprecated(nor);
	}

	spi_nor_late_init_params(nor);

	return 0;
	return spi_nor_late_init_params(nor);
}

/** spi_nor_set_octal_dtr() - enable or disable Octal DTR I/O.
+3 −1
Original line number Diff line number Diff line
@@ -378,6 +378,7 @@ struct spi_nor_otp {
 *			than reading the status register to indicate they
 *			are ready for a new command
 * @locking_ops:	SPI NOR locking methods.
 * @priv:		flash's private data.
 */
struct spi_nor_flash_parameter {
	u64				bank_size;
@@ -406,6 +407,7 @@ struct spi_nor_flash_parameter {
	int (*ready)(struct spi_nor *nor);

	const struct spi_nor_locking_ops *locking_ops;
	void *priv;
};

/**
@@ -432,7 +434,7 @@ struct spi_nor_fixups {
			 const struct sfdp_parameter_header *bfpt_header,
			 const struct sfdp_bfpt *bfpt);
	int (*post_sfdp)(struct spi_nor *nor);
	void (*late_init)(struct spi_nor *nor);
	int (*late_init)(struct spi_nor *nor);
};

/**
+3 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ static const struct spi_nor_fixups is25lp256_fixups = {
	.post_bfpt = is25lp256_post_bfpt_fixups,
};

static void pm25lv_nor_late_init(struct spi_nor *nor)
static int pm25lv_nor_late_init(struct spi_nor *nor)
{
	struct spi_nor_erase_map *map = &nor->params->erase_map;
	int i;
@@ -38,6 +38,8 @@ static void pm25lv_nor_late_init(struct spi_nor *nor)
	for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++)
		if (map->erase_type[i].size == 4096)
			map->erase_type[i].opcode = SPINOR_OP_BE_4K_PMC;

	return 0;
}

static const struct spi_nor_fixups pm25lv_nor_fixups = {
+3 −1
Original line number Diff line number Diff line
@@ -110,10 +110,12 @@ static void macronix_nor_default_init(struct spi_nor *nor)
	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
}

static void macronix_nor_late_init(struct spi_nor *nor)
static int macronix_nor_late_init(struct spi_nor *nor)
{
	if (!nor->params->set_4byte_addr_mode)
		nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b;

	return 0;
}

static const struct spi_nor_fixups macronix_nor_fixups = {
Loading