Commit f74de390 authored by Takahiro Kuwano's avatar Takahiro Kuwano Committed by Pratyush Yadav
Browse files

mtd: spi-nor: sfdp: introduce smpt_map_id fixup hook



Certain chips have inconsistent Sector Map Parameter Table (SMPT) data,
which leads to the wrong map ID being identified, causing failures to
detect the correct sector map.

To fix this, introduce smpt_map_id() into the struct spi_nor_fixups.
This function will be called after the initial SMPT-based detection,
allowing chip-specific logic to correct the map ID.

Infineon S25FS512S needs this fixup as it has inconsistency between map
ID definition and configuration register value actually obtained.

Co-developed-by: default avatarMarek Vasut <marek.vasut+renesas@mailbox.org>
Signed-off-by: default avatarMarek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: default avatarTudor Ambarus <tudor.ambarus@linaro.org>
Tested-by: Marek Vasut <marek.vasut+renesas@mailbox.org> # S25FS512S
Signed-off-by: default avatarTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Reviewed-by: default avatarTudor Ambarus <tudor.ambarus@linaro.org&gt;>
Signed-off-by: default avatarPratyush Yadav <pratyush@kernel.org>
parent 653f6def
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -411,6 +411,8 @@ struct spi_nor_flash_parameter {
 * @post_bfpt: called after the BFPT table has been parsed
 * @smpt_read_dummy: called during SMPT table is being parsed. Used to fix the
 *                   number of dummy cycles in read register ops.
 * @smpt_map_id: called after map ID in SMPT table has been determined for the
 *               case the map ID is wrong and needs to be fixed.
 * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs
 *             that do not support RDSFDP). Typically used to tweak various
 *             parameters that could not be extracted by other means (i.e.
@@ -429,6 +431,7 @@ struct spi_nor_fixups {
			 const struct sfdp_parameter_header *bfpt_header,
			 const struct sfdp_bfpt *bfpt);
	void (*smpt_read_dummy)(const struct spi_nor *nor, u8 *read_dummy);
	void (*smpt_map_id)(const struct spi_nor *nor, u8 *map_id);
	int (*post_sfdp)(struct spi_nor *nor);
	int (*late_init)(struct spi_nor *nor);
};
+12 −0
Original line number Diff line number Diff line
@@ -730,6 +730,16 @@ static u8 spi_nor_smpt_read_dummy(const struct spi_nor *nor, const u32 settings)
	return read_dummy;
}

static void spi_nor_smpt_map_id_fixups(const struct spi_nor *nor, u8 *map_id)
{
	if (nor->manufacturer && nor->manufacturer->fixups &&
	    nor->manufacturer->fixups->smpt_map_id)
		nor->manufacturer->fixups->smpt_map_id(nor, map_id);

	if (nor->info->fixups && nor->info->fixups->smpt_map_id)
		nor->info->fixups->smpt_map_id(nor, map_id);
}

/**
 * spi_nor_get_map_in_use() - get the configuration map in use
 * @nor:	pointer to a 'struct spi_nor'
@@ -783,6 +793,8 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt,
		map_id = map_id << 1 | !!(*buf & read_data_mask);
	}

	spi_nor_smpt_map_id_fixups(nor, &map_id);

	/*
	 * If command descriptors are provided, they always precede map
	 * descriptors in the table. There is no need to start the iteration