From patchwork Sat Mar 24 23:24:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alban X-Patchwork-Id: 890738 X-Patchwork-Delegate: boris.brezillon@free-electrons.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=free.fr Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="mol0uD5b"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="Ck5kvXd8"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 408YM60SW2z9ryk for ; Mon, 26 Mar 2018 10:26:42 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=p48KJdDe/nkH9oyMghCyTY0DUzj2WFTmFwbvbdMIU24=; b=mol0uD5bCnU1ofBlpQkxAiOkgX 94QHpRyLBnGjO+b7/GYaqeLRekYxWV0UxDhfBsHoxSNCM3seQaGl82iOXZ5H3lSNiQEqDlb8BvBZA mqbMWZnnZ5yK/+VJhHIxdbTm+RtlsQoOeVcIe8rJq8Rkc3UBxNmVhlSYW+FX9W1NbwhNeUrcMKkYb XDjVYTLFscgyiC4m+iaXkOxRNEtOG55iNA/25WLUOv1p34hflilNdIlW3uo3fWiKiYwJb/yMvu2LM OScoGJQ+Z40Xbmuzo+DOMbXQrY1HWTi8yv80tWINJKqoWhutggwMctMmnAmp6oktLEJ24YI1/aPeS bGDprlTA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1f0F25-0006On-AS; Sun, 25 Mar 2018 23:26:37 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1f0Emz-0006ba-Ov for linux-mtd@bombadil.infradead.org; Sun, 25 Mar 2018 23:11:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=4Wpsb9fR1pNZwIiEIyGd5SjQ9ybyCGrCUDxq+pWR0zo=; b=Ck5kvXd8m2JP+lFVlV9CLzLSb C8nW6Y0uB1bXMl0MF7AF9pK0HOOh4Ta0OdhS12R358Abkd0CBVSIANs6duhsFmZCXieyAQNv+txkU 3Z1gkEgLB8qAHJ8m5l9fyjfnwKMHQtm9X+ea9QuTYSZuCub3sxy2R5qw/3LzfNDl86FY5FnHsri8k nPAtdkLfjFrm74w/R5nJXGp0kcosuE1h9xYDbFzavM2AZ8c4KyqBG0wZ7kfiZNxeOjkcMZNWvnQRz 03pCLtenseKtnb9wf9BgK9/wn4W+hi2r0tx51izY8EU630HSjgjuarDHLO1shH+BmygNzDA5yFY80 em07oq06g==; Received: from smtp4-g21.free.fr ([212.27.42.4]) by merlin.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1ezsZl-0004jg-BO for linux-mtd@lists.infradead.org; Sat, 24 Mar 2018 23:27:54 +0000 Received: from tock.home (unknown [IPv6:2a02:8108:4740:3978:85fa:b641:9ec1:a586]) (Authenticated sender: albeu) by smtp4-g21.free.fr (Postfix) with ESMTPA id 9B62319F574; Sun, 25 Mar 2018 00:26:41 +0100 (CET) From: Alban Bedel To: linux-kernel@vger.kernel.org Subject: [PATCH v3 3/3] mtd: Add support for reading MTD devices via the nvmem API Date: Sun, 25 Mar 2018 00:24:59 +0100 Message-Id: <1521933899-362-4-git-send-email-albeu@free.fr> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521933899-362-1-git-send-email-albeu@free.fr> References: <1521933899-362-1-git-send-email-albeu@free.fr> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180324_192753_585336_DDF5F85B X-CRM114-Status: GOOD ( 20.00 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.1 on merlin.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [212.27.42.4 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (albeu[at]free.fr) -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [212.27.42.4 listed in wl.mailspike.net] -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Boris Brezillon , devicetree@vger.kernel.org, Richard Weinberger , Marek Vasut , Rob Herring , Srinivas Kandagatla , linux-mtd@lists.infradead.org, Cyrille Pitchen , Alban Bedel , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Allow drivers that use the nvmem API to read data stored on MTD devices. For this the mtd devices are registered as read-only NVMEM providers. On OF systems only devices that have the 'nvmem-provider' property are registered, on non-OF system all MTD devices are registered. Signed-off-by: Alban Bedel --- Changelog: v2: * Moved to the MTD core instead of using notifiers * Fixed the Kconfig description v3: * Rebased on current kernel * Moved the code to mtdcore.c and removed the conditional compilation as suggested by Boris Brezillon * Fixed my name in From and Signed-off-by * Only allow root to read from the nvmem sysfs interface --- drivers/mtd/Kconfig | 1 + drivers/mtd/mtdcore.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/mtd.h | 2 ++ 3 files changed, 62 insertions(+) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 2a8ac68..911d869 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -1,5 +1,6 @@ menuconfig MTD tristate "Memory Technology Device (MTD) support" + imply NVMEM help Memory Technology Devices are flash, RAM and similar chips, often used for solid state file systems on embedded devices. This option diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 28553c8..d2a127c 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -478,6 +478,48 @@ int mtd_pairing_groups(struct mtd_info *mtd) } EXPORT_SYMBOL_GPL(mtd_pairing_groups); +static int mtd_nvmem_reg_read(void *priv, unsigned int offset, + void *val, size_t bytes) +{ + struct mtd_info *mtd = priv; + size_t retlen; + int err; + + err = mtd_read(mtd, offset, bytes, &retlen, val); + if (err && err != -EUCLEAN) + return err; + + return retlen == bytes ? 0 : -EIO; +} + +static int mtd_nvmem_add(struct mtd_info *mtd) +{ + struct nvmem_config config = {}; + + config.dev = &mtd->dev; + config.owner = THIS_MODULE; + config.reg_read = mtd_nvmem_reg_read; + config.size = mtd->size; + config.word_size = 1; + config.stride = 1; + config.read_only = true; + config.root_only = true; + config.priv = mtd; + + mtd->nvmem = nvmem_register(&config); + if (IS_ERR(mtd->nvmem)) { + /* Just ignore if there is no NVMEM support in the kernel */ + if (PTR_ERR(mtd->nvmem) == -ENOSYS) { + mtd->nvmem = NULL; + } else { + dev_err(&mtd->dev, "Failed to register NVMEM device\n"); + return PTR_ERR(mtd->nvmem); + } + } + + return 0; +} + static struct dentry *dfs_dir_mtd; /** @@ -560,6 +602,11 @@ int add_mtd_device(struct mtd_info *mtd) if (error) goto fail_added; + /* Add the nvmem provider */ + error = mtd_nvmem_add(mtd); + if (error) + goto fail_nvmem_add; + if (!IS_ERR_OR_NULL(dfs_dir_mtd)) { mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(&mtd->dev), dfs_dir_mtd); if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir)) { @@ -585,6 +632,8 @@ int add_mtd_device(struct mtd_info *mtd) __module_get(THIS_MODULE); return 0; +fail_nvmem_add: + device_unregister(&mtd->dev); fail_added: of_node_put(mtd_get_of_node(mtd)); idr_remove(&mtd_idr, i); @@ -627,6 +676,16 @@ int del_mtd_device(struct mtd_info *mtd) mtd->index, mtd->name, mtd->usecount); ret = -EBUSY; } else { + /* Try to remove the NVMEM provider */ + if (mtd->nvmem) { + ret = nvmem_unregister(mtd->nvmem); + if (ret) { + dev_err(&mtd->dev, + "Failed to unregister NVMEM device\n"); + goto out_error; + } + } + device_unregister(&mtd->dev); idr_remove(&mtd_idr, mtd->index); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 205eded..660b8e7 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -352,6 +353,7 @@ struct mtd_info { struct device dev; int usecount; struct mtd_debug_info dbg; + struct nvmem_device *nvmem; }; int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,