From patchwork Mon Jun 25 15:50:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 10486891 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 0C939601D5 for ; Mon, 25 Jun 2018 15:57:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E0610285ED for ; Mon, 25 Jun 2018 15:57:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D5524285F0; Mon, 25 Jun 2018 15:57:10 +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 54910285ED for ; Mon, 25 Jun 2018 15:57:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754671AbeFYP4u (ORCPT ); Mon, 25 Jun 2018 11:56:50 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:42552 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752268AbeFYPvU (ORCPT ); Mon, 25 Jun 2018 11:51:20 -0400 Received: by mail-wr0-f196.google.com with SMTP id w10-v6so14199178wrk.9 for ; Mon, 25 Jun 2018 08:51:19 -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=oHMsMuVcLbezHzWoWPW3xXfcWIPuVOv4LhSPaLBYHKZfX3SiVTXYGq+nGC6XodtN87 IQXpv30knXAf6DPRozOKUDfto+GrYBjJ3iqkMAThRMfe2/8t8zio+Z2Q1UbfoM5zGTz/ itTvCPp+B4PCE2Iv42Bcsz9eGmvARj27olIZOUvPEy/Xh2EO50pkls9W8MgNUPl37So4 HyOJeCPDH/36zOvwsJX8Eh2tMIlDowH7frC8OwCFrzTpEX2XEkB1gxhQvWgIlQci0p9B lhrB+XiQU6H3oVGh193ObouLq7OBAZok6G4NddsoRzVmGmvQJbqdKGTIdSSne2mfNv8E bu4Q== 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=abbkmlr4Ez/TX2l7E2AaTxvtLSI7dVTkRVi3H5H8YhXOJBGL6CPx3zUR+9qb5z1mP1 1bNSdOp/dsNflAfOOnzJVDXqWnLwMz3EBhLx2uGtLjAyLIruClZqqLYJW3pf5InPZXit wOegkHhYXbuwucOd0IK64PImzZ5p04BLgB8QnnczmwZQ7vnJFB5cgYUsCqfYx2cpfCxZ KWQ+gH0ycOSlIwLvroP21wlAiUjPA9HM/+F2raikO2U0beH0LEwdrOXoPcaY7knWCmOX Gd3ma/up+AyQVZgSdFRtvQ/dF0NGB3o+GRX6pX2CAszWKBnzXc/VZY7Yn3WDrnrgRQlr PiQA== X-Gm-Message-State: APt69E0WhOcjxp385VvrKpa/YUKqBeNw6CPX2vSoi+RfjZmDadTcZSyD gdtlL+4QuKD9gLfCm/Xi6TOang== X-Google-Smtp-Source: AAOMgpfpQLUzcWZreWeTU3vNeA2YJmP0/OX+U8SfrfG1i023yA9CEDyjSodxdlnzYJh/DlEWhvv5lA== X-Received: by 2002:adf:f40a:: with SMTP id g10-v6mr10522782wro.256.1529941879338; Mon, 25 Jun 2018 08:51:19 -0700 (PDT) Received: from brgl-bgdev.home ([2a01:cb1d:af:5b00:e837:b8d5:48c1:571b]) by smtp.gmail.com with ESMTPSA id x16-v6sm3523737wro.13.2018.06.25.08.51.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Jun 2018 08:51:18 -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 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 01/14] nvmem: add support for cell lookups Date: Mon, 25 Jun 2018 17:50:12 +0200 Message-Id: <20180625155025.12567-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180625155025.12567-1-brgl@bgdev.pl> References: <20180625155025.12567-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) {