[RFC,6/9] regmap: Speed up _regmap_raw_write_impl() for large buffers
diff mbox series

Message ID 20200216172117.49832-7-noralf@tronnes.org
State New
Headers show
Series
  • Regmap over USB for Multifunction USB Device (gpio, display, ...)
Related show

Commit Message

Noralf Trønnes Feb. 16, 2020, 5:21 p.m. UTC
When writing a 3MB buffer the unwritable check in _regmap_raw_write_impl()
adds a ~20ms overhead on a Raspberry Pi 4.
Amend this by avoiding the check if it's not necessary.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/base/regmap/regmap.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Mark Brown Feb. 17, 2020, 12:15 p.m. UTC | #1
On Sun, Feb 16, 2020 at 06:21:14PM +0100, Noralf Trønnes wrote:

> When writing a 3MB buffer the unwritable check in _regmap_raw_write_impl()
> adds a ~20ms overhead on a Raspberry Pi 4.
> Amend this by avoiding the check if it's not necessary.

This is a generic optimization, why is it mixed in with the rest of this
series?  There is no dependency either way :(

>  	/* Check for unwritable registers before we start */
> -	for (i = 0; i < val_len / map->format.val_bytes; i++)
> -		if (!regmap_writeable(map,
> -				     reg + regmap_get_offset(map, i)))
> -			return -EINVAL;
> +	if (map->max_register || map->writeable_reg || map->wr_table) {
> +		for (i = 0; i < val_len / map->format.val_bytes; i++)
> +			if (!regmap_writeable(map,
> +					      reg + regmap_get_offset(map, i)))
> +				return -EINVAL;
> +	}

This is going to break if there is any change to the implementation of
regmap_writeable().  The code should at least be next to that if not
actually shared so that this doesn't happen.  I'd suggest implementing a
function regmap_writeable_range() and then making regmap_writeable()
call that.

Patch
diff mbox series

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 19f57ccfbe1d..cd876309a74b 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1489,10 +1489,12 @@  static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
 	WARN_ON(!map->bus);
 
 	/* Check for unwritable registers before we start */
-	for (i = 0; i < val_len / map->format.val_bytes; i++)
-		if (!regmap_writeable(map,
-				     reg + regmap_get_offset(map, i)))
-			return -EINVAL;
+	if (map->max_register || map->writeable_reg || map->wr_table) {
+		for (i = 0; i < val_len / map->format.val_bytes; i++)
+			if (!regmap_writeable(map,
+					      reg + regmap_get_offset(map, i)))
+				return -EINVAL;
+	}
 
 	if (!map->cache_bypass && map->format.parse_val) {
 		unsigned int ival;