From patchwork Mon Jun 20 02:52:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 9186523 X-Patchwork-Delegate: sboyd@codeaurora.org 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 3F26C60756 for ; Mon, 20 Jun 2016 03:19:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 336DC22B26 for ; Mon, 20 Jun 2016 03:19:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2681123B23; Mon, 20 Jun 2016 03:19:18 +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=unavailable 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 4220022B26 for ; Mon, 20 Jun 2016 03:19:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752207AbcFTDTQ (ORCPT ); Sun, 19 Jun 2016 23:19:16 -0400 Received: from mirror2.csie.ntu.edu.tw ([140.112.30.76]:36686 "EHLO wens.csie.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752068AbcFTDTP (ORCPT ); Sun, 19 Jun 2016 23:19:15 -0400 Received: by wens.csie.org (Postfix, from userid 1000) id D59185F7A5; Mon, 20 Jun 2016 10:52:23 +0800 (CST) From: Chen-Yu Tsai To: Mark Brown , Lee Jones , Alessandro Zummo , Alexandre Belloni , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Maxime Ripard , Michael Turquette , Stephen Boyd Cc: Chen-Yu Tsai , rtc-linux@googlegroups.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [PATCH v3 1/8] regmap: Support bulk writes for devices without raw formatting Date: Mon, 20 Jun 2016 10:52:11 +0800 Message-Id: <1466391138-12862-2-git-send-email-wens@csie.org> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1466391138-12862-1-git-send-email-wens@csie.org> References: <1466391138-12862-1-git-send-email-wens@csie.org> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When doing a bulk writes from a device which lacks raw I/O support we fall back to doing register at a time reads but we still use the raw formatters in order to render the data into the word size used by the device (since bulk reads still operate on the device word size rather than unsigned ints). This means that devices without raw formatting such as those that provide reg_read() are not supported. Provide handling for them by copying the values read into native endian values of the appropriate size. This complements commit d5b98eb12420 ("regmap: Support bulk reads for devices without raw formatting"). Signed-off-by: Chen-Yu Tsai --- Changes since v2: none Changes since v1: none --- drivers/base/regmap/regmap.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index df2d2ef5d6b3..51fa7d66a393 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1777,8 +1777,6 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, size_t val_bytes = map->format.val_bytes; size_t total_size = val_bytes * val_count; - if (map->bus && !map->format.parse_inplace) - return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) return -EINVAL; @@ -1789,7 +1787,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, * * The first if block is used for memory mapped io. It does not allow * val_bytes of 3 for example. - * The second one is used for busses which do not have this limitation + * The second one is for busses that do not provide raw I/O. + * The third one is used for busses which do not have these limitations * and can write arbitrary value lengths. */ if (!map->bus) { @@ -1825,6 +1824,32 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, } out: map->unlock(map->lock_arg); + } else if (map->bus && !map->format.parse_inplace) { + const u8 *u8 = val; + const u16 *u16 = val; + const u32 *u32 = val; + unsigned int ival; + + for (i = 0; i < val_count; i++) { + switch (map->format.val_bytes) { + case 4: + ival = u32[i]; + break; + case 2: + ival = u16[i]; + break; + case 1: + ival = u8[i]; + break; + default: + return -EINVAL; + } + + ret = regmap_write(map, reg + (i * map->reg_stride), + ival); + if (ret) + return ret; + } } else if (map->use_single_write || (map->max_raw_write && map->max_raw_write < total_size)) { int chunk_stride = map->reg_stride;