From patchwork Fri Jun 29 09:40:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 10496045 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 48FB26016C for ; Fri, 29 Jun 2018 09:48:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D975298D4 for ; Fri, 29 Jun 2018 09:48:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 20A31298DA; Fri, 29 Jun 2018 09:48:07 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=unavailable 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 96460298D4 for ; Fri, 29 Jun 2018 09:48:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933159AbeF2Jre (ORCPT ); Fri, 29 Jun 2018 05:47:34 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:37773 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753590AbeF2Jkq (ORCPT ); Fri, 29 Jun 2018 05:40:46 -0400 Received: by mail-wm0-f67.google.com with SMTP id n17-v6so1372971wmh.2 for ; Fri, 29 Jun 2018 02:40:45 -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=h/FNWrso0KYb0FtvjK1i/NE6vmY1e5xQyWwcE+KEWFI=; b=R3jn183NteYS4ykkM1zHN3kG2kow5YhYIUZxfE0cRBG8cQARzRyQRvYA7VYEUNOkgU sR9pqrmagPqwAcj9sHhg0JBYj/tn08KmcuoVZFbhE53YZvSU+dYjd/5IbJQbw5XrDqJK iRE8eJsjKBHwVsic1V5ZHKUhfcEg5SVrIfTdYztK9wryjsPbxVz1RaMhtMPkwzssBcys DP5Hbr2Eo4mvN9AgS1lLI1zzrmLAVxt1IbUqZzKjgeTTZCxgHQIx0CiwSghhR54rnEOG +QvyVgGzbhY4nBvzDG7Nj17iwnAREj77bcsjHbcQlr108vcgOcGxpa4EmM7Nh2zWcQB8 K0Ng== 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=h/FNWrso0KYb0FtvjK1i/NE6vmY1e5xQyWwcE+KEWFI=; b=QSnONQdlbSqV/x+NBc6gNEkev66ClwJZ0i+21fJb4FOTxobo3Zc09qIyly//LEhDFy h38hynyY5+CPS/GySnaDiz50Hfnx7AxDRG/D95BR5rMrASabxsrjX1M35EZwnOcezf/8 YVLQGEhMGMV1NwUqlGQb5HOGPneVwGqW+FS/j9Um7aBzxtr0+Q7/ENz/Nipw3bHweOAN SkdACx5noKusUuHDhnPt7ClwR4KGfniQ/qD2q/sHbolIUBC0G043K4Of3ytVJy7UY14Q 1nzq1f0O9i5bmGquApI09oqS5ByHjZ66vAXffqvLBYORC+JPv21EUm0v8fN7AAjq82I2 Nj9Q== X-Gm-Message-State: APt69E1KOt03cuA13HayyOe1Wz6u17UUiZFcJCz4VCQBZdlJDhLJ7vpK QmEKhiseJCt29J06IsG2eAY5/A== X-Google-Smtp-Source: AAOMgpeWekvZVrWRVwPLeQ0h+yF5iTQuAuezdeCepqs2wz8KYQgWnOmJNINpsqUtP1kIH0f1Pnk2uw== X-Received: by 2002:a1c:d884:: with SMTP id p126-v6mr1148161wmg.110.1530265244681; Fri, 29 Jun 2018 02:40:44 -0700 (PDT) Received: from brgl-bgdev.lan (LFbn-NIC-1-55-10.w2-15.abo.wanadoo.fr. [2.15.147.10]) by smtp.gmail.com with ESMTPSA id d102-v6sm1386394wma.10.2018.06.29.02.40.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 29 Jun 2018 02:40:44 -0700 (PDT) From: Bartosz Golaszewski To: Sekhar Nori , Kevin Hilman , Russell King , Grygorii Strashko , "David S . Miller" , Srinivas Kandagatla , Lukas Wunner , Rob Herring , Florian Fainelli , Dan Carpenter , Ivan Khoronzhuk , David Lechner , Greg Kroah-Hartman , Andrew Lunn , Jonathan Corbet Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, netdev@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH v4 01/18] nvmem: add support for cell lookups Date: Fri, 29 Jun 2018 11:40:22 +0200 Message-Id: <20180629094039.7543-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180629094039.7543-1-brgl@bgdev.pl> References: <20180629094039.7543-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 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 b5b0cdc21d01..2495550cbbc4 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 * @@ -936,7 +1007,11 @@ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id) return cell; } - 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) {