From patchwork Thu Aug 30 12:14:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 10581635 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 8DBAC139B for ; Thu, 30 Aug 2018 12:16:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77EAC2B45B for ; Thu, 30 Aug 2018 12:16:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A3BE2B66B; Thu, 30 Aug 2018 12:16:19 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B81C82B45B for ; Thu, 30 Aug 2018 12:16:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=MjoHO9Y5IYaAyQaAik8i7jU8X0PTt5kRgsvPMxBeGEk=; b=ZirJWxPHH6DWD7 7VrtyDtkF46jmYrqZtcwFVVqdIGWqkyLUrAc+fo6aFrJ3oaqXgnLYaSFp1uGUSITD8eml61yGdjlu dgDWaO6yDICeGeMX2KbkM0qgjkNOfEo1qnrJuHarHHn7kQ7sFGA2hYSnjsQm7ZKlSzEeHWQOV/WN0 YOfMB2HJ7st3sBq2UPtEhH4yY4wKx4iAxf8mhmyDl7IMkvyxry6Jfeyr89NFuPgZcgJAabR3vuX5N QB4OLOFlfnvu/zSl4OcqaF2Gp7tuUQrXLb/gEhPTauh8e3gv6LqcojA6yDNEp+OVGac33dvY2MTm8 wx3YkFgzr3rSfscoKOkQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fvLrl-0008LK-J5; Thu, 30 Aug 2018 12:16:01 +0000 Received: from mail-lf1-f66.google.com ([209.85.167.66]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fvLr7-0006sq-1f for linux-arm-kernel@lists.infradead.org; Thu, 30 Aug 2018 12:15:35 +0000 Received: by mail-lf1-f66.google.com with SMTP id m26-v6so7013302lfb.0 for ; Thu, 30 Aug 2018 05:15:10 -0700 (PDT) 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=1MedcM4V+7dGcKaRYYIgXvFYAsYq2HqE222toUzVIdE=; b=nuD4CCuJv2fXHFqhhWXL7wiSeEkVMzAbXFwb6CVm4TH/JhRkZ1t3Me/FD4jqvxg9nr ty0tJ2W1adE9q9qaAd6mkRcyyxRIM/aEkA/EWsBxE976AlM5Joiz3A50QMygttFRmvGt YWf8naMmB01XDeT2JhbRXTwgWV57wk9JLG77yUgbs1pivkYJHHatk2zF1fc451IGL4LS SSBM3C/h5r6mrSrCiFbvq2RRbNYoxUJgDQshCqrHuhInQvTeYJPqTc5nh7C5QybdRKlu +Jkzq+ANTqi5lfyItbcHGcgfRKtFLdajzUbrl3xc2YlLpl0pKvNAeboIo9AstfcgfE85 z+2g== X-Gm-Message-State: APzg51CWoeWJKeKlb4z57Nu5vnVZdAkTym43SX1IWnDxoF+f1VP7tY5f dXot+JUeLnO5n67BJr+6T6Y= X-Google-Smtp-Source: ANB0VdYGWDOJRPvFkMw/Oymf6jH8vl4/MW+OnyraQ/eTyIeSTSm1iUwDQCeeatpHwieFSysd704zgQ== X-Received: by 2002:a19:7118:: with SMTP id m24-v6mr6022572lfc.6.1535631308928; Thu, 30 Aug 2018 05:15:08 -0700 (PDT) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id b68-v6sm1224845ljb.62.2018.08.30.05.15.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Aug 2018 05:15:08 -0700 (PDT) Date: Thu, 30 Aug 2018 15:14:56 +0300 From: Matti Vaittinen To: corbet@lwn.net, mturquette@baylibre.com, sboyd@kernel.org, linux@armlinux.org.uk, andrew.smirnov@gmail.com, robh@kernel.org, sre@kernel.org, linux@roeck-us.net, sjhuang@iluvatar.ai, matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Subject: [PATCH 1/2] clk: clkdev/of_clk - add managed lookup and provider registrations Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.2 (2017-12-15) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180830_051521_240734_1CCBA82D X-CRM114-Status: GOOD ( 20.41 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: heikki.haikola@fi.rohmeurope.com, linux-doc@vger.kernel.org, mikko.mutanen@fi.rohmeurope.com, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP With MFD devices the clk properties may be contained in MFD (parent) 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. Also clkdev registration lacks of managed registration functions and it seems quite many drivers do not drop clkdev lookups at exit. Add devm_clk_hw_register_clkdev and devm_clk_release_clkdev to ease lookup releasing at exit. Signed-off-by: Matti Vaittinen --- Documentation/driver-model/devres.txt | 3 + drivers/clk/clk.c | 28 ++++++-- drivers/clk/clkdev.c | 122 ++++++++++++++++++++++++++-------- include/linux/clk-provider.h | 4 ++ include/linux/clkdev.h | 4 ++ 5 files changed, 129 insertions(+), 32 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 15720cd17958..20dac9ffd3e0 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -238,6 +238,9 @@ 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() + devm_clk_release_clkdev() DMA dmaenginem_async_device_register() diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d31055ae6ec6..fd0bc6421269 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3798,12 +3798,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), @@ -3811,10 +3811,9 @@ 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); + *ptr = of_node; + ret = of_clk_add_hw_provider(of_node, get, data); if (!ret) { - *ptr = np; devres_add(dev, ptr); } else { devres_free(ptr); @@ -3822,8 +3821,25 @@ int devm_of_clk_add_hw_provider(struct device *dev, return ret; } +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); +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 diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 9ab3db8b3988..f6100b6e06fd 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -401,6 +401,25 @@ static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw, return cl; } +static int do_clk_register_clkdev(struct clk_hw *hw, + struct clk_lookup **cl, const char *con_id, const char *dev_id) +{ + + if (IS_ERR(hw)) + return PTR_ERR(hw); + /* + * Since dev_id can be NULL, and NULL is handled specially, we must + * pass it as either a NULL format string, or with "%s". + */ + if (dev_id) + *cl = __clk_register_clkdev(hw, con_id, "%s", + dev_id); + else + *cl = __clk_register_clkdev(hw, con_id, NULL); + + return *cl ? 0 : -ENOMEM; +} + /** * clk_register_clkdev - register one clock lookup for a struct clk * @clk: struct clk to associate with all clk_lookups @@ -420,20 +439,10 @@ int clk_register_clkdev(struct clk *clk, const char *con_id, { struct clk_lookup *cl; - if (IS_ERR(clk)) - return PTR_ERR(clk); - - /* - * Since dev_id can be NULL, and NULL is handled specially, we must - * pass it as either a NULL format string, or with "%s". - */ - if (dev_id) - cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s", - dev_id); - else - cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL); - - return cl ? 0 : -ENOMEM; + if (!IS_ERR(clk)) + return do_clk_register_clkdev(__clk_get_hw(clk), &cl, con_id, + dev_id); + return PTR_ERR(clk); } EXPORT_SYMBOL(clk_register_clkdev); @@ -456,18 +465,79 @@ int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id, { struct clk_lookup *cl; - if (IS_ERR(hw)) - return PTR_ERR(hw); + return do_clk_register_clkdev(hw, &cl, con_id, dev_id); +} +EXPORT_SYMBOL(clk_hw_register_clkdev); - /* - * Since dev_id can be NULL, and NULL is handled specially, we must - * pass it as either a NULL format string, or with "%s". - */ - if (dev_id) - cl = __clk_register_clkdev(hw, con_id, "%s", dev_id); - else - cl = __clk_register_clkdev(hw, con_id, NULL); +static void devm_clkdev_release(struct device *dev, void *res) +{ + clkdev_drop(*(struct clk_lookup **)res); +} - return cl ? 0 : -ENOMEM; +static int devm_clk_match_clkdev(struct device *dev, void *res, void *data) +{ + struct clk_lookup **l = res; + + if (!l || !*l) { + WARN_ON(!l || !*l); + return 0; + } + return *l == data; } -EXPORT_SYMBOL(clk_hw_register_clkdev); + +/** + * devm_clk_release_clkdev - Resource managed clkdev lookup release + * @dev: device this lookup is bound + * @con_id: connection ID string on device + * @dev_id: format string describing device name + * + * Drop the clkdev lookup created with devm_clk_hw_register_clkdev. + * Normally this function will not need to be called and the resource + * management code will ensure that the resource is freed. + */ +void devm_clk_release_clkdev(struct device *dev, const char *con_id, + const char *dev_id) +{ + struct clk_lookup *cl; + int rval; + + cl = clk_find(dev_id, con_id); + WARN_ON(!cl); + rval = devres_release(dev, devm_clkdev_release, + &devm_clk_match_clkdev, cl); + WARN_ON(rval); +} +EXPORT_SYMBOL(devm_clk_release_clkdev); + +/** + * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw + * @dev: device this lookup is bound + * @hw: struct clk_hw to associate with all clk_lookups + * @con_id: connection ID string on device + * @dev_id: format string describing device name + * + * con_id or dev_id may be NULL as a wildcard, just as in the rest of + * clkdev. + * + * To make things easier for mass registration, we detect error clk_hws + * from a previous clk_hw_register_*() call, and return the error code for + * those. This is to permit this function to be called immediately + * after clk_hw_register_*(). + */ +int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw, + const char *con_id, const char *dev_id) +{ + int rval = -ENOMEM; + struct clk_lookup **cl; + + cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL); + if (cl) { + rval = do_clk_register_clkdev(hw, cl, con_id, dev_id); + if (!rval) + devres_add(dev, cl); + else + devres_free(cl); + } + return rval; +} +EXPORT_SYMBOL(devm_clk_hw_register_clkdev); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 08b1aa70a38d..94f9bae6490a 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -909,6 +909,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, diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index 4890ff033220..ccb32af5848b 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -52,4 +52,8 @@ int clk_add_alias(const char *, const char *, const char *, struct device *); int clk_register_clkdev(struct clk *, const char *, const char *); int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *); +int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw, + const char *con_id, const char *dev_id); +void devm_clk_release_clkdev(struct device *dev, const char *con_id, + const char *dev_id); #endif From patchwork Thu Aug 30 12:15:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 10581637 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 214845A4 for ; Thu, 30 Aug 2018 12:18:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BCE92BBED for ; Thu, 30 Aug 2018 12:18:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F258D2BBFF; Thu, 30 Aug 2018 12:18:39 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6C86B2BBED for ; Thu, 30 Aug 2018 12:18:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=U0vyD84xWSUgLx5CxBMWtpvXh5aADKmHbPA6hpW3J50=; b=p6ftvdQLHp566P STTUtkpcwIA4IqGogOcNJD/XUOuOPeLzRvcE1WcQOTo+KKr5tFO0KwBJwaEONzDR1+7OPaexKXxRZ YqvDlzUA7m9Sds+0dBARpxJc2FC32jl559IhHSsHYRenTpNuMJRwzENX90sLPNpTiGiRbCEtbJuuS H8RFkEFpViU3fLdRiSI6GAb3lx7URWham68M24KVBJq+AJA3lnlHxB9D6Bxx7/LMP+dj8/UpnTXl/ F1gKNBiWDuPshPybUvYD4hKQtws5oBpdOuardkNdnL+lDcZR2ODwtG9hMBGnz62+lLZB+56V6HaWW R6rWMrrCQYkUVv5NWZxA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fvLu7-0000st-43; Thu, 30 Aug 2018 12:18:27 +0000 Received: from mail-lf1-f68.google.com ([209.85.167.68]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fvLrh-0008GO-RW for linux-arm-kernel@lists.infradead.org; Thu, 30 Aug 2018 12:16:08 +0000 Received: by mail-lf1-f68.google.com with SMTP id c29-v6so862667lfj.1 for ; Thu, 30 Aug 2018 05:15:47 -0700 (PDT) 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=g4KPi67myzeQ1FvF6NBuES+SArwvrUD1LTCBlE+pLLQ=; b=rQkzAuRWis/ezCN5kPj4rUIqhmad7TlHbTqUY7Yfav+pvPD7kh5fgvhimELS37Pe1T gWyeGHr1gYe5YriMlxsM0UjljeZBSkL64QW+jfz2UrvQuxnUFUwb/s0HJOcGRrPLVZr6 tiLVSeU6zveNwkCPaj6djsOa0jVUxbu3sRK5RFlnnzL4FH6bf/TxOn6qumAFPq2FNYTI 59ZgfSUcNPRjhVFHg1Pv3/CF+kxZfCMkq12frU/VSn7QjEsMtGBwDTeyrfPkQszyJI0/ 5GRPrOJoB8bbqO5AwA36szy5Fly4Zyuecpq7ZoWieoaZoRpteQGSdnExTno9ZkL3bklv DT8w== X-Gm-Message-State: APzg51CmLnEZCSY92x21GNrKSiccpn+enqdPkvRXuM/xLMZdOZr/JNVq 9LTpX9TeHdoAEuW9qaXs4Zc= X-Google-Smtp-Source: ANB0VdZjBhrOjmNhq0/6cN/thlOtfv1z79VJJ7SYto4VTIiOsiPKk0c6eC2BNXmHsrG8pGgA4whDDw== X-Received: by 2002:a19:a2c1:: with SMTP id l184-v6mr4101751lfe.129.1535631345764; Thu, 30 Aug 2018 05:15:45 -0700 (PDT) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id r22-v6sm1219224ljh.22.2018.08.30.05.15.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Aug 2018 05:15:45 -0700 (PDT) Date: Thu, 30 Aug 2018 15:15:32 +0300 From: Matti Vaittinen To: corbet@lwn.net, mturquette@baylibre.com, sboyd@kernel.org, linux@armlinux.org.uk, andrew.smirnov@gmail.com, robh@kernel.org, sre@kernel.org, linux@roeck-us.net, sjhuang@iluvatar.ai, matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Subject: [PATCH 2/2] clk: bd718x7: Initial support for ROHM bd71837/bd71847 PMIC clock Message-ID: <0e6f19f99a4321d37472635c9210f6c13ac53147.1535630942.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) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180830_051557_975548_8B4199D0 X-CRM114-Status: GOOD ( 17.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: heikki.haikola@fi.rohmeurope.com, linux-doc@vger.kernel.org, mikko.mutanen@fi.rohmeurope.com, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP ROHM bd71837 and bd71847 contain 32768Hz clock gate. Support the clock using generic clock framework. Note, only bd71837 is tested but bd71847 should be identical what comes to clk parts. Signed-off-by: Matti Vaittinen --- drivers/clk/Kconfig | 6 +++ drivers/clk/Makefile | 1 + drivers/clk/clk-bd718x7.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 drivers/clk/clk-bd718x7.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 292056bbb30e..b2aee8fa4445 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -283,6 +283,12 @@ config COMMON_CLK_STM32H7 ---help--- Support for stm32h7 SoC family clocks +config COMMON_CLK_BD718XX + tristate "Clock driver for ROHM BD71837 PMIC MFD" + depends on MFD_ROHM_BD718XX + help + This driver supports ROHM BD71837 PMIC clock. + source "drivers/clk/actions/Kconfig" source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index a84c5573cabe..886dce9f9bec 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -21,6 +21,7 @@ endif obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o +obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c new file mode 100644 index 000000000000..df5f1068ce8e --- /dev/null +++ b/drivers/clk/clk-bd718x7.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 ROHM Semiconductors +// bd71837.c -- ROHM BD71837MWV clock driver + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct bd718xx_clk { + struct clk_hw hw; + u8 reg; + u8 mask; + struct platform_device *pdev; + struct bd718xx *mfd; +}; + +static int bd71837_clk_set(struct clk_hw *hw, int status) +{ + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status); +} + +static void bd71837_clk_disable(struct clk_hw *hw) +{ + int rv; + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + rv = bd71837_clk_set(hw, 0); + if (rv) + dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv); +} + +static int bd71837_clk_enable(struct clk_hw *hw) +{ + return bd71837_clk_set(hw, 1); +} + +static int bd71837_clk_is_enabled(struct clk_hw *hw) +{ + int enabled; + int rval; + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + rval = regmap_read(c->mfd->regmap, c->reg, &enabled); + + if (rval) + return rval; + + return enabled & c->mask; +} + +static const struct clk_ops bd71837_clk_ops = { + .prepare = &bd71837_clk_enable, + .unprepare = &bd71837_clk_disable, + .is_prepared = &bd71837_clk_is_enabled, +}; + +static int bd71837_clk_probe(struct platform_device *pdev) +{ + struct bd718xx_clk *c; + int rval = -ENOMEM; + const char *parent_clk; + struct device *parent = pdev->dev.parent; + struct bd718xx *mfd = dev_get_drvdata(parent); + struct clk_init_data init = { + .name = "bd718xx-32k-out", + .ops = &bd71837_clk_ops, + }; + + c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + + init.num_parents = 1; + parent_clk = of_clk_get_parent_name(parent->of_node, 0); + + init.parent_names = &parent_clk; + if (!parent_clk) { + dev_err(&pdev->dev, "No parent clk found\n"); + return -EINVAL; + } + + c->reg = BD718XX_REG_OUT32K; + c->mask = BD718XX_OUT32K_EN; + c->mfd = mfd; + c->pdev = pdev; + c->hw.init = &init; + + of_property_read_string_index(parent->of_node, + "clock-output-names", 0, &init.name); + + rval = devm_clk_hw_register(&pdev->dev, &c->hw); + if (!rval) { + rval = devm_clk_hw_register_clkdev(&pdev->dev, + &c->hw, init.name, NULL); + if (rval) + dev_warn(&pdev->dev, "Failed to register clkdev\n"); + if (parent->of_node) { + rval = devm_of_clk_add_parent_hw_provider(&pdev->dev, + of_clk_hw_simple_get, &c->hw); + if (rval) + dev_err(&pdev->dev, + "adding clk provider failed\n"); + } + } else { + dev_err(&pdev->dev, "failed to register 32K clk"); + } + + return rval; +} + +static struct platform_driver bd71837_clk = { + .driver = { + .name = "bd718xx-clk", + }, + .probe = bd71837_clk_probe, +}; + +module_platform_driver(bd71837_clk); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("BD71837 chip clk driver"); +MODULE_LICENSE("GPL");