All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael Walle" <mwalle@kernel.org>
To: <tkuw584924@gmail.com>, <linux-mtd@lists.infradead.org>
Cc: <tudor.ambarus@linaro.org>, <pratyush@kernel.org>,
	<miquel.raynal@bootlin.com>, <richard@nod.at>, <vigneshr@ti.com>,
	<Bacem.Daassi@infineon.com>,
	"Takahiro Kuwano" <Takahiro.Kuwano@infineon.com>
Subject: Re: [PATCH v4 2/4] mtd: spi-nor: core: get rid of SNOR_LAST_REGION flag
Date: Fri, 23 Feb 2024 11:17:50 +0100	[thread overview]
Message-ID: <CZCDQLZW6P1M.26WJS6HQEVDRO@kernel.org> (raw)
In-Reply-To: <eded84294bd81e966d6f423e578fc2cfb9a4a5b6.1708404584.git.Takahiro.Kuwano@infineon.com>

On Tue Feb 20, 2024 at 9:34 AM CET, tkuw584924 wrote:
> From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
>
> Introduce n_regions in spi_nor_erase_map structure and remove
> SNOR_LAST_REGION flag. Loop logics that depend on the flag are also
> reworked to use n_regions as loop condition.
>
> Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
> Suggested-by: Tudor Ambarus <tudor.ambarus@linaro.org>
> Suggested-by: Michael Walle <mwalle@kernel.org>
> ---
>  drivers/mtd/spi-nor/core.c    | 105 +++++++++-------------------------
>  drivers/mtd/spi-nor/core.h    |  10 ++--
>  drivers/mtd/spi-nor/debugfs.c |  16 +++---
>  drivers/mtd/spi-nor/sfdp.c    |  18 ++----
>  4 files changed, 43 insertions(+), 106 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 5b2f13d0888e..d9a0c0e31950 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -1565,57 +1565,11 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
>  	return NULL;
>  }
>  
> -static u64 spi_nor_region_is_last(const struct spi_nor_erase_region *region)
> -{
> -	return region->flags & SNOR_LAST_REGION;
> -}
> -
>  static u64 spi_nor_region_end(const struct spi_nor_erase_region *region)
>  {
>  	return region->offset + region->size;
>  }
>  
> -/**
> - * spi_nor_region_next() - get the next spi nor region
> - * @region:	pointer to a structure that describes a SPI NOR erase region
> - *
> - * Return: the next spi nor region or NULL if last region.
> - */
> -struct spi_nor_erase_region *
> -spi_nor_region_next(struct spi_nor_erase_region *region)
> -{
> -	if (spi_nor_region_is_last(region))
> -		return NULL;
> -	region++;
> -	return region;
> -}
> -
> -/**
> - * spi_nor_find_erase_region() - find the region of the serial flash memory in
> - *				 which the offset fits
> - * @map:	the erase map of the SPI NOR
> - * @addr:	offset in the serial flash memory
> - *
> - * Return: a pointer to the spi_nor_erase_region struct, ERR_PTR(-errno)
> - *	   otherwise.
> - */
> -static struct spi_nor_erase_region *
> -spi_nor_find_erase_region(const struct spi_nor_erase_map *map, u64 addr)
> -{
> -	struct spi_nor_erase_region *region = map->regions;
> -	u64 region_end = spi_nor_region_end(region);
> -
> -	while (addr < region->offset || addr >= region_end) {
> -		region = spi_nor_region_next(region);
> -		if (!region)
> -			return ERR_PTR(-EINVAL);
> -
> -		region_end = spi_nor_region_end(region);
> -	}
> -
> -	return region;
> -}
> -
>  /**
>   * spi_nor_init_erase_cmd() - initialize an erase command
>   * @region:	pointer to a structure that describes a SPI NOR erase region
> @@ -1682,48 +1636,41 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor,
>  	struct spi_nor_erase_region *region;
>  	struct spi_nor_erase_command *cmd = NULL;
>  	u64 region_end;
> +	unsigned int i;
>  	int ret = -EINVAL;
>  
> -	region = spi_nor_find_erase_region(map, addr);
> -	if (IS_ERR(region))
> -		return PTR_ERR(region);
> -
> -	region_end = spi_nor_region_end(region);
> +	for (i = 0; i < map->n_regions; i++) {
> +		region = &map->regions[i];
> +		region_end = spi_nor_region_end(region);

Likewise,

region_end = return region->offset + region->size;

>  
> -	while (len) {
> -		erase = spi_nor_find_best_erase_type(map, region, addr, len);
> -		if (!erase)
> -			goto destroy_erase_cmd_list;
> -
> -		if (prev_erase != erase ||
> -		    erase->size != cmd->size ||
> -		    region->flags & SNOR_OVERLAID_REGION) {
> -			cmd = spi_nor_init_erase_cmd(region, erase);
> -			if (IS_ERR(cmd)) {
> -				ret = PTR_ERR(cmd);
> +		while (len && addr >= region->offset && addr < region_end) {
> +			erase = spi_nor_find_best_erase_type(map, region, addr,
> +							     len);
> +			if (!erase)
>  				goto destroy_erase_cmd_list;
> -			}
>  
> -			list_add_tail(&cmd->list, erase_list);
> -		} else {
> -			cmd->count++;
> -		}
> -
> -		addr += cmd->size;
> -		len -= cmd->size;
> +			if (prev_erase != erase || erase->size != cmd->size ||
> +			    region->flags & SNOR_OVERLAID_REGION) {
> +				cmd = spi_nor_init_erase_cmd(region, erase);
> +				if (IS_ERR(cmd)) {
> +					ret = PTR_ERR(cmd);
> +					goto destroy_erase_cmd_list;
> +				}
> +
> +				list_add_tail(&cmd->list, erase_list);
> +			} else {
> +				cmd->count++;
> +			}
>  
> -		if (len && addr >= region_end) {
> -			region = spi_nor_region_next(region);
> -			if (!region)
> -				goto destroy_erase_cmd_list;
> -			region_end = spi_nor_region_end(region);
> +			len -= cmd->size;
> +			addr += cmd->size;
> +			prev_erase = erase;
>  		}
>  
> -		prev_erase = erase;
> +		if (!len)
> +			return 0;
>  	}

From what I can tell, this looks ok,

Reviewed-by: Michael Walle <mwalle@kernel.org>

-michael

>  
> -	return 0;
> -
>  destroy_erase_cmd_list:
>  	spi_nor_destroy_erase_cmd_list(erase_list);
>  	return ret;
> @@ -2439,8 +2386,8 @@ void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map,
>  	map->uniform_region.offset = 0;
>  	map->uniform_region.size = flash_size;
>  	map->uniform_region.erase_mask = erase_mask;
> -	map->uniform_region.flags = SNOR_LAST_REGION;
>  	map->regions = &map->uniform_region;
> +	map->n_regions = 1;
>  }
>  
>  int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index e002de22b18a..1668d79f55bc 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -238,8 +238,7 @@ struct spi_nor_erase_command {
>   *			inside this region. The erase types are sorted in
>   *			ascending order with the smallest Erase Type size being
>   *			at BIT(0).
> - * @flags:		flags to determine if this region is overlaid, if this
> - *			region is the last in the SPI NOR flash memory
> + * @flags:		flags to determine if this region is overlaid.
>   */
>  struct spi_nor_erase_region {
>  	u64		offset;
> @@ -250,8 +249,7 @@ struct spi_nor_erase_region {
>  
>  #define SNOR_ERASE_TYPE_MAX	4
>  
> -#define SNOR_LAST_REGION	BIT(0)
> -#define SNOR_OVERLAID_REGION	BIT(1)
> +#define SNOR_OVERLAID_REGION	BIT(0)
>  
>  /**
>   * struct spi_nor_erase_map - Structure to describe the SPI NOR erase map
> @@ -264,11 +262,13 @@ struct spi_nor_erase_region {
>   *			The erase types are sorted in ascending order, with the
>   *			smallest Erase Type size being the first member in the
>   *			erase_type array.
> + * @n_regions:		number of erase regions.
>   */
>  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];
> +	unsigned int			n_regions;
>  };
>  
>  /**
> @@ -699,8 +699,6 @@ void spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, u8 opcode,
>  void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size,
>  			    u8 opcode);
>  void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase);
> -struct spi_nor_erase_region *
> -spi_nor_region_next(struct spi_nor_erase_region *region);
>  void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map,
>  				    u8 erase_mask, u64 flash_size);
>  
> diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c
> index 16b30f1a3066..0832b5893d6b 100644
> --- a/drivers/mtd/spi-nor/debugfs.c
> +++ b/drivers/mtd/spi-nor/debugfs.c
> @@ -78,10 +78,10 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
>  	struct spi_nor *nor = s->private;
>  	struct spi_nor_flash_parameter *params = nor->params;
>  	struct spi_nor_erase_map *erase_map = &params->erase_map;
> -	struct spi_nor_erase_region *region;
> +	struct spi_nor_erase_region *region = erase_map->regions;
>  	const struct flash_info *info = nor->info;
>  	char buf[16], *str;
> -	int i;
> +	unsigned int i;
>  
>  	seq_printf(s, "name\t\t%s\n", info->name);
>  	seq_printf(s, "id\t\t%*ph\n", SPI_NOR_MAX_ID_LEN, nor->id);
> @@ -144,13 +144,11 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
>  	seq_puts(s, "\nsector map\n");
>  	seq_puts(s, " region (in hex)   | erase mask | flags\n");
>  	seq_puts(s, " ------------------+------------+----------\n");
> -	for (region = erase_map->regions;
> -	     region;
> -	     region = spi_nor_region_next(region)) {
> -		u64 start = region->offset;
> -		u64 end = start + region->size - 1;
> -		u8 erase_mask = region->erase_mask;
> -		u8 flags = region->flags;
> +	for (i = 0; i < erase_map->n_regions; i++) {
> +		u64 start = region[i].offset;
> +		u64 end = start + region[i].size - 1;
> +		u8 erase_mask = region[i].erase_mask;
> +		u8 flags = region[i].flags;
>  
>  		seq_printf(s, " %08llx-%08llx |     [%c%c%c%c] | %s\n",
>  			   start, end,
> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> index c8d8b4e5b7e6..c4721d7dc97a 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -390,15 +390,14 @@ static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map)
>  {
>  	struct spi_nor_erase_region *region = map->regions;
>  	u8 sorted_erase_mask;
> +	unsigned int i;
>  
> -	while (region) {
> -		sorted_erase_mask = spi_nor_sort_erase_mask(map,
> -							    region->erase_mask);
> +	for (i = 0; i < map->n_regions; i++) {
> +		sorted_erase_mask =
> +			spi_nor_sort_erase_mask(map, region[i].erase_mask);
>  
>  		/* Overwrite erase mask. */
> -		region->erase_mask = sorted_erase_mask;
> -
> -		region = spi_nor_region_next(region);
> +		region[i].erase_mask = sorted_erase_mask;
>  	}
>  }
>  
> @@ -774,11 +773,6 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt,
>  	return ret;
>  }
>  
> -static void spi_nor_region_mark_end(struct spi_nor_erase_region *region)
> -{
> -	region->flags |= SNOR_LAST_REGION;
> -}
> -
>  static void spi_nor_region_mark_overlay(struct spi_nor_erase_region *region)
>  {
>  	region->flags |= SNOR_OVERLAID_REGION;
> @@ -836,6 +830,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
>  	if (!region)
>  		return -ENOMEM;
>  	map->regions = region;
> +	map->n_regions = region_count;
>  
>  	uniform_erase_type = 0xff;
>  	regions_erase_type = 0;
> @@ -864,7 +859,6 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
>  
>  		offset = region[i].offset + region[i].size;
>  	}
> -	spi_nor_region_mark_end(&region[i - 1]);
>  
>  	save_uniform_erase_type = map->uniform_region.erase_mask;
>  	map->uniform_region.erase_mask =


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2024-02-23 10:18 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-20  8:34 [PATCH v4 0/4] mtd: spi-nor: core: set mtd->eraseregions for non-uniform erase map tkuw584924
2024-02-20  8:34 ` [PATCH v4 1/4] mtd: spi-nor: core: rework struct spi_nor_erase_region tkuw584924
2024-02-23 10:14   ` Michael Walle
2024-02-23 10:17     ` Tudor Ambarus
2024-02-20  8:34 ` [PATCH v4 2/4] mtd: spi-nor: core: get rid of SNOR_LAST_REGION flag tkuw584924
2024-02-23 10:17   ` Michael Walle [this message]
2024-02-26 11:15   ` Tudor Ambarus
2024-02-20  8:34 ` [PATCH v4 3/4] mtd: spi-nor: core: get rid of SNOR_OVERLAID_REGION flag tkuw584924
2024-02-23 10:19   ` Michael Walle
2024-02-20  8:34 ` [PATCH v4 4/4] mtd: spi-nor: core: set mtd->eraseregions for non-uniform erase map tkuw584924
2024-02-23 10:21   ` Michael Walle
2024-02-22  9:16 ` [PATCH v4 0/4] " Tudor Ambarus
2024-02-22 10:26   ` Takahiro Kuwano
2024-02-26  9:02 ` Tudor Ambarus
2024-02-26 11:36 ` Tudor Ambarus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CZCDQLZW6P1M.26WJS6HQEVDRO@kernel.org \
    --to=mwalle@kernel.org \
    --cc=Bacem.Daassi@infineon.com \
    --cc=Takahiro.Kuwano@infineon.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=miquel.raynal@bootlin.com \
    --cc=pratyush@kernel.org \
    --cc=richard@nod.at \
    --cc=tkuw584924@gmail.com \
    --cc=tudor.ambarus@linaro.org \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.