From patchwork Thu Jun 28 14:32:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 10494167 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 64BFE60230 for ; Thu, 28 Jun 2018 14:40:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C0C42A0F7 for ; Thu, 28 Jun 2018 14:40:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49B1A2A568; Thu, 28 Jun 2018 14:40:18 +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 696E12A5CF for ; Thu, 28 Jun 2018 14:40:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966611AbeF1OkO (ORCPT ); Thu, 28 Jun 2018 10:40:14 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:52494 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966504AbeF1OdL (ORCPT ); Thu, 28 Jun 2018 10:33:11 -0400 Received: by mail-wm0-f65.google.com with SMTP id e69-v6so7063202wme.2 for ; Thu, 28 Jun 2018 07:33:10 -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=8RZaulrbWmAZvr/0f9ziR1QRlL3GNp+ezFc78oFzU7w=; b=sSLFjZwoKuVjz1S95I5Ogiwgd4zpClmvn1SQn1l4XRYZk3kF5YWnVT80+0dIjvxEJu VXuq0AaZYZJaOAKOW5pl9CXQzO58mOoo8Vogkt5v9iX8CadtBfSF5GOmcvtVJiTgh1CI PEuIOqzinfzRuvneQBAKUricCNvQsaRFWoQMHQliM4hvlw37AwgsCOi76gn8z0r/JcYu OIhnBrbzOyc6Z62IqL/UFsSDY3OiPie1O3DJZrwSdaZbOYrUG6jh3Kv41TftronyJle0 P4HygPxFqtoLurVGsiTH4ps91ZfwRqaz+GEl8zJLkHZi8qAxwNgRf+oY4O66Pm1AaIQg RFyQ== 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=8RZaulrbWmAZvr/0f9ziR1QRlL3GNp+ezFc78oFzU7w=; b=GuMPOfaluw4nDTyjS0ENV0xdwjm6K0FCO+bnnOgZovjNjojagaMxZ25XbCtazSPR/c yiGFRaD/VKGmXCyFuV7e2SzK8Cln54e/itPCWdRAG1YGfrz1mjEWjvfJ8ziHOhFFqwcC GTrOYTl8GyvSehZmXwUq0yT/zV/P135RrJDdObay1dYOeVqYvgwV2lygRbgcDxRJTIse oyQKbuffJlGc/ILTpRRsrch+9uy4k4dFMpWSN8NciWU6uKxyPHssjfpp9VPRX0GBBPoB MSd4JdqJOZYn9JSDxyrPwdJnRU57TWVn08S3jE7Maw3yhTVijuLG+3oaVfXBK3f07pLR bGpQ== X-Gm-Message-State: APt69E3nEzx3YKbGNTOZi/IhaJyS8HSFJscf7iw1451CcrbaA3PfnVEe UaANTSTy0uEQM57xa6P7k1hwlg== X-Google-Smtp-Source: AAOMgpeoapZX/mD6XYGgWsr+amVtH6z5LaxU7LmMI3Q++HuKX62vSHJfU+FBogHi2OELSug3/E1n+g== X-Received: by 2002:a1c:9c4c:: with SMTP id f73-v6mr8140987wme.141.1530196389780; Thu, 28 Jun 2018 07:33:09 -0700 (PDT) Received: from brgl-bgdev.baylibre.local (AStLambert-681-1-87-41.w90-86.abo.wanadoo.fr. [90.86.29.41]) by smtp.gmail.com with ESMTPSA id 4-v6sm8037499wmh.14.2018.06.28.07.33.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Jun 2018 07:33:09 -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 v3 01/18] nvmem: add support for cell lookups Date: Thu, 28 Jun 2018 16:32:27 +0200 Message-Id: <20180628143244.4561-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180628143244.4561-1-brgl@bgdev.pl> References: <20180628143244.4561-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 --- drivers/nvmem/core.c | 75 +++++++++++++++++++++++++++++++++- include/linux/nvmem-consumer.h | 6 +++ include/linux/nvmem-provider.h | 10 +++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index b5b0cdc21d01..c4889a4b26cf 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,37 @@ 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(-EPROBE_DEFER); + 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) + 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 +1005,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) {