From patchwork Mon Feb 11 13:58:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 10805891 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 34F38746 for ; Mon, 11 Feb 2019 13:58:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23FB42A312 for ; Mon, 11 Feb 2019 13:58:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 17B6C2A43F; Mon, 11 Feb 2019 13:58:23 +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 9C0462A312 for ; Mon, 11 Feb 2019 13:58:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726107AbfBKN6W (ORCPT ); Mon, 11 Feb 2019 08:58:22 -0500 Received: from relay11.mail.gandi.net ([217.70.178.231]:46847 "EHLO relay11.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726025AbfBKN6W (ORCPT ); Mon, 11 Feb 2019 08:58:22 -0500 Received: from localhost (aaubervilliers-681-1-80-177.w90-88.abo.wanadoo.fr [90.88.22.177]) (Authenticated sender: thomas.petazzoni@bootlin.com) by relay11.mail.gandi.net (Postfix) with ESMTPSA id A3792100018; Mon, 11 Feb 2019 13:58:19 +0000 (UTC) From: Thomas Petazzoni To: Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Petazzoni Subject: [PATCH] clk: clk-gpio: add support for sleeping GPIOs in gpio-gate-clk Date: Mon, 11 Feb 2019 14:58:18 +0100 Message-Id: <20190211135818.10518-1-thomas.petazzoni@bootlin.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 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 The current implementation of gpio-gate-clk enables/disables the clock using the GPIO in the ->enable() and ->disable() clock callbacks. This requires the GPIO to be configurable in atomic contexts. While it is the case for most memory-mapped GPIO controllers, it is not the case for GPIO expanders on I2C or SPI. This commit extends the gpio-gate-clk to check whether the GPIO calls require sleeping or not. If sleeping is not required, the current implementation based on ->enable()/->disable() is kept. However, if sleeping is needed, we instead implement the logic in the ->prepare() and ->unprepare() hooks. Thanks to this, a gate clock connected to a GPIO on a GPIO expander can be controlled with the existing driver. Signed-off-by: Thomas Petazzoni --- drivers/clk/clk-gpio.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 6a43ce420492..f5d481713c7d 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -61,6 +61,35 @@ const struct clk_ops clk_gpio_gate_ops = { }; EXPORT_SYMBOL_GPL(clk_gpio_gate_ops); +static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw) +{ + struct clk_gpio *clk = to_clk_gpio(hw); + + gpiod_set_value_cansleep(clk->gpiod, 1); + + return 0; +} + +static void clk_sleeping_gpio_gate_unprepare(struct clk_hw *hw) +{ + struct clk_gpio *clk = to_clk_gpio(hw); + + gpiod_set_value_cansleep(clk->gpiod, 0); +} + +static int clk_sleeping_gpio_gate_is_prepared(struct clk_hw *hw) +{ + struct clk_gpio *clk = to_clk_gpio(hw); + + return gpiod_get_value_cansleep(clk->gpiod); +} + +const struct clk_ops clk_sleeping_gpio_gate_ops = { + .prepare = clk_sleeping_gpio_gate_prepare, + .unprepare = clk_sleeping_gpio_gate_unprepare, + .is_prepared = clk_sleeping_gpio_gate_is_prepared, +}; + /** * DOC: basic clock multiplexer which can be controlled with a gpio output * Traits of this clock: @@ -147,10 +176,16 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, const char *parent_name, struct gpio_desc *gpiod, unsigned long flags) { + const struct clk_ops *ops; + + if (gpiod_cansleep(gpiod)) + ops = &clk_sleeping_gpio_gate_ops; + else + ops = &clk_gpio_gate_ops; + return clk_register_gpio(dev, name, (parent_name ? &parent_name : NULL), - (parent_name ? 1 : 0), gpiod, flags, - &clk_gpio_gate_ops); + (parent_name ? 1 : 0), gpiod, flags, ops); } EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);