All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Sverdlin <alexander.sverdlin@nsn.com>
To: Ionut Nicu <ioan.nicu.ext@nsn.com>, linux-kernel@vger.kernel.org
Cc: Mark Brown <broonie@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: Fwd: Re: [PATCH 1/3] regmap: flat: use the cache_present bitmap
Date: Mon, 19 Aug 2013 13:18:01 +0200	[thread overview]
Message-ID: <5211FEE9.5000300@nsn.com> (raw)
In-Reply-To: <5211D68C.1070608@nsn.com>

Hello!

On 08/19/2013 10:25 AM, Ionut Nicu wrote:
> -------- Original Message --------
> Subject: Re: [PATCH 1/3] regmap: flat: use the cache_present bitmap
> Date: Fri, 09 Aug 2013 19:16:49 +0200
> From: Ionut Nicu <ioan.nicu.ext@nsn.com>
> To: ext Mark Brown <broonie@kernel.org>
> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,  linux-kernel@vger.kernel.org
> 
> On 09.08.2013 13:44, ext Mark Brown wrote:
>> On Fri, Aug 09, 2013 at 12:09:11PM +0200, Ionut Nicu wrote:
>>> As opposed to the other regmap cache implementations,
>>> regcache_flat didn't use the cache_present bitmap for
>>> figuring out whether a register was cached or not, nor
>>> did it mark a register as present in the cache when
>>> regcache_flat_write() was called.
>>
>>> This caused incorrect behaviour, such as returning
>>> value 0 for non-volatile registers without first reading
>>> their value from the device and storing it in the cache.
>>
>> The goal with the flat cache is to do as little work as possible for
>> things like memory mapped devices where the cache operations are
>> actually noticable in comparison with the I/O costs.  I would therefore
>> exapect that anything using the flat cache would want to ensure that the
>> cache is fully populated at init time, reading back from the device if
>> nothing else (by setting num_reg_defaults_raw but not providing values),
>> rather than do additional operations in the data path.
>>
> 
> Ok, I get your point. I've tried using this approach, but the thing is
> that I have a device which supports only single rw operations. The
> regcache_hw_init() function calls regmap_raw_read which in turn calls
> _regmap_raw_read() when cache_bypass is enabled. But _regmap_raw_read()
> doesn't take the use_single_rw flag into account and tries to read
> num_reg_defaults_raw registers in a single bus transfer. Unfortunately
> this doesn't work with my device. 
> 
> I thought about changing regcache_hw_init() to check for this flag in
> the same way regmap_bulk_read() does, but I think this is pretty ugly.
> 
> What do you think about moving the check to use_single_rw inside
> _regmap_raw_read(), right where the bus accesses are done?
> 
> Something like in the following patch:

Acked-by: Alexander Sverdlin <alexander.sverdlin@nsn.com>

> 
> diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
> index 42b45ac..de7f353 100644
> --- a/drivers/base/regmap/regmap.c
> +++ b/drivers/base/regmap/regmap.c
> @@ -1486,14 +1486,16 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
>  {
>  	struct regmap_range_node *range;
>  	u8 *u8 = map->work_buf;
> -	int ret;
> +	size_t val_bytes = map->format.val_bytes;
> +	size_t reg_size = map->format.reg_bytes + map->format.pad_bytes;
> +	int ret, i;
>  
>  	WARN_ON(!map->bus);
>  
>  	range = _regmap_range_lookup(map, reg);
>  	if (range) {
>  		ret = _regmap_select_page(map, &reg, range,
> -					  val_len / map->format.val_bytes);
> +					  val_len / val_bytes);
>  		if (ret != 0)
>  			return ret;
>  	}
> @@ -1508,15 +1510,41 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
>  	 */
>  	u8[0] |= map->read_flag_mask;
>  
> -	trace_regmap_hw_read_start(map->dev, reg,
> -				   val_len / map->format.val_bytes);
> +	/*
> +	 * Some devices does not support bulk read, for
> +	 * them we have a series of single read operations.
> +	 */
> +	if (map->use_single_rw) {
> +		for (i = 0; i < val_len; i++) {
> +			trace_regmap_hw_read_start(map->dev,
> +					reg + (i * map->reg_stride), 1);
> +
> +			map->format.format_reg(map->work_buf,
> +					reg + (i *  map->reg_stride),
> +					map->reg_shift);
> +			u8[0] |= map->read_flag_mask;
> +
> +			ret = map->bus->read(map->bus_context,
> +					map->work_buf,
> +					reg_size,
> +					val + (i * val_bytes),
> +					val_bytes);
> +			if (ret != 0)
> +				return ret;
>  
> -	ret = map->bus->read(map->bus_context, map->work_buf,
> -			     map->format.reg_bytes + map->format.pad_bytes,
> -			     val, val_len);
> +			trace_regmap_hw_read_done(map->dev,
> +					reg + (i * map->reg_stride), 1);
> +		}
> +	} else {
> +		trace_regmap_hw_read_start(map->dev, reg, val_len / val_bytes);
>  
> -	trace_regmap_hw_read_done(map->dev, reg,
> -				  val_len / map->format.val_bytes);
> +		ret = map->bus->read(map->bus_context, map->work_buf,
> +				reg_size, val, val_len);
> +		if (ret != 0)
> +			return ret;
> +
> +		trace_regmap_hw_read_done(map->dev, reg, val_len / val_bytes);
> +	}
>  
>  	return ret;
>  }
> @@ -1702,25 +1730,9 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
>  		return -EINVAL;
>  
>  	if (vol || map->cache_type == REGCACHE_NONE) {
> -		/*
> -		 * Some devices does not support bulk read, for
> -		 * them we have a series of single read operations.
> -		 */
> -		if (map->use_single_rw) {
> -			for (i = 0; i < val_count; i++) {
> -				ret = regmap_raw_read(map,
> -						reg + (i * map->reg_stride),
> -						val + (i * val_bytes),
> -						val_bytes);
> -				if (ret != 0)
> -					return ret;
> -			}
> -		} else {
> -			ret = regmap_raw_read(map, reg, val,
> -					      val_bytes * val_count);
> -			if (ret != 0)
> -				return ret;
> -		}
> +		ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
> +		if (ret != 0)
> +			return ret;
>  
>  		for (i = 0; i < val_count * val_bytes; i += val_bytes)
>  			map->format.parse_inplace(val + i);
> 
> 
> 
> 
> 

-- 
Best regards,
Alexander Sverdlin.

      parent reply	other threads:[~2013-08-19 11:19 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-09 10:09 [PATCH 1/3] regmap: flat: use the cache_present bitmap Ionut Nicu
2013-08-09 11:44 ` Mark Brown
2013-08-09 17:16   ` Ionut Nicu
2013-08-13  7:17     ` Ionut Nicu
2013-08-13 11:06       ` Mark Brown
     [not found]     ` <5211D68C.1070608@nsn.com>
2013-08-19 11:18       ` Alexander Sverdlin [this message]

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=5211FEE9.5000300@nsn.com \
    --to=alexander.sverdlin@nsn.com \
    --cc=broonie@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=ioan.nicu.ext@nsn.com \
    --cc=linux-kernel@vger.kernel.org \
    /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.