All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Introduce reg stride order
@ 2015-12-17  8:45 Xiubo Li
  2015-12-17  8:45 ` [PATCH 1/3] regmap: core: Introduce register " Xiubo Li
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Xiubo Li @ 2015-12-17  8:45 UTC (permalink / raw)
  To: broonie; +Cc: linux-kernel, Xiubo Li

Xiubo Li (3):
  regmap: core: Introduce register stride order
  regcache: Introduce the index parsing API
  regcache: flat: Introduce regcache_get_index()

 drivers/base/regmap/internal.h      | 13 +++++++++++++
 drivers/base/regmap/regcache-flat.c | 11 ++++++-----
 drivers/base/regmap/regmap.c        | 15 +++++++++------
 3 files changed, 28 insertions(+), 11 deletions(-)

-- 
1.8.3.1




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] regmap: core: Introduce register stride order
  2015-12-17  8:45 [PATCH 0/3] Introduce reg stride order Xiubo Li
@ 2015-12-17  8:45 ` Xiubo Li
  2015-12-17  8:45 ` [PATCH 2/3] regcache: Introduce the index parsing API Xiubo Li
  2015-12-17  8:45 ` [PATCH 3/3] regcache: flat: Introduce regcache_get_index() Xiubo Li
  2 siblings, 0 replies; 4+ messages in thread
From: Xiubo Li @ 2015-12-17  8:45 UTC (permalink / raw)
  To: broonie; +Cc: linux-kernel, Xiubo Li

Since the register stride should always equal to 2^N, and bit rotation is
much faster than multiplication and division. So introducing the stride
order and using bit rotation to get the offset of the register from the
index to improve the performance.

Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
---
 drivers/base/regmap/internal.h |  7 +++++++
 drivers/base/regmap/regmap.c   | 15 +++++++++------
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 3df9770..d43784e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -110,6 +110,7 @@ struct regmap {
 	/* number of bits to (left) shift the reg value when formatting*/
 	int reg_shift;
 	int reg_stride;
+	int reg_stride_order;
 
 	/* regcache specific members */
 	const struct regcache_ops *cache_ops;
@@ -263,4 +264,10 @@ static inline const char *regmap_name(const struct regmap *map)
 	return map->name;
 }
 
