From patchwork Thu Sep 15 20:56:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 9334729 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BE0356089F for ; Thu, 15 Sep 2016 20:56:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF38E29B76 for ; Thu, 15 Sep 2016 20:56:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A407F29B88; Thu, 15 Sep 2016 20:56:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 29B9529B81 for ; Thu, 15 Sep 2016 20:56:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754147AbcIOU4i (ORCPT ); Thu, 15 Sep 2016 16:56:38 -0400 Received: from muru.com ([72.249.23.125]:42449 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751502AbcIOU4Y (ORCPT ); Thu, 15 Sep 2016 16:56:24 -0400 Received: from sampyla.monkeybrains.net (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 2F9EA8350; Thu, 15 Sep 2016 20:56:38 +0000 (UTC) From: Tony Lindgren To: Mark Brown Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH 1/2] regmap: Allow longer flag masks for read and write Date: Thu, 15 Sep 2016 13:56:10 -0700 Message-Id: <20160915205611.14046-2-tony@atomide.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160915205611.14046-1-tony@atomide.com> References: <20160915205611.14046-1-tony@atomide.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We currently only support masking the top bit for read and write flags. Let's make the mask unsigned long and mask the bytes based on the configured register length to make things more generic. This allows using regmap for more exotic combinations like SPI devices that need little endian addressing. Signed-off-by: Tony Lindgren --- drivers/base/regmap/internal.h | 4 ++-- drivers/base/regmap/regmap.c | 32 +++++++++++++++++++------------- include/linux/regmap.h | 8 ++++---- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -105,8 +105,8 @@ struct regmap { bool defer_caching; - u8 read_flag_mask; - u8 write_flag_mask; + unsigned long read_flag_mask; + unsigned long write_flag_mask; /* number of bits to (left) shift the reg value when formatting*/ int reg_shift; diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1319,12 +1319,26 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, return 0; } +static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes, + unsigned long mask) +{ + u8 *buf; + int i; + + if (!mask || !map->work_buf) + return; + + buf = map->work_buf; + + for (i = 0; i < max_bytes; i++) + buf[i] |= (mask >> (8 * i)) & 0xff; +} + int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { struct regmap_range_node *range; unsigned long flags; - u8 *u8 = map->work_buf; void *work_val = map->work_buf + map->format.reg_bytes + map->format.pad_bytes; void *buf; @@ -1393,8 +1407,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, } map->format.format_reg(map->work_buf, reg, map->reg_shift); - - u8[0] |= map->write_flag_mask; + regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, + map->write_flag_mask); /* * Essentially all I/O mechanisms will be faster with a single @@ -2270,7 +2284,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, unsigned int val_len) { struct regmap_range_node *range; - u8 *u8 = map->work_buf; int ret; WARN_ON(!map->bus); @@ -2287,15 +2300,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, } map->format.format_reg(map->work_buf, reg, map->reg_shift); - - /* - * Some buses or devices flag reads by setting the high bits in the - * register address; since it's always the high bits for all - * current formats we can do this here rather than in - * formatting. This may break if we get interesting formats. - */ - u8[0] |= map->read_flag_mask; - + regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, + map->read_flag_mask); trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); ret = map->bus->read(map->bus_context, map->work_buf, diff --git a/include/linux/regmap.h b/include/linux/regmap.h --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -241,9 +241,9 @@ typedef void (*regmap_unlock)(void *); * register cache support). * @num_reg_defaults: Number of elements in reg_defaults. * - * @read_flag_mask: Mask to be set in the top byte of the register when doing + * @read_flag_mask: Mask to be set in the top bytes of the register when doing * a read. - * @write_flag_mask: Mask to be set in the top byte of the register when doing + * @write_flag_mask: Mask to be set in the top bytes of the register when doing * a write. If both read_flag_mask and write_flag_mask are * empty the regmap_bus default masks are used. * @use_single_rw: If set, converts the bulk read and write operations into @@ -299,8 +299,8 @@ struct regmap_config { const void *reg_defaults_raw; unsigned int num_reg_defaults_raw; - u8 read_flag_mask; - u8 write_flag_mask; + unsigned long read_flag_mask; + unsigned long write_flag_mask; bool use_single_rw; bool can_multi_write;