From patchwork Mon Dec 3 12:18:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 10709413 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F19B913BF for ; Mon, 3 Dec 2018 12:18:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC3412A98E for ; Mon, 3 Dec 2018 12:18:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CB4E82A98D; Mon, 3 Dec 2018 12:18:41 +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.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham 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 4158B2A98D for ; Mon, 3 Dec 2018 12:18:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726289AbeLCMT3 (ORCPT ); Mon, 3 Dec 2018 07:19:29 -0500 Received: from mail-lj1-f195.google.com ([209.85.208.195]:46039 "EHLO mail-lj1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725883AbeLCMT3 (ORCPT ); Mon, 3 Dec 2018 07:19:29 -0500 Received: by mail-lj1-f195.google.com with SMTP id s5-v6so11126665ljd.12; Mon, 03 Dec 2018 04:18:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=VuiEaW0Oj53yp3q4uxN2C3Fqx50TMkjVvsBbGOjHZUY=; b=p+a9KN07rlsH7xqyVQpQHhYcO+vL9ATVT69fkFQMES90aHXI7YybK2cRZvnASqVnuu tL29iGGRG9bF8WWjymK6hzPc59mZ3nvXbOL7ABe3XgIy+ry9TzaFuk1IJHya3HIah9xR NALJpPXXhdMnDL0NGZxUeeIlD5BzqE6EgR1MP+MTq/E/M+Mgn2qXAdgVYcv6L3df7NA8 9xPCyUzHDj7SfXvf58bw1wTutiuXiSMt4qqM4imAsF5UjIPejb+JB1reM2KNRLsiqWDA wgLMsTVNLV70OtDE2DUZS2mMIkIrLfjRRm0Xo5shbiKPal+xRTiEYXcSubpVk/AyS8JO vWuA== X-Gm-Message-State: AA+aEWaKHOOKQ4irTsSEN/7zNwTOubyg6O97pbbOMSVn8pO2NiBzSzUG sfLZFQ/7ubovKmGugFvoHl8= X-Google-Smtp-Source: AFSGD/XA0By5ECSehpqZO8rpWGHa5fzid7ZDNrkXSvC063FdQgEuCV198/ybPvKkV2wyFX5cxcZkuQ== X-Received: by 2002:a2e:9b52:: with SMTP id o18-v6mr9879341ljj.108.1543839517681; Mon, 03 Dec 2018 04:18:37 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id h85-v6sm2478439ljf.68.2018.12.03.04.18.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 03 Dec 2018 04:18:37 -0800 (PST) Date: Mon, 3 Dec 2018 14:18:24 +0200 From: Matti Vaittinen To: mazziesaccount@gmail.com, matti.vaittinen@fi.rohmeurope.com Cc: mturquette@baylibre.com, sboyd@kernel.org, cw00.choi@samsung.com, krzk@kernel.org, b.zolnierkie@samsung.com, linux@armlinux.org.uk, andy.gross@linaro.org, david.brown@linaro.org, pavel@ucw.cz, andrew.smirnov@gmail.com, lee.jones@linaro.org, pombredanne@nexb.com, sjhuang@iluvatar.ai, akshu.agrawal@amd.com, djkurtz@chromium.org, rafael.j.wysocki@intel.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v5 2/9] clk: of_clk - add managed provider registrations Message-ID: <72d98b6f8deca66d4182c37669ec4421977922b3.1543837442.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP With MFD devices the clk properties may be contained in MFD (parent) DT node. Current devm_of_clk_add_hw_provider assumes the clk is bound to MFD subdevice not to MFD device (parent). Add devm_of_clk_add_hw_provider_parent to tackle this issue. Signed-off-by: Matti Vaittinen --- Documentation/driver-model/devres.txt | 1 + drivers/clk/clk.c | 65 ++++++++++++++++++++++++++++++----- include/linux/clk-provider.h | 11 ++++++ 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index dbf14326243b..97c9c575b2af 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -238,6 +238,7 @@ CLOCK devm_clk_put() devm_clk_hw_register() devm_of_clk_add_hw_provider() + devm_of_clk_add_parent_hw_provider() devm_clk_hw_register_clkdev() DMA diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index af011974d4ec..30beb60bd8f9 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3893,12 +3893,12 @@ static void devm_of_clk_release_provider(struct device *dev, void *res) of_clk_del_provider(*(struct device_node **)res); } -int devm_of_clk_add_hw_provider(struct device *dev, +static int __devm_of_clk_add_hw_provider(struct device *dev, struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data), - void *data) + struct device_node *of_node, void *data) { - struct device_node **ptr, *np; + struct device_node **ptr; int ret; ptr = devres_alloc(devm_of_clk_release_provider, sizeof(*ptr), @@ -3906,19 +3906,62 @@ int devm_of_clk_add_hw_provider(struct device *dev, if (!ptr) return -ENOMEM; - np = dev->of_node; - ret = of_clk_add_hw_provider(np, get, data); - if (!ret) { - *ptr = np; + *ptr = of_node; + ret = of_clk_add_hw_provider(of_node, get, data); + if (!ret) devres_add(dev, ptr); - } else { + else devres_free(ptr); - } return ret; } + +/** + * devm_of_clk_add_hw_provider() - Managed clk provider node registration + * @dev: Device acting as the clock provider. Used for DT node and lifetime. + * @get: callback for decoding clk_hw + * @data: context pointer for @get callback. + * + * Returns 0 on success or an errno on failure. + * + * Registers clock provider for given device's node. Provider is automatically + * released at device exit. + */ +int devm_of_clk_add_hw_provider(struct device *dev, + struct clk_hw *(*get)(struct of_phandle_args *clkspec, + void *data), + void *data) +{ + return __devm_of_clk_add_hw_provider(dev, get, dev->of_node, data); +} EXPORT_SYMBOL_GPL(devm_of_clk_add_hw_provider); +/** + * devm_of_clk_add_parent_hw_provider() - Managed clk provider node registration + * @dev: Device acting as the clock provider. Provider's DT node is parent node. + * @get: callback for decoding clk_hw + * @data: context pointer for @get callback. + * + * Returns 0 on success or an errno on failure. + * + * Registers clock provider for given device's parent node. Usable in cases + * where it really is the parent node that contains the provider information. + * Typical use-cases are MFD devices where the MFD sub-device is handling + * actual clock HW but the MFD node (parent) is containing the clock + * information. + * + * Provider is automatically released at device exit. + */ +int devm_of_clk_add_parent_hw_provider(struct device *dev, + struct clk_hw *(*get)(struct of_phandle_args *clkspec, + void *data), + void *data) +{ + return __devm_of_clk_add_hw_provider(dev, get, dev->parent->of_node, + data); +} +EXPORT_SYMBOL_GPL(devm_of_clk_add_parent_hw_provider); + /** * of_clk_del_provider() - Remove a previously registered clock provider * @np: Device node pointer associated with clock provider @@ -3950,6 +3993,10 @@ static int devm_clk_provider_match(struct device *dev, void *res, void *data) return *np == data; } +/** + * devm_of_clk_del_provider() - Remove clock provider registered using devm + * @dev: Device to whose lifetime the clock provider was bound + */ void devm_of_clk_del_provider(struct device *dev) { int ret; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 60c51871b04b..a6663f084cf1 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -916,6 +916,10 @@ int devm_of_clk_add_hw_provider(struct device *dev, struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data), void *data); +int devm_of_clk_add_parent_hw_provider(struct device *dev, + struct clk_hw *(*get)(struct of_phandle_args *clkspec, + void *data), + void *data); void of_clk_del_provider(struct device_node *np); void devm_of_clk_del_provider(struct device *dev); struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, @@ -953,6 +957,13 @@ static inline int devm_of_clk_add_hw_provider(struct device *dev, { return 0; } +static inline int devm_of_clk_add_parent_hw_provider(struct device *dev, + struct clk_hw *(*get)(struct of_phandle_args *clkspec, + void *data), + void *data) +{ + return 0; +} static inline void of_clk_del_provider(struct device_node *np) {} static inline void devm_of_clk_del_provider(struct device *dev) {} static inline struct clk *of_clk_src_simple_get(