From patchwork Tue Jun 26 10:22:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 10488689 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 76796602B3 for ; Tue, 26 Jun 2018 10:31:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 628462886E for ; Tue, 26 Jun 2018 10:31:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 573322887D; Tue, 26 Jun 2018 10:31:01 +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 D8F6C2886E for ; Tue, 26 Jun 2018 10:31:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934283AbeFZKai (ORCPT ); Tue, 26 Jun 2018 06:30:38 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:36991 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934294AbeFZKXQ (ORCPT ); Tue, 26 Jun 2018 06:23:16 -0400 Received: by mail-wm0-f65.google.com with SMTP id n17-v6so682677wmh.2 for ; Tue, 26 Jun 2018 03:23:15 -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=M2pBvISezV7UKcYvnKa/lLg3BIe8aDxcoHTMh7WCXlQ=; b=Jf6kZNap2OHB+GqlOIZq4Gx+Vx1zjHUneuabUkDqlpR9wlX2GsAJhlLoxdcgh0tcQh y9jBuioZ4DrFgB7ksz22jTnypQxDg0aqucdkSxybxWs3Hs3Rz2FOEJHWSVKaywKjQhD7 EAGWumTCwA/lz2APtjazbTZXC61aDGhdGw29Thsx1bGnwc5+t+ryolE8kMccsMiIkOrQ wTh5iA2wTwG99n3RqQWo7p/GvCNU/OTn6asPT4fifiPrCNIBLswiyFVMEExniskqa1iZ tHMIGkYJIFrRZWfTDj5dXXvc/OfYsi4o/zH6mpefaqKpdhCGvZdLRxqWklDLybjalqA+ rlMg== 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=M2pBvISezV7UKcYvnKa/lLg3BIe8aDxcoHTMh7WCXlQ=; b=pJ2AM+dxDP/A9H+FEEpHaBtNTRGOXclvEao1EjTZvzwJmuTMX8T1hhYLMKXklkvgSM 3PVgkAJlsflcmmXt4fh9mT9jGwn47uR4RGC7R70HgvCP6OANHm3ywEcQ4izLpsBVjVOV ihQ4ICyA7s+6F3knhod2bW0aotgviUbUyrU0Np0PRrHPoqMeMwfPXb4n/5HA4zUrscQD IuQM/SPtznH7SttVczORAb5MMv+nhr9z+34qpNxxLSH4Z03kvkYH+cZADJaNkyhrZU1H Idsp8dE6hzxUpf3euEOxJuguFqXXKXDQgdz7vYUFH7OK4/nfV+pMwxLUCCuk3ruokYRS v3sw== X-Gm-Message-State: APt69E0PskWuotwZI1pytZSMzj9RpwSGp3SmGupsZu3zNlvnbT9P6o9I 5kMkJwtBhydkS+Ol3sDvQo3X9Q== X-Google-Smtp-Source: AAOMgpdTkbn6MaJLwVthN9sNdmgxCnFJ1QA5AN6vZYNi1CLNPzne7m+Xjij3OmKQGyynI8ti7L9X2A== X-Received: by 2002:a1c:4787:: with SMTP id m7-v6mr1137894wmi.92.1530008594923; Tue, 26 Jun 2018 03:23:14 -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 203-v6sm2573852wmp.23.2018.06.26.03.23.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Jun 2018 03:23:14 -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 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 v2 01/15] nvmem: add support for cell lookups Date: Tue, 26 Jun 2018 12:22:31 +0200 Message-Id: <20180626102245.30711-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626102245.30711-1-brgl@bgdev.pl> References: <20180626102245.30711-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 a function that allows machine code to register nvmem lookup which are later lazily used to add corresponding nvmem cells. Signed-off-by: Bartosz Golaszewski --- drivers/nvmem/core.c | 57 +++++++++++++++++++++++++++++++++- include/linux/nvmem-consumer.h | 6 ++++ include/linux/nvmem-provider.h | 6 ++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index b5b0cdc21d01..a2e87b464319 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,23 @@ static const struct attribute_group *nvmem_ro_root_dev_groups[] = { NULL, }; +/** + * nvmem_register_lookup() - 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_register_lookup(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_register_lookup); + static void nvmem_release(struct device *dev) { struct nvmem_device *nvmem = to_nvmem_device(dev); @@ -916,6 +936,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 +987,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..766c0a96c113 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,8 @@ struct nvmem_config { struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); int nvmem_unregister(struct nvmem_device *nvmem); +void nvmem_register_lookup(struct nvmem_cell_lookup *lookup, size_t nentries); + struct nvmem_device *devm_nvmem_register(struct device *dev, const struct nvmem_config *cfg); @@ -92,6 +95,9 @@ static inline int nvmem_unregister(struct nvmem_device *nvmem) return -ENOSYS; } +static inline void +nvmem_register_lookup(struct nvmem_cell_lookup *lookup, size_t nentries) {} + static inline struct nvmem_device * devm_nvmem_register(struct device *dev, const struct nvmem_config *c) {