Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp971743imm; Wed, 8 Aug 2018 08:39:38 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwFv+cdbriv4id1wcGC/BxOg4R3VXNYWpvM8Rp4y9GVAU2ibH3wnuhwFcn2AChGhLJKRJ+X X-Received: by 2002:a62:9e5d:: with SMTP id s90-v6mr3534485pfd.214.1533742778464; Wed, 08 Aug 2018 08:39:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533742778; cv=none; d=google.com; s=arc-20160816; b=adKWz//hgwrkgf2BL84i32CkHw5OqBA1GnriP72gcKfsOzWtMnjDCWqEMahOuL6lhr sE1uMbByZ3OEH73/wZtSjqk1oGx3uDoJMzUqolFyUiu3nnlZ2zbBcdN76vLkdwOGoHS9 drkc6VWNHz5t9HibeWRQ17yiU2IEeY8lj9dpwTJm+b5xLOGM3FQ+yxUx8EfD/hlZ40kG 9ogeJUb9xaBcnO+BuG/bjKQ66W9Y49a2oGQxkIEH6XR2a8fdpZ4LxGh9W1IIV/JS5lV3 rHPxu5rUxFVplHprDCoQ+d4fxLJ4NHLRJx2zrw9OUGshkjh63cQ5LTM4sRX2za1HIv33 WhCA== 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:arc-authentication-results; bh=C6+lAOCD7xYYjqAwsyLpdNynP10DYfCMxlDsoPITD5U=; b=mleywikkOTcZqKmUKqAvZhtFnP81DB+Wov0H35fEM0ggTW9/7uF67voyEWfXYID7TM ip9J5g+YMlXVk9V2MoVEV9UTKVEEw1BENh2H4ZgZ8ekFTybYN1PtWH6e7uMiWgKO57Iq 9sU8t1GGpzyGqEtks/JHHxXFiReEtDMz9o0Fv8LlavP1mK7YuWyV9MeAOAz74qCbbAPF 76fEqHJq/5ePUzT6GJ+KuWwzxJB1IvL9U6cMi80nv9a7G2MHHDfWQXvi1bOpW6l8F2ei m50Z+INSe15vfWt8m1xyQFYCZ188XXRnK6lJ41Tauv9IixgNKOLIGVEv2HqaohLtn1PV jU3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=iykSHf10; 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 91-v6si3612696ply.405.2018.08.08.08.39.23; Wed, 08 Aug 2018 08:39:38 -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=iykSHf10; 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 S1727702AbeHHRxk (ORCPT + 99 others); Wed, 8 Aug 2018 13:53:40 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:33658 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727534AbeHHRxj (ORCPT ); Wed, 8 Aug 2018 13:53:39 -0400 Received: by mail-wr1-f67.google.com with SMTP id g6-v6so2425276wrp.0 for ; Wed, 08 Aug 2018 08:33:27 -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=iykSHf10yMyrpl8DK+aj/cdwz2SbHXCRaXdZtNJe3p9PGb0iT0ftaNi1BzDboHGfvL G3dWHCHn8XwpuDBz53tc9Uk2kF6ycWEx2FEYl4G717TBKqdwtAZqHBhv6uOVOsPiFJEt mVFxZJ4VCikZF1nUhGerB1dWPWmufG/76nwSjUsAqsxbVYqPJaMc/BpaMiZkILRXCpxN yu1OqSK0Fg9hQIYw9vajzfamUNX9DwCNwRit9wZ68R23C1HRR04gqcmclSxcjTzXRsy7 JSJGWwex37E0QsHA00GfTcbUp53L4Tl3mh7nggMqpO6SMW2tGtkN0kuea23oBM3t+4Gq zeaw== 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=Iaok7KYgsEr2HUW5A7H1J5XbZ4PpfWV2DmIV2k0h8iNEnI/+KpwwzDVF1676Bl19Xj PI3RNLu0BZRyytwsOvo2mj1hT9jzI+BlRihaQjqQXFRLlRo7p0CKt6d6Kb2qgUPGyJ+N qAxsvaYs6pnzp27CijdAYtEQqBzGVtD5kK6JjMBf2j8pVwwgrtA7nLtYQCMBPv+lzA0K 06uvqdhXkg4jsNsbTgDjGDYbf8qPLMfCgL0+7g0eRPnovSKgQXjXdhpIqKSrDpnpT1ZD baecNp+5TIbZO1uUjFX/q6n9+V1D7rT1X6LSAGGrtSj/AyYeY15Ul/MBKbXm09hN7v+2 bFJw== X-Gm-Message-State: AOUpUlF+ba0gycmVJjlwkBXH/pnROmAVrhuqLsTCw/3FJ3a1keVMvyVD Zmd/rVFZPEjjscLBAw2Im23Lqw== X-Received: by 2002:a5d:5088:: with SMTP id a8-v6mr2289235wrt.37.1533742407252; Wed, 08 Aug 2018 08:33:27 -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 s2-v6sm5240915wrw.52.2018.08.08.08.33.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Aug 2018 08:33:26 -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 01/28] nvmem: add support for cell lookups Date: Wed, 8 Aug 2018 17:31:23 +0200 Message-Id: <20180808153150.23444-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl> References: <20180808153150.23444-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 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) { -- 2.18.0