From patchwork Fri Aug 10 08:04:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 10562373 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 4F128157B for ; Fri, 10 Aug 2018 08:06:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DFA82B57C for ; Fri, 10 Aug 2018 08:06:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2EC6C2B65D; Fri, 10 Aug 2018 08:06:34 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A93602B57C for ; Fri, 10 Aug 2018 08:06:33 +0000 (UTC) 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=24dyUBGh2fWnWDpT45Pq9RBQ41N9IhhBQgAOjGExHDU=; b=Qq7DqWdHt8oFxs9gW/jhFR9wH7 jbCgH3APsenOlSaUHbugiQqr/zBU4DVt3YAeNtHFqjZzR3miwZarPem5klCqDDmyiOLWI8OOt/xmS FldaQQiQalUXt4ot9mfs2cZr7bpbjv6LwAsEn29EEX1g5DehoQI+EToGdQBZ5/fC14MnHISbT2nzF ZF7eYwViOFhvzGqWDX33lHJeZKnidoMf+eHJYcjwV0FqfXrGhg3Ps9Dqy8f7a1WWMMmL/EQFrrijc /f+2ljg8qKuzhsa9J3591ytShVqyUWaMZIH6LU2Xo0EUSpOcQrMd126U4FuAVDPpQpP5P8x8SUX6I O2zx+IzA==; 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 1fo2RE-00035K-Eg; Fri, 10 Aug 2018 08:06:24 +0000 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fo2Qb-000298-MF for linux-arm-kernel@lists.infradead.org; Fri, 10 Aug 2018 08:05:49 +0000 Received: by mail-wm0-x243.google.com with SMTP id c14-v6so919233wmb.4 for ; Fri, 10 Aug 2018 01:05:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C6+lAOCD7xYYjqAwsyLpdNynP10DYfCMxlDsoPITD5U=; b=Fj32K78hjOSxM5NAqapijcKbRg/4larGEi8ftAd5tBajKY92mFowMxQQk18GW+qzWv zxrnIkq/69gbVfOxlq2MwcfBKvoO7EWf0UEi4osZ5146rntyi+b7HTFExQOF4+gd5S4e lxawCv1CpztTCSE2PZIiumjeKv0tagGNM+SGuvqHXu4OA+NmbngdtuX3/iBAwu5HHL2p r1F5VqEqMpsYoL7+NMYprdJg8b06eC7uR844xP1ZOSuzCMSbZaE+5EFoaIlz4lzqaKAp IJp6ksJXeDmy4LJPU/G4sGyKCre9FCbhAbo8EVuA7SnlPYJ6QLZWyzRm/LLLZ8DtnR6Q ywKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=C6+lAOCD7xYYjqAwsyLpdNynP10DYfCMxlDsoPITD5U=; b=POg+xXhu+0O+FZUPl8xadeDSgMp9RJbLkjrdceTJvISfPdioP5nEfQna+BbfoSMvZ3 ONWN2UvMF8abUJlKc6EhMHD9GFzy2MZfBVpxlVsh6Wn+GVdtJFB7PlU+WHJmJZvzAmel ux38U7FAsVLCGoCxv1vBSo6Mq3/azPXw+C/ihcGM6gyWeDGdU2J11l1Pr6QeeqGWREV5 djaEQ8qESCCV00iododUVsTen/HWrxd8NVFFKDZ6Mxvg6/IDLOHMRMv56RMkohlTVupD SET2s9go4w0adw7Z3EvCRnjB4ll8Ii7+kdumqnpdvxyRoB7phgifRLLE9T4EniVHwZUx 4U6Q== X-Gm-Message-State: AOUpUlFWZZwqyoPl/VF2+0E1zphQ5SNL0+CLjvydA4OFNutqFXQps6rr 60QDKKKkWFDLEKzA5uoMol2HWg== X-Google-Smtp-Source: AA+uWPzy3clBvGJg0JNyQdBbCp/prcqqEHgnMmGGNtBt3AvzUga0oigMCh8jYiBVJd4uCWcmRC7+Ww== X-Received: by 2002:a1c:28c2:: with SMTP id o185-v6mr804377wmo.40.1533888333968; Fri, 10 Aug 2018 01:05:33 -0700 (PDT) Received: from brgl-bgdev.lan (LFbn-MAR-1-609-89.w90-118.abo.wanadoo.fr. [90.118.185.89]) by smtp.gmail.com with ESMTPSA id h7-v6sm9546405wrs.8.2018.08.10.01.05.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Aug 2018 01:05:33 -0700 (PDT) From: Bartosz Golaszewski To: Jonathan Corbet , Sekhar Nori , Kevin Hilman , Russell King , Arnd Bergmann , Greg Kroah-Hartman , David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , Grygorii Strashko , "David S . Miller" , Srinivas Kandagatla , Naren , Mauro Carvalho Chehab , Andrew Morton , Lukas Wunner , Dan Carpenter , Florian Fainelli , Ivan Khoronzhuk , Sven Van Asbroeck , Paolo Abeni , Alban Bedel , Rob Herring , David Lechner , Andrew Lunn Subject: [PATCH v2 01/29] nvmem: add support for cell lookups Date: Fri, 10 Aug 2018 10:04:58 +0200 Message-Id: <20180810080526.27207-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180810080526.27207-1-brgl@bgdev.pl> References: <20180810080526.27207-1-brgl@bgdev.pl> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180810_010545_783710_377E6E12 X-CRM114-Status: GOOD ( 24.72 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-doc@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski , linux-mtd@lists.infradead.org, linux-i2c@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bartosz Golaszewski We can currently only register nvmem cells from device tree or by manually calling nvmem_add_cells(). The latter options however forces users to make sure that the nvmem provider with which the cells are associated is registered before the call. This patch proposes a new solution inspired by other frameworks that offer resource lookups (GPIO, PWM etc.). It adds functions that allow machine code to register nvmem lookup which are later lazily used to add corresponding nvmem cells and remove them if no longer needed. Signed-off-by: Bartosz Golaszewski Acked-by: Srinivas Kandagatla --- drivers/nvmem/core.c | 77 +++++++++++++++++++++++++++++++++- include/linux/nvmem-consumer.h | 6 +++ include/linux/nvmem-provider.h | 10 +++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 514d1dfc5630..329ea5b8f809 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -62,6 +62,9 @@ static DEFINE_IDA(nvmem_ida); static LIST_HEAD(nvmem_cells); static DEFINE_MUTEX(nvmem_cells_mutex); +static LIST_HEAD(nvmem_cell_lookups); +static DEFINE_MUTEX(nvmem_lookup_mutex); + #ifdef CONFIG_DEBUG_LOCK_ALLOC static struct lock_class_key eeprom_lock_key; #endif @@ -247,6 +250,41 @@ static const struct attribute_group *nvmem_ro_root_dev_groups[] = { NULL, }; +/** + * nvmem_add_lookup_table() - register a number of nvmem cell lookup entries + * + * @lookup: array of nvmem cell lookup entries + * @nentries: number of lookup entries in the array + */ +void nvmem_add_lookup_table(struct nvmem_cell_lookup *lookup, size_t nentries) +{ + int i; + + mutex_lock(&nvmem_lookup_mutex); + for (i = 0; i < nentries; i++) + list_add_tail(&lookup[i].list, &nvmem_cell_lookups); + mutex_unlock(&nvmem_lookup_mutex); +} +EXPORT_SYMBOL_GPL(nvmem_add_lookup_table); + +/** + * nvmem_del_lookup_table() - unregister a set of previously added nvmem cell + * lookup entries + * + * @lookup: array of nvmem cell lookup entries + * @nentries: number of lookup entries in the array + */ +void nvmem_del_lookup_table(struct nvmem_cell_lookup *lookup, size_t nentries) +{ + int i; + + mutex_lock(&nvmem_lookup_mutex); + for (i = 0; i < nentries; i++) + list_del(&lookup[i].list); + mutex_unlock(&nvmem_lookup_mutex); +} +EXPORT_SYMBOL_GPL(nvmem_del_lookup_table); + static void nvmem_release(struct device *dev) { struct nvmem_device *nvmem = to_nvmem_device(dev); @@ -916,6 +954,39 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, EXPORT_SYMBOL_GPL(of_nvmem_cell_get); #endif +static struct nvmem_cell *nvmem_cell_from_lookup(const char *cell_id) +{ + struct nvmem_cell *cell = ERR_PTR(-ENOENT); + struct nvmem_cell_lookup *lookup; + struct nvmem_device *nvmem; + int rc; + + mutex_lock(&nvmem_lookup_mutex); + + list_for_each_entry(lookup, &nvmem_cell_lookups, list) { + if (strcmp(cell_id, lookup->info.name) == 0) { + nvmem = nvmem_find(lookup->nvmem_name); + if (!nvmem) { + cell = ERR_PTR(-EPROBE_DEFER); + goto out; + } + + rc = nvmem_add_cells(nvmem, &lookup->info, 1); + if (rc) { + cell = ERR_PTR(rc); + goto out; + } + + cell = nvmem_cell_get_from_list(cell_id); + break; + } + } + +out: + mutex_unlock(&nvmem_lookup_mutex); + return cell; +} + /** * nvmem_cell_get() - Get nvmem cell of device form a given cell name * @@ -940,7 +1011,11 @@ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id) if (!cell_id) return ERR_PTR(-EINVAL); - return nvmem_cell_get_from_list(cell_id); + cell = nvmem_cell_get_from_list(cell_id); + if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER) + return cell; + + return nvmem_cell_from_lookup(cell_id); } EXPORT_SYMBOL_GPL(nvmem_cell_get); diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h index 4e85447f7860..f4b5d3186e94 100644 --- a/include/linux/nvmem-consumer.h +++ b/include/linux/nvmem-consumer.h @@ -29,6 +29,12 @@ struct nvmem_cell_info { unsigned int nbits; }; +struct nvmem_cell_lookup { + struct nvmem_cell_info info; + struct list_head list; + const char *nvmem_name; +}; + #if IS_ENABLED(CONFIG_NVMEM) /* Cell based interface */ diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 24def6ad09bb..6a17d722062b 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -17,6 +17,7 @@ struct nvmem_device; struct nvmem_cell_info; +struct nvmem_cell_lookup; typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, void *val, size_t bytes); typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, @@ -72,6 +73,9 @@ struct nvmem_config { struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); int nvmem_unregister(struct nvmem_device *nvmem); +void nvmem_add_lookup_table(struct nvmem_cell_lookup *lookup, size_t nentries); +void nvmem_del_lookup_table(struct nvmem_cell_lookup *lookup, size_t nentries); + struct nvmem_device *devm_nvmem_register(struct device *dev, const struct nvmem_config *cfg); @@ -92,6 +96,12 @@ static inline int nvmem_unregister(struct nvmem_device *nvmem) return -ENOSYS; } +static inline void +nvmem_add_lookup_table(struct nvmem_cell_lookup *lookup, size_t nentries) {} + +static inline void +nvmem_del_lookup_table(struct nvmem_cell_lookup *lookup, size_t nentries) {} + static inline struct nvmem_device * devm_nvmem_register(struct device *dev, const struct nvmem_config *c) {