+static inline unsigned int regmap_get_offset(const struct regmap *map,
+					     unsigned int index)
+{
+	return index << map->reg_stride_order;
+}
+
 #endif
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ee54e84..9890d27 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -638,6 +638,7 @@ struct regmap *__regmap_init(struct device *dev,
 		map->reg_stride = config->reg_stride;
 	else
 		map->reg_stride = 1;
+	map->reg_stride_order = get_order(map->reg_stride);
 	map->use_single_read = config->use_single_rw || !bus || !bus->read;
 	map->use_single_write = config->use_single_rw || !bus || !bus->write;
 	map->can_multi_write = config->can_multi_write && bus && bus->write;
@@ -1308,7 +1309,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
 	if (map->writeable_reg)
 		for (i = 0; i < val_len / map->format.val_bytes; i++)
 			if (!map->writeable_reg(map->dev,
-						reg + (i * map->reg_stride)))
+					       reg + regmap_get_offset(map, i)))
 				return -EINVAL;
 
 	if (!map->cache_bypass && map->format.parse_val) {
@@ -1316,7 +1317,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
 		int val_bytes = map->format.val_bytes;
 		for (i = 0; i < val_len / val_bytes; i++) {
 			ival = map->format.parse_val(val + (i * val_bytes));
-			ret = regcache_write(map, reg + (i * map->reg_stride),
+			ret = regcache_write(map,
+					     reg + regmap_get_offset(map, i),
 					     ival);
 			if (ret) {
 				dev_err(map->dev,
@@ -1846,8 +1848,9 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 				goto out;
 			}
 
-			ret = _regmap_write(map, reg + (i * map->reg_stride),
-					ival);
+			ret = _regmap_write(map,
+					    reg + regmap_get_offset(map, i),
+					    ival);
 			if (ret != 0)
 				goto out;
 		}
@@ -2416,7 +2419,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 		 * cost as we expect to hit the cache.
 		 */
 		for (i = 0; i < val_count; i++) {
-			ret = _regmap_read(map, reg + (i * map->reg_stride),
+			ret = _regmap_read(map, reg + regmap_get_offset(map, i),
 					   &v);
 			if (ret != 0)
 				goto out;
@@ -2568,7 +2571,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 	} else {
 		for (i = 0; i < val_count; i++) {
 			unsigned int ival;
-			ret = regmap_read(map, reg + (i * map->reg_stride),
+			ret = regmap_read(map, reg + regmap_get_offset(map, i),
 					  &ival);
 			if (ret != 0)
 				return ret;
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] regcache: Introduce the index parsing API
  2015-12-17  8:45 [PATCH 0/3] Introduce reg stride order Xiubo Li
  2015-12-17  8:45 ` [PATCH 1/3] regmap: core: Introduce register " Xiubo Li
@ 2015-12-17  8:45 ` Xiubo Li
  2015-12-17  8:45 ` [PATCH 3/3] regcache: flat: Introduce regcache_get_index() Xiubo Li
  2 siblings, 0 replies; 4+ messages in thread
From: Xiubo Li @ 2015-12-17  8:45 UTC (permalink / raw)
  To: broonie; +Cc: linux-kernel, Xiubo Li

Here introduces regcache_get_index() for regmap cache, which uses
the register stride order and bit rotation.

Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
---
 drivers/base/regmap/internal.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d43784e..60699e6 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -270,4 +270,10 @@ static inline unsigned int regmap_get_offset(const struct regmap *map,
 	return index << map->reg_stride_order;
 }
 
+static inline unsigned int regcache_get_index(const struct regmap *map,
+					    unsigned int reg)
+{
+	return reg >> map->reg_stride_order;
+}
+
 #endif
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] regcache: flat: Introduce regcache_get_index()
  2015-12-17  8:45 [PATCH 0/3] Introduce reg stride order Xiubo Li
  2015-12-17  8:45 ` [PATCH 1/3] regmap: core: Introduce register " Xiubo Li
  2015-12-17  8:45 ` [PATCH 2/3] regcache: Introduce the index parsing API Xiubo Li
@ 2015-12-17  8:45 ` Xiubo Li
  2 siblings, 0 replies; 4+ messages in thread
From: Xiubo Li @ 2015-12-17  8:45 UTC (permalink / raw)
  To: broonie; +Cc: linux-kernel, Xiubo Li

Here we introduce regcache_get_index(), which using register stride
order and bit rotation, will save some memory spaces for flat cache.
Though this will also lost some access performance, since the bit
rotation is used to get the index of the cache array, and this could
be ingored for memory I/O accessing.

Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
---
 drivers/base/regmap/regcache-flat.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c
index 686c9e0..218cf39 100644
--- a/drivers/base/regmap/regcache-flat.c
+++ b/drivers/base/regmap/regcache-flat.c
@@ -21,15 +21,16 @@ static int regcache_flat_init(struct regmap *map)
 	int i;
 	unsigned int *cache;
 
-	map->cache = kcalloc(map->max_register + 1, sizeof(unsigned int),
-			     GFP_KERNEL);
+	map->cache = kcalloc(regcache_get_index(map, map->max_register) + 1,
+			     sizeof(unsigned int), GFP_KERNEL);
 	if (!map->cache)
 		return -ENOMEM;
 
 	cache = map->cache;
 
 	for (i = 0; i < map->num_reg_defaults; i++)
-		cache[map->reg_defaults[i].reg] = map->reg_defaults[i].def;
+		cache[regcache_get_index(map, map->reg_defaults[i].reg)] =
+				map->reg_defaults[i].def;
 
 	return 0;
 }
@@ -47,7 +48,7 @@ static int regcache_flat_read(struct regmap *map,
 {
 	unsigned int *cache = map->cache;
 
-	*value = cache[reg];
+	*value = cache[regcache_get_index(map, reg)];
 
 	return 0;
 }
@@ -57,7 +58,7 @@ static int regcache_flat_write(struct regmap *map, unsigned int reg,
 {
 	unsigned int *cache = map->cache;
 
-	cache[reg] = value;
+	cache[regcache_get_index(map, reg)] = value;
 
 	return 0;
 }
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-12-17  8:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-17  8:45 [PATCH 0/3] Introduce reg stride order Xiubo Li
2015-12-17  8:45 ` [PATCH 1/3] regmap: core: Introduce register " Xiubo Li
2015-12-17  8:45 ` [PATCH 2/3] regcache: Introduce the index parsing API Xiubo Li
2015-12-17  8:45 ` [PATCH 3/3] regcache: flat: Introduce regcache_get_index() Xiubo Li

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.