From patchwork Wed Mar 20 05:53:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gaurav Kohli X-Patchwork-Id: 10860869 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7145E13B5 for ; Wed, 20 Mar 2019 05:53:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AC6C2999F for ; Wed, 20 Mar 2019 05:53:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3EFD5299A2; Wed, 20 Mar 2019 05:53:28 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 A88A12999F for ; Wed, 20 Mar 2019 05:53:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727018AbfCTFx0 (ORCPT ); Wed, 20 Mar 2019 01:53:26 -0400 Received: from alexa-out-blr-01.qualcomm.com ([103.229.18.197]:24848 "EHLO alexa-out-blr-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725900AbfCTFx0 (ORCPT ); Wed, 20 Mar 2019 01:53:26 -0400 X-IronPort-AV: E=Sophos;i="5.60,247,1549909800"; d="scan'208";a="454358" Received: from ironmsg02-blr.qualcomm.com ([10.86.208.131]) by alexa-out-blr-01.qualcomm.com with ESMTP/TLS/AES256-SHA; 20 Mar 2019 11:23:23 +0530 X-IronPort-AV: E=McAfee;i="5900,7806,9200"; a="7284346" Received: from gkohli-linux.qualcomm.com ([10.204.78.26]) by ironmsg02-blr.qualcomm.com with ESMTP; 20 Mar 2019 11:23:23 +0530 Received: by gkohli-linux.qualcomm.com (Postfix, from userid 427023) id 933EB3B35; Wed, 20 Mar 2019 11:23:22 +0530 (IST) From: Gaurav Kohli To: srinivas.kandagatla@linaro.org, linux-kernel@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org, Shiraz Hashim , Gaurav Kohli Subject: [PATCH v0] nvmem: core: Export nvmem cell info to userspace Date: Wed, 20 Mar 2019 11:23:21 +0530 Message-Id: <1553061201-28894-1-git-send-email-gkohli@codeaurora.org> X-Mailer: git-send-email 1.9.1 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Shiraz Hashim Existing nvmem framework export full register space as nvmem binary, but not exporting child node of nvmem which is nvmem cell. Kernel can read the specific cell by using nvmem_cell_read but userspace don't have such provision. Add framework to export nvmem cell as well, So userspace can use it directly. Signed-off-by: Shiraz Hashim Signed-off-by: Gaurav Kohli Co-developed-by: Gaurav Kohli diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index f24008b..e4b6160 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -47,6 +47,7 @@ struct nvmem_cell { int nbits; struct device_node *np; struct nvmem_device *nvmem; + struct bin_attribute attr; struct list_head node; }; @@ -99,6 +100,27 @@ static ssize_t type_show(struct device *dev, return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); } +static ssize_t bin_attr_nvmem_cell_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t pos, size_t count) +{ + struct nvmem_cell *cell; + size_t len; + u8 *data; + + if (attr->private) + cell = attr->private; + else + return -EINVAL; + + data = nvmem_cell_read(cell, &len); + + len = (len > count) ? count : len; + memcpy(buf, data, len); + + return len; +} + static DEVICE_ATTR_RO(type); static struct attribute *nvmem_attrs[] = { @@ -324,6 +346,7 @@ static void nvmem_cell_drop(struct nvmem_cell *cell) { blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell); mutex_lock(&nvmem_mutex); + device_remove_bin_file(&cell->nvmem->dev, &cell->attr); list_del(&cell->node); mutex_unlock(&nvmem_mutex); of_node_put(cell->np); @@ -341,8 +364,24 @@ static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem) static void nvmem_cell_add(struct nvmem_cell *cell) { + int rval; + struct bin_attribute *nvmem_cell_attr = &cell->attr; + mutex_lock(&nvmem_mutex); list_add_tail(&cell->node, &cell->nvmem->cells); + + /* add attr for this cell */ + nvmem_cell_attr->attr.name = cell->name; + nvmem_cell_attr->attr.mode = 0400; + nvmem_cell_attr->private = cell; + nvmem_cell_attr->size = cell->bytes; + nvmem_cell_attr->read = bin_attr_nvmem_cell_read; + rval = device_create_bin_file(&cell->nvmem->dev, nvmem_cell_attr); + if (rval) { + dev_err(&cell->nvmem->dev, + "Failed to create cell binary file %d\n", rval); + } + mutex_unlock(&nvmem_mutex); blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell); }