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: 10562351 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 958B0157B for ; Fri, 10 Aug 2018 08:05:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8584927F10 for ; Fri, 10 Aug 2018 08:05:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 794E92B575; Fri, 10 Aug 2018 08:05:43 +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,DKIM_SIGNED, DKIM_VALID,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 EDC3427F10 for ; Fri, 10 Aug 2018 08:05:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727746AbeHJKeV (ORCPT ); Fri, 10 Aug 2018 06:34:21 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:50632 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727518AbeHJKeU (ORCPT ); Fri, 10 Aug 2018 06:34:20 -0400 Received: by mail-wm0-f67.google.com with SMTP id s12-v6so935729wmc.0 for ; Fri, 10 Aug 2018 01:05:34 -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=fJWyNWGqNF/b6ZxljC+xBLvr6n/0B+mCjVV8EORZr4OKQTvLKgzBzHT8JRXRMxXQRS D+h7NjFUy73TvOsNwb3CLYG91Bxn5IhyX3PScSVmtuxoExUWlhpxGUdw9y/sfqQX7BXO iqs1pHicrflBrh0J6SimlS0QiCcXg8sf+EyHhB6XDiOySdMmtkMzpP9iXK/Oei/G280t vdy1ARlk9b+zrN+6BgbegkamK87zg/yw17kzYomgCocQquSaB/RMowrcIZu9dwOD2KHa N9D+LhgVLhABcCmyq2Yx/ucHhYFi1krKTQXlfBTngAo1IZX5lw9W5BV8HJSnCMWbJlWo z38g== X-Gm-Message-State: AOUpUlGE38wEdBSIWubObW6mB1t9kdk0FAFzD/yPD1W2DA/zC4+uG22f DDlRPSUrf2oAoUI+4rbaXtUZWw== 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 Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-i2c@vger.kernel.org, linux-mtd@lists.infradead.org, linux-omap@vger.kernel.org, netdev@vger.kernel.org, Bartosz Golaszewski 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> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.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) {