Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755677AbbLQIpn (ORCPT ); Thu, 17 Dec 2015 03:45:43 -0500 Received: from cmccmta3.chinamobile.com ([221.176.66.81]:9333 "EHLO cmccmta3.chinamobile.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752071AbbLQIo7 (ORCPT ); Thu, 17 Dec 2015 03:44:59 -0500 X-RM-TRANSID: 2eea56727606b8c-f32cf X-RM-SPAM-FLAG: 00000000 X-RM-TRANSID: 2ee1567276055ce-7eb07 From: Xiubo Li To: broonie@kernel.org Cc: linux-kernel@vger.kernel.org, Xiubo Li Subject: [PATCH 1/3] regmap: core: Introduce register stride order Date: Thu, 17 Dec 2015 16:45:28 +0800 Message-Id: <1450341930-5090-2-git-send-email-lixiubo@cmss.chinamobile.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1450341930-5090-1-git-send-email-lixiubo@cmss.chinamobile.com> References: <1450341930-5090-1-git-send-email-lixiubo@cmss.chinamobile.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3765 Lines: 105 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 --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/