Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp1604758imm; Fri, 7 Sep 2018 03:11:39 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdaaw24uxkMcJvk6GXg80p3tPHp/5qvzMLRlc9Fv7oaRG7qK6iZ809Zko10Nzm3rEHV2e8rV X-Received: by 2002:a63:d857:: with SMTP id k23-v6mr7464284pgj.106.1536315099241; Fri, 07 Sep 2018 03:11:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536315099; cv=none; d=google.com; s=arc-20160816; b=hGgrJaIj/oYSS+ClozF9/l6FmJCNht2DRwUxhajm/yrVPVLNMDwXyX//Zh14vl83QM v7c6hEjUpn0xdcwTqXoXkEBPWGGNMhdZaXZSlnrr6DgPZQUSKPa9U6Gj3BwlMRVqga5i +cTlqatLqHLWBb+GYKu97KFdejv9Cq5sQQlZNsTVPEuw6ts0bEz1Sc1x5VWBpnzaJnx0 cq+LpGRGjjx51vhSXCYJllqu93ewmP82UTuNBxc2ZzJi28/1IyW4CwjQSibjBkU13pbe LotyRbrC7M0noZEJp0KSAT2Y1GK4JikGMZQfvZA0ECEdrW9On0FOe2hAKTFISOYTpQH6 iUGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=O6kW/MWMreMdqngfmMkd7IkhX/posN3NlXBEDLsqaVk=; b=ZK55hCIJYSYPBGkhDSGYrxh6epfk2V81+0SlUM1j4XQAm4zVvbihd4wOscdLFo84Oq mwU0ht0OkJC9VCSdpZ5dhD/s3RctCCzIkEZZEWXFCWl3Vh/SM5czTeuqQ09P8ZSLFK5a oCQAeqzdgvYPvHV5URan0jFvj5CIWWHE7lxjm8SiCzf5NzmaWAudht2EswuFoabhnFjh 7wzlvGn8lMgQMdgnNXvlWduLyalGr/haMEHyqpGSJ/LMwC2TMYoMG8hbf2UTPOusX4y7 7NJHb4bnoXh8ydixA+ZJvxJRrgokC2aVDlK0nceAcndaTJO4dl3yfRKuH2ENUCw908q4 rtUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=B2LeJ69L; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w126-v6si7914282pfb.232.2018.09.07.03.11.23; Fri, 07 Sep 2018 03:11:39 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=B2LeJ69L; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728818AbeIGOsv (ORCPT + 99 others); Fri, 7 Sep 2018 10:48:51 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:42425 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728690AbeIGOsu (ORCPT ); Fri, 7 Sep 2018 10:48:50 -0400 Received: by mail-wr1-f68.google.com with SMTP id v17-v6so14348499wrr.9 for ; Fri, 07 Sep 2018 03:08:36 -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=O6kW/MWMreMdqngfmMkd7IkhX/posN3NlXBEDLsqaVk=; b=B2LeJ69LnpVEnygPtrvKbCTfC3GKdCl3LpnW/Opnqk9O6dGsko4UrPLNyOeLwJC/tB uy7s5P4gJnDKT+yYQ7lIa+wqYl2P48aLuDjmegkx2UNLXWpmuPolU3Fs7TeZh8hFBvyr z6bFP0uKAc7MubH3xzLjb+ZZea6jgPuQQiC+cWfd+yiWrUA00PPRZWalQi8yfv5cfxgU udparDXdn0LP7S+jrSSefg5gFrc3w0NWdIcMUHXza9/O+TGoMUpZr3bZDemXUiUt6fa5 d6164NMy9tATVxf8Ikoeg+AnbsLA/tSaQlVEN0QzxYq5Ydn19/NQK2JXUpJtPDFtediv bYTw== 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=O6kW/MWMreMdqngfmMkd7IkhX/posN3NlXBEDLsqaVk=; b=o0ArE2x+kavp7CYJq3ReojkNlpqOTd2k3PhBlA8ZXyD6lecBNMZ65HTxYJTR7KJ9sT qUAAn+gzskL4bnk9FguYlQjwU+TftcW3FxGVKAVoFJmvHIUzPm59wnMAIwP/nBHmeWGJ H/YfSqlFL45EGVtQN5jJ6516EdN/hsryu2+ID0+2/+kmQs823RZs7n1WYAeg0ULKZn4o wWkTMjHdx3sEnuC7MBXMyR0lstiPzMobvei6Cvjk0vk12IZIflR5XI69TtTR+Rh9xz2r FwPmp2/C718vfzZt1Jz8CAk3bYgInDpK3pRvyCbgyEB9xhDij4lsNDDNOOQFdksuNh0o fEPw== X-Gm-Message-State: APzg51D1Jh6H8M+PXrpwWE/HOEymbdDx5j9JC9vxHBEu5Am9p0RqKKss QWQBjokdsmrgCcTizKka7bnVNg== X-Received: by 2002:adf:ae5a:: with SMTP id u26-v6mr5780676wrd.246.1536314915443; Fri, 07 Sep 2018 03:08:35 -0700 (PDT) Received: from brgl-bgdev.baylibre.local (AStLambert-681-1-83-232.w90-86.abo.wanadoo.fr. [90.86.25.232]) by smtp.gmail.com with ESMTPSA id 72-v6sm6631619wrb.48.2018.09.07.03.08.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Sep 2018 03:08:34 -0700 (PDT) From: Bartosz Golaszewski To: Srinivas Kandagatla , "David S . Miller" , Mauro Carvalho Chehab , Greg Kroah-Hartman , Andrew Morton , Arnd Bergmann , Jonathan Corbet , Sekhar Nori , Kevin Hilman , David Lechner , Boris Brezillon , Andrew Lunn , Alban Bedel , Maxime Ripard , Chen-Yu Tsai Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Bartosz Golaszewski Subject: [PATCH v2 13/16] nvmem: add support for cell lookups from machine code Date: Fri, 7 Sep 2018 12:07:47 +0200 Message-Id: <20180907100750.14564-14-brgl@bgdev.pl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180907100750.14564-1-brgl@bgdev.pl> References: <20180907100750.14564-1-brgl@bgdev.pl> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Bartosz Golaszewski Add a way for machine code users to associate devices with nvmem cells. Signed-off-by: Bartosz Golaszewski --- drivers/nvmem/core.c | 143 +++++++++++++++++++++++++++------- include/linux/nvmem-machine.h | 16 ++++ 2 files changed, 132 insertions(+), 27 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index da7a9d5beb33..9e2f9c993a07 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -62,6 +62,9 @@ static DEFINE_IDA(nvmem_ida); static DEFINE_MUTEX(nvmem_cell_mutex); static LIST_HEAD(nvmem_cell_tables); +static DEFINE_MUTEX(nvmem_lookup_mutex); +static LIST_HEAD(nvmem_lookup_list); + static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -285,6 +288,18 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np) return to_nvmem_device(d); } +static struct nvmem_device *nvmem_find(const char *name) +{ + struct device *d; + + d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); + + if (!d) + return NULL; + + return to_nvmem_device(d); +} + static void nvmem_cell_drop(struct nvmem_cell *cell) { mutex_lock(&nvmem_mutex); @@ -421,6 +436,21 @@ nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index) return cell; } +static struct nvmem_cell * +nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) +{ + struct nvmem_cell *cell = NULL; + + mutex_lock(&nvmem_mutex); + list_for_each_entry(cell, &nvmem->cells, node) { + if (strcmp(cell_id, cell->name) == 0) + break; + } + mutex_unlock(&nvmem_mutex); + + return cell; +} + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) { struct device_node *parent, *child; @@ -691,22 +721,16 @@ int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) } EXPORT_SYMBOL(devm_nvmem_unregister); -static struct nvmem_device *__nvmem_device_get(struct device_node *np) +static struct nvmem_device * +__nvmem_device_get(struct device_node *np, const char *name) { struct nvmem_device *nvmem = NULL; - if (!np) - return ERR_PTR(-EINVAL); - mutex_lock(&nvmem_mutex); - - nvmem = of_nvmem_find(np); - if (!nvmem) { - mutex_unlock(&nvmem_mutex); - return ERR_PTR(-EPROBE_DEFER); - } - + nvmem = np ? of_nvmem_find(np) : nvmem_find(name); mutex_unlock(&nvmem_mutex); + if (!nvmem) + return ERR_PTR(-EPROBE_DEFER); if (!try_module_get(nvmem->owner)) { dev_err(&nvmem->dev, @@ -726,18 +750,6 @@ static void __nvmem_device_put(struct nvmem_device *nvmem) kref_put(&nvmem->refcnt, nvmem_device_release); } -static struct nvmem_device *nvmem_find(const char *name) -{ - struct device *d; - - d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); - - if (!d) - return NULL; - - return to_nvmem_device(d); -} - #if IS_ENABLED(CONFIG_OF) /** * of_nvmem_device_get() - Get nvmem device from a given id @@ -760,7 +772,7 @@ struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id) if (!nvmem_np) return ERR_PTR(-EINVAL); - return __nvmem_device_get(nvmem_np); + return __nvmem_device_get(nvmem_np, NULL); } EXPORT_SYMBOL_GPL(of_nvmem_device_get); #endif @@ -897,7 +909,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, if (!nvmem_np) return ERR_PTR(-EINVAL); - nvmem = __nvmem_device_get(nvmem_np); + nvmem = __nvmem_device_get(nvmem_np, NULL); of_node_put(nvmem_np); if (IS_ERR(nvmem)) return ERR_CAST(nvmem); @@ -913,6 +925,44 @@ 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_get_from_lookup(struct device *dev, const char *con_id) +{ + struct nvmem_cell *cell = ERR_PTR(-ENOENT); + struct nvmem_cell_lookup *lookup; + struct nvmem_device *nvmem; + const char *dev_id; + + if (!dev) + return ERR_PTR(-EINVAL); + + dev_id = dev_name(dev); + + mutex_lock(&nvmem_lookup_mutex); + + list_for_each_entry(lookup, &nvmem_lookup_list, node) { + if ((strcmp(lookup->dev_id, dev_id) == 0) && + (strcmp(lookup->con_id, con_id) == 0)) { + /* This is the right entry. */ + nvmem = __nvmem_device_get(NULL, lookup->nvmem_name); + if (!nvmem) { + /* Provider may not be registered yet. */ + cell = ERR_PTR(-EPROBE_DEFER); + goto out; + } + + cell = nvmem_find_cell_by_name(nvmem, + lookup->cell_name); + if (!cell) + goto out; + } + } + +out: + mutex_unlock(&nvmem_lookup_mutex); + return cell; +} + /** * nvmem_cell_get() - Get nvmem cell of device form a given cell name * @@ -925,10 +975,14 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get); */ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id) { - if (!dev->of_node) + if (dev->of_node) + return of_nvmem_cell_get(dev->of_node, cell_id); + + /* Only allow empty cell_id for DT systems. */ + if (!cell_id) return ERR_PTR(-EINVAL); - return of_nvmem_cell_get(dev->of_node, cell_id); + return nvmem_cell_get_from_lookup(dev, cell_id); } EXPORT_SYMBOL_GPL(nvmem_cell_get); @@ -1300,6 +1354,41 @@ void nvmem_del_cell_table(struct nvmem_cell_table *table) } EXPORT_SYMBOL_GPL(nvmem_del_cell_table); +/** + * nvmem_add_cell_lookups() - register a list of cell lookup entries + * + * @entries: array of cell lookup entries + * @nentries: number of cell lookup entries in the array + */ +void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) +{ + int i; + + mutex_lock(&nvmem_lookup_mutex); + for (i = 0; i < nentries; i++) + list_add_tail(&entries[i].node, &nvmem_lookup_list); + mutex_unlock(&nvmem_lookup_mutex); +} +EXPORT_SYMBOL_GPL(nvmem_add_cell_lookups); + +/** + * nvmem_del_cell_lookups() - remove a list of previously added cell lookup + * entries + * + * @entries: array of cell lookup entries + * @nentries: number of cell lookup entries in the array + */ +void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) +{ + int i; + + mutex_lock(&nvmem_lookup_mutex); + for (i = 0; i < nentries; i++) + list_del(&entries[i].node); + mutex_unlock(&nvmem_lookup_mutex); +} +EXPORT_SYMBOL_GPL(nvmem_del_cell_lookups); + /** * nvmem_dev_name() - Get the name of a given nvmem device. * diff --git a/include/linux/nvmem-machine.h b/include/linux/nvmem-machine.h index 1e199dfaacab..7859c08934d5 100644 --- a/include/linux/nvmem-machine.h +++ b/include/linux/nvmem-machine.h @@ -26,16 +26,32 @@ struct nvmem_cell_table { struct list_head node; }; +struct nvmem_cell_lookup { + const char *nvmem_name; + const char *cell_name; + const char *dev_id; + const char *con_id; + struct list_head node; +}; + #if IS_ENABLED(CONFIG_NVMEM) void nvmem_add_cell_table(struct nvmem_cell_table *table); void nvmem_del_cell_table(struct nvmem_cell_table *table); +void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); +void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); + #else /* CONFIG_NVMEM */ static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} +static inline void +nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {} +static inline void +nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {} + #endif /* CONFIG_NVMEM */ #endif /* ifndef _LINUX_NVMEM_MACHINE_H */ -- 2.18.0