diff mbox

[06/20] regmap: Fix regmap_bulk_write for bus writes

Message ID 1439374365-20623-7-git-send-email-mpa@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Markus Pargmann Aug. 12, 2015, 10:12 a.m. UTC
The regmap config does not prohibit val_bytes that are not powers of
two. But the current code of regmap_bulk_write for use_single_rw does
limit the possible val_bytes to 1, 2 and 4.

This patch fixes the behaviour to allow bus writes with non-standard
val_bytes sizes.

Cc: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/base/regmap/regmap.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Mark Brown Aug. 12, 2015, 11:10 a.m. UTC | #1
On Wed, Aug 12, 2015 at 12:12:31PM +0200, Markus Pargmann wrote:

> Cc: Stephen Boyd <sboyd@codeaurora.org>

I'm not sure why you're putting this in these commit messages...

>  	if (!map->bus || map->use_single_rw) {
> +		if (val_bytes != 1 && val_bytes != 2 && val_bytes != 4)
> +			return -EINVAL;
> +

switch statement please.  This also looks like a separate change to the
handling of single writes.

> +	} else if (map->use_single_rw) {
> +		/*

How are we ever going to fall into this else case?  The first check has
an || map->use_single_rw it so if this is true then the first check will
be too so we'd never end up in this else case.
Markus Pargmann Aug. 12, 2015, 12:07 p.m. UTC | #2
On Wed, Aug 12, 2015 at 12:10:31PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:31PM +0200, Markus Pargmann wrote:
> 
> > Cc: Stephen Boyd <sboyd@codeaurora.org>
> 
> I'm not sure why you're putting this in these commit messages...

Just to not forget that Stephen should be in Cc as he introduced the
switch case which removed the code that I add here again:
	f4298360a5c2 (regmap: Allow regmap_bulk_write() to work for "no-bus" regmaps)

> 
> >  	if (!map->bus || map->use_single_rw) {
> > +		if (val_bytes != 1 && val_bytes != 2 && val_bytes != 4)
> > +			return -EINVAL;
> > +
> 
> switch statement please.  This also looks like a separate change to the
> handling of single writes.

Sorry this was a left-over of a previous arrangement. Will remove it.

> 
> > +	} else if (map->use_single_rw) {
> > +		/*
> 
> How are we ever going to fall into this else case?  The first check has
> an || map->use_single_rw it so if this is true then the first check will
> be too so we'd never end up in this else case.

Oh right, seems like another leftover of rebases :-/ sorry. The above
condition should just be
 	if (!map->bus) {

Otherwise we fall into to this second case which is also able to handle
for example 3 byte values.

Thanks,

Markus
diff mbox

Patch

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index f6bd3517a472..f98bd5bf5c62 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1680,6 +1680,9 @@  int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 	 * them we have a series of single write operations.
 	 */
 	if (!map->bus || map->use_single_rw) {
+		if (val_bytes != 1 && val_bytes != 2 && val_bytes != 4)
+			return -EINVAL;
+
 		map->lock(map->lock_arg);
 		for (i = 0; i < val_count; i++) {
 			unsigned int ival;
@@ -1706,6 +1709,21 @@  int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
+	} else if (map->use_single_rw) {
+		/*
+		 * We need to handle bus writes separate to support val_bytes
+		 * that are not powers of 2.
+		 */
+		map->lock(map->lock_arg);
+		for (i = 0; i < val_count; i++) {
+			ret = _regmap_raw_write(map,
+						reg + (i * map->reg_stride),
+						val + (i * val_bytes),
+						val_bytes);
+			if (ret)
+				break;
+		}
+		map->unlock(map->lock_arg);
 	} else {
 		void *wval;