Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp2588841imw; Wed, 6 Jul 2022 08:26:57 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tHWLpJjRwl1jovwYPv0G9teDHJO3TNRLFCZFf1xkoiQH6tIL0/sNwHs1fvgu6FiGKVQAl1 X-Received: by 2002:a17:90a:cc18:b0:1ef:839e:45b0 with SMTP id b24-20020a17090acc1800b001ef839e45b0mr23042637pju.156.1657121217385; Wed, 06 Jul 2022 08:26:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657121217; cv=none; d=google.com; s=arc-20160816; b=YV/qCZj7YVACgtqguBSK5Lv7cuMoS8jMYGdhGCwqkEpjaEPcVirYsnclzayToJNpLh wLGjieqo2txZuIcPoOHprIWQKPfXKmTElYU/L2GjkDdTsC93UXe8mc5UAa+sXnVDWiyw TgyZAk9dEw7b+UKzkEBhC5s4MKKzdKz1oA5wM8sVvK2MRsTGQaN84BG1U49Zgg5HYQy9 VYHP4gMPC8c5+V4BNmVpSg5lfm65bJbrjZC1CW8WUiyIPiibtBPMR0csBe7S++leqosD n2edA2Jv+PftLVGeWZG7oyu/F0WmyBkYNnhBgZ5PFR42aA3CW0qMcMid+3BmLDYFAGQy MvaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=5MyzPstAwbNGZEWJRgSFYxiR0DFtAmFf/jRZizSuqcw=; b=MXNWWSk28+hvvSBlYYdiyYy32dM1Ef8hbVHUaRgKOT9E1KWgSw8IkpuutYF45opBVs QKs4XZDiNpXhDqvUHHGaj1M+8DGtSnS/qT+YdAownzkzAzD3Yb90IVkd5/AYM8YNAbpw EqeZZt91RkmUilaXm/e+eI434iLlqjTCRj2WMfV0oi2fYdBe4rmpg+KC/6+9HBsVoTiS 93kg1r9+zMFJKAoOwCkt8gQLvAf2wq/vcHPLdX/GcdlvufWbJLmsF3k/NjOTDDf7wJZv O0yWtGqMHpIDzrmykn2BzeTLMGcCK5DuPlh9XZUImMlYt7o0f4khrpJT6bBvnVRocHVM 4KGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mj3LRXQX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 1-20020a170902c10100b0016a33d12363si16248783pli.193.2022.07.06.08.26.43; Wed, 06 Jul 2022 08:26:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mj3LRXQX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232915AbiGFPEm (ORCPT + 99 others); Wed, 6 Jul 2022 11:04:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231347AbiGFPEl (ORCPT ); Wed, 6 Jul 2022 11:04:41 -0400 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CDE0315A33 for ; Wed, 6 Jul 2022 08:04:39 -0700 (PDT) Received: by mail-wm1-x329.google.com with SMTP id f190so9001126wma.5 for ; Wed, 06 Jul 2022 08:04:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=5MyzPstAwbNGZEWJRgSFYxiR0DFtAmFf/jRZizSuqcw=; b=mj3LRXQXQS6StvqGOZV6yugtZVTIN9JdnhqyAg3ppfci1KsgUElEnrP6nbBHrPtEwH mrP5sMNlNA8NxVxcnRABA1NRUhD6tmmG8o1G8UbZxJrTsmEBs+oVEbKLaRUVKskBQ8Ay T+jEJz0gUQ/D7w/xPBe/QXvhce2vHW7Sd7XIr7QeNt/CGXm9pQRtWamhPjXCToKddyfI uJwVqdYjhOVwW4IJqkP8W14Yxvig09hiY2IGXC8y20OKsLfA2AX4dv1vcLIz55wMYdMI SsMwVU9UoCjCyYe+P/pElj2uQgk8FU03unEzXaFpSaABvNO9suztWV8UXyBNg6t+AbI2 T6OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=5MyzPstAwbNGZEWJRgSFYxiR0DFtAmFf/jRZizSuqcw=; b=ZnLv/bx+8BY2uAci3f0pCj3TJkrt7r17irOZHCDjgg9g2Y9mZ3Jn/YCuZBy5Qeey2e Ul+F59lWWFItETTDiIih50A5aPw23uBSMAO/WTAWfVIYIT03OBVNpkyACdbD1ROyKQA9 kFGQ8V+VOThH286Mq2s7HnWpmhVvWJ/3C5lLeTWGbN7NTTPaYPwb0+z9NGkMC0pM6P/g yHrtX+AT0LBnjtgdWGdgzpqq6J8nz2lQ/sBNqBoozjLqmDeWV5vXF6DlDKFUCjIztJOF kyOHIWHFT38c5PIHk9FwspL/JqsDpZzWInOTlNytIEp2c599s7EE2+1DhLvmhuOfjO+5 VAWQ== X-Gm-Message-State: AJIora9LA/vNGPk3G5v9v15pkASD0+Dw4j9t25d3pSA/bM35Jebtalan //EnS2+qUJIPZH4zQuXjRuMXZw== X-Received: by 2002:a1c:770c:0:b0:3a0:37ec:bbb9 with SMTP id t12-20020a1c770c000000b003a037ecbbb9mr46160208wmi.2.1657119878350; Wed, 06 Jul 2022 08:04:38 -0700 (PDT) Received: from localhost.localdomain ([94.52.112.99]) by smtp.gmail.com with ESMTPSA id v7-20020a1cac07000000b003a04e6410e0sm22443420wme.33.2022.07.06.08.04.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Jul 2022 08:04:37 -0700 (PDT) From: Abel Vesa To: Mike Turquette , Stephen Boyd , Bjorn Andersson , Dmitry Baryshkov , Konrad Dybcio Cc: linux-clk@vger.kernel.org, Linux Kernel Mailing List , linux-arm-msm@vger.kernel.org, Abel Vesa Subject: [RFC 1/2] clk: Add generic sync_state callback for disabling unused clocks Date: Wed, 6 Jul 2022 18:04:10 +0300 Message-Id: <20220706150411.708213-1-abel.vesa@linaro.org> X-Mailer: git-send-email 2.34.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There are unused clocks that need to stay enabled on clk_disable_unused, but rather should be disabled later on on sync_state. Provide a generic sync_state callback for the clock providers that register such clocks. Then, use the same mechanism as clk_disable_unused from that generic callback, but pass the device to make sure only the clocks belonging to the current clock provider get disabled, if unused. Also, during the default clk_disable_unused, if the driver that registered the clock has the generic clk_sync_state_disable_unused callback set for sync_state, leave its clocks enabled. Signed-off-by: Abel Vesa --- drivers/clk/clk.c | 67 +++++++++++++++++++++++++++--------- include/linux/clk-provider.h | 1 + 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 7fc191c15507..ea55806505c0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1218,19 +1218,31 @@ static void clk_core_disable_unprepare(struct clk_core *core) clk_core_unprepare_lock(core); } -static void __init clk_unprepare_unused_subtree(struct clk_core *core) +static void clk_unprepare_unused_subtree(struct clk_core *core, + struct device *dev) { struct clk_core *child; lockdep_assert_held(&prepare_lock); hlist_for_each_entry(child, &core->children, child_node) - clk_unprepare_unused_subtree(child); + clk_unprepare_unused_subtree(child, dev); + + if (dev && core->dev != dev) + return; + + /* + * clock will be unprepared on sync_state, + * so leave as is on clk_disable_unused + */ + if (!dev && dev_has_sync_state(core->dev) && + core->dev->driver->sync_state == clk_sync_state_disable_unused) + return; if (core->prepare_count) return; - if (core->flags & CLK_IGNORE_UNUSED) + if (!dev && core->flags & CLK_IGNORE_UNUSED) return; if (clk_pm_runtime_get(core)) @@ -1248,7 +1260,8 @@ static void __init clk_unprepare_unused_subtree(struct clk_core *core) clk_pm_runtime_put(core); } -static void __init clk_disable_unused_subtree(struct clk_core *core) +static void clk_disable_unused_subtree(struct clk_core *core, + struct device *dev) { struct clk_core *child; unsigned long flags; @@ -1256,7 +1269,18 @@ static void __init clk_disable_unused_subtree(struct clk_core *core) lockdep_assert_held(&prepare_lock); hlist_for_each_entry(child, &core->children, child_node) - clk_disable_unused_subtree(child); + clk_disable_unused_subtree(child, dev); + + if (dev && core->dev != dev) + return; + + /* + * clock will be disabled on sync_state, + * so leave as is on clk_disable_unused + */ + if (!dev && dev_has_sync_state(core->dev) && + core->dev->driver->sync_state == clk_sync_state_disable_unused) + return; if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_prepare_enable(core->parent); @@ -1269,7 +1293,7 @@ static void __init clk_disable_unused_subtree(struct clk_core *core) if (core->enable_count) goto unlock_out; - if (core->flags & CLK_IGNORE_UNUSED) + if (!dev && core->flags & CLK_IGNORE_UNUSED) goto unlock_out; /* @@ -1302,35 +1326,46 @@ static int __init clk_ignore_unused_setup(char *__unused) } __setup("clk_ignore_unused", clk_ignore_unused_setup); -static int __init clk_disable_unused(void) +static void __clk_disable_unused(struct device *dev) { struct clk_core *core; - if (clk_ignore_unused) { - pr_warn("clk: Not disabling unused clocks\n"); - return 0; - } - clk_prepare_lock(); hlist_for_each_entry(core, &clk_root_list, child_node) - clk_disable_unused_subtree(core); + clk_disable_unused_subtree(core, dev); hlist_for_each_entry(core, &clk_orphan_list, child_node) - clk_disable_unused_subtree(core); + clk_disable_unused_subtree(core, dev); hlist_for_each_entry(core, &clk_root_list, child_node) - clk_unprepare_unused_subtree(core); + clk_unprepare_unused_subtree(core, dev); hlist_for_each_entry(core, &clk_orphan_list, child_node) - clk_unprepare_unused_subtree(core); + clk_unprepare_unused_subtree(core, dev); clk_prepare_unlock(); +} + +static int __init clk_disable_unused(void) +{ + if (clk_ignore_unused) { + pr_warn("clk: Not disabling unused clocks\n"); + return 0; + } + + __clk_disable_unused(NULL); return 0; } late_initcall_sync(clk_disable_unused); +void clk_sync_state_disable_unused(struct device *dev) +{ + __clk_disable_unused(dev); +} +EXPORT_SYMBOL_GPL(clk_sync_state_disable_unused); + static int clk_core_determine_round_nolock(struct clk_core *core, struct clk_rate_request *req) { diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 72d937c03a3e..5d3ed2b14f2c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -679,6 +679,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock); +void clk_sync_state_disable_unused(struct device *dev); /** * clk_register_divider - register a divider clock with the clock framework * @dev: device registering this clock -- 2.34.3