From patchwork Wed Apr 13 17:39:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 65747 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp142460qge; Wed, 13 Apr 2016 10:40:06 -0700 (PDT) X-Received: by 10.66.118.106 with SMTP id kl10mr14544036pab.78.1460569205834; Wed, 13 Apr 2016 10:40:05 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 78si2295724pfp.25.2016.04.13.10.40.05; Wed, 13 Apr 2016 10:40:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754158AbcDMRjx (ORCPT + 29 others); Wed, 13 Apr 2016 13:39:53 -0400 Received: from mail-wm0-f54.google.com ([74.125.82.54]:38542 "EHLO mail-wm0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754008AbcDMRjg (ORCPT ); Wed, 13 Apr 2016 13:39:36 -0400 Received: by mail-wm0-f54.google.com with SMTP id u206so90646663wme.1 for ; Wed, 13 Apr 2016 10:39:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=at5zhc3uqDtmx5wOYA6pseR96NX4rc4H5XzS0YG+5WY=; b=BaltUdc/j5VW1vkK5EUcbvW5rwZ9Q9EwcVHeQm3RJlXdiDqHzUVxBLaX0C7T8GeJa9 c/uiFc3bilsbcanherRrdAUl96C5Z7gqr0Lo4j1gt941C7NzdZ8Y75bZfo6WjOz25OpV 21LP1F65VFRSsVhJtVXBksVlxyW2qoRd39dCg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=at5zhc3uqDtmx5wOYA6pseR96NX4rc4H5XzS0YG+5WY=; b=Kmfq7qSp8X1Jlb/coJ7DxQ2QowdmzPwB+6Nb8CA/vUhBq2Fv48wk8otJDi4HVLY/G+ K5dOJEt1LbfIqiTlr4iHrCbRg4h3GoYKH1LQmI/OlDvp4DFq+HGLPxHaSRfuIldWrPGS L9Ns/I8mgsjmI6MWH2uIOLKR3Q2x/2a9Nes7WTgxq/77q1C6L4QXbQJhQbvCUrpI2Xky K6f20mjmVxlnfUfE9ZvljueZn9AdLBSGpWn9UJgmKbqDL0e+fkTPWtnHUS84AA4GHAur IhAXFC3c+3BlVArIjIKTe/TARHXPNk8CHm9lZbRbW8H+iK50fCMwUa/cS7B0uchFcLd5 hxLg== X-Gm-Message-State: AOPr4FXkhx9wiJjUV5Omk8q4rYlMLljfE8BO1rH6XpFty+jFnUjDfD36e4QEpEn3GLbguP0m X-Received: by 10.28.127.80 with SMTP id a77mr12057683wmd.84.1460569174509; Wed, 13 Apr 2016 10:39:34 -0700 (PDT) Received: from localhost.localdomain (host-92-17-247-99.as13285.net. [92.17.247.99]) by smtp.gmail.com with ESMTPSA id d131sm2317962wmd.12.2016.04.13.10.39.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Apr 2016 10:39:33 -0700 (PDT) From: Srinivas Kandagatla To: Mark Brown , Greg Kroah-Hartman Cc: Srinivas Kandagatla , Maxime Ripard , linux-kernel@vger.kernel.org, rjendra@qti.qualcomm.com Subject: [PATCH v1 3/3] nvmem: core: fix regmap accessor usage Date: Wed, 13 Apr 2016 18:39:14 +0100 Message-Id: <1460569154-25030-4-git-send-email-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1460569154-25030-1-git-send-email-srinivas.kandagatla@linaro.org> References: <1460569154-25030-1-git-send-email-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org With the recent patch of removing the raw accessors form regmap-mmio, broke the qfprom support. This patch attempts to fix that regression by adding check before calling regmap raw accessors functions. Without this patch nvmem providers based on regmap mmio would not work. Reported-by: Rajendra Nayak Fixes: 922a9f936e40 ("regmap: mmio: Convert to regmap_bus and fix accessor usage") Signed-off-by: Srinivas Kandagatla --- drivers/nvmem/core.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 8 deletions(-) -- 2.5.0 diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 0de3d87..8da631c 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -67,6 +67,80 @@ static struct lock_class_key eeprom_lock_key; #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) +static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int reg, + void *val, size_t bytes) +{ + int i, ret = 0; + struct regmap *map = nvmem->regmap; + size_t word_count = bytes / nvmem->word_size; + unsigned int ival; + u32 *u32_buf = val; + u16 *u16_buf = val; + u8 *u8_buf = val; + + if (regmap_can_raw_read(map)) + return regmap_raw_read(map, reg, val, bytes); + + for (i = 0; i < word_count; i++) { + ret = regmap_read(map, reg + i * nvmem->stride, &ival); + if (ret != 0) + return ret; + + switch (nvmem->word_size) { + case 4: + u32_buf[i] = ival; + break; + case 2: + u16_buf[i] = ival; + break; + case 1: + u8_buf[i] = ival; + break; + default: + return -EINVAL; + } + } + + return ret; +} + +static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int reg, + void *val, size_t bytes) +{ + int i, ret = 0; + struct regmap *map = nvmem->regmap; + size_t word_count = bytes / nvmem->word_size; + unsigned int ival; + u32 *u32_buf = val; + u16 *u16_buf = val; + u8 *u8_buf = val; + + if (regmap_can_raw_write(map)) + return regmap_raw_write(map, reg, val, bytes); + + for (i = 0; i < word_count; i++) { + switch (nvmem->word_size) { + case 4: + ival = u32_buf[i]; + break; + case 2: + ival = u16_buf[i]; + break; + case 1: + ival = u8_buf[i]; + break; + default: + return -EINVAL; + } + + ret = regmap_write(map, reg + i * nvmem->stride, ival); + if (ret != 0) + return ret; + } + + return ret; +} + static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t count) @@ -93,7 +167,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, count = round_down(count, nvmem->word_size); - rc = regmap_raw_read(nvmem->regmap, pos, buf, count); + rc = nvmem_reg_read(nvmem, pos, buf, count); if (IS_ERR_VALUE(rc)) return rc; @@ -127,7 +201,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, count = round_down(count, nvmem->word_size); - rc = regmap_raw_write(nvmem->regmap, pos, buf, count); + rc = nvmem_reg_write(nvmem, pos, buf, count); if (IS_ERR_VALUE(rc)) return rc; @@ -948,7 +1022,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, { int rc; - rc = regmap_raw_read(nvmem->regmap, cell->offset, buf, cell->bytes); + rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes); if (IS_ERR_VALUE(rc)) return rc; @@ -1014,7 +1088,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, *b <<= bit_offset; /* setup the first byte with lsb bits from nvmem */ - rc = regmap_raw_read(nvmem->regmap, cell->offset, &v, 1); + rc = nvmem_reg_read(nvmem, cell->offset, &v, 1); *b++ |= GENMASK(bit_offset - 1, 0) & v; /* setup rest of the byte if any */ @@ -1031,7 +1105,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, /* if it's not end on byte boundary */ if ((nbits + bit_offset) % BITS_PER_BYTE) { /* setup the last byte with msb bits from nvmem */ - rc = regmap_raw_read(nvmem->regmap, + rc = nvmem_reg_read(nvmem, cell->offset + cell->bytes - 1, &v, 1); *p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v; @@ -1064,7 +1138,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) return PTR_ERR(buf); } - rc = regmap_raw_write(nvmem->regmap, cell->offset, buf, cell->bytes); + rc = nvmem_reg_write(nvmem, cell->offset, buf, cell->bytes); /* free the tmp buffer */ if (cell->bit_offset || cell->nbits) @@ -1155,7 +1229,7 @@ int nvmem_device_read(struct nvmem_device *nvmem, if (!nvmem || !nvmem->regmap) return -EINVAL; - rc = regmap_raw_read(nvmem->regmap, offset, buf, bytes); + rc = nvmem_reg_read(nvmem, offset, buf, bytes); if (IS_ERR_VALUE(rc)) return rc; @@ -1183,7 +1257,7 @@ int nvmem_device_write(struct nvmem_device *nvmem, if (!nvmem || !nvmem->regmap) return -EINVAL; - rc = regmap_raw_write(nvmem->regmap, offset, buf, bytes); + rc = nvmem_reg_write(nvmem, offset, buf, bytes); if (IS_ERR_VALUE(rc)) return rc;