From nobody Thu Feb 12 01:39:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25459C77B73 for ; Sun, 30 Apr 2023 11:26:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230165AbjD3L02 (ORCPT ); Sun, 30 Apr 2023 07:26:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229461AbjD3L01 (ORCPT ); Sun, 30 Apr 2023 07:26:27 -0400 Received: from hust.edu.cn (unknown [202.114.0.240]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A13626AD for ; Sun, 30 Apr 2023 04:26:24 -0700 (PDT) Received: from haru.localdomain ([10.12.176.125]) (user=m202071377@hust.edu.cn mech=LOGIN bits=0) by mx1.hust.edu.cn with ESMTP id 33UBNmPL023948-33UBNmPM023948 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sun, 30 Apr 2023 19:23:53 +0800 From: XuDong Liu To: Maxime Ripard , Chen-Yu Tsai , David Airlie , Daniel Vetter , Jernej Skrabec , Samuel Holland , Boris Brezillon , Paul Kocialkowski Cc: hust-os-kernel-patches@googlegroups.com, XuDong Liu , Dongliang Mu , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH] drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks` Date: Sun, 30 Apr 2023 19:23:46 +0800 Message-Id: <20230430112347.4689-1-m202071377@hust.edu.cn> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-FEAS-AUTH-USER: m202071377@hust.edu.cn Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Smatch reports: drivers/gpu/drm/sun4i/sun4i_tcon.c:805 sun4i_tcon_init_clocks() warn: 'tcon->clk' from clk_prepare_enable() not released on lines: 792,801. In the function sun4i_tcon_init_clocks(), tcon->clk and tcon->sclk0 are not disabled in the error handling, which affects the release of these variable. Although sun4i_tcon_bind(), which calls sun4i_tcon_init_clocks(), use sun4i_tcon_free_clocks to disable the variables mentioned, but the error handling branch of sun4i_tcon_init_clocks() ignores the required disable process. To fix this issue, use the devm_clk_get_enabled to automatically balance enable and disabled calls. As original implementation use sun4i_tcon_free_clocks() to disable clk explicitly, we delete the related calls and error handling that are no longer needed. Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Fixes: b14e945bda8a ("drm/sun4i: tcon: Prepare and enable TCON channel 0 cl= ock at init") Fixes: 8e9240472522 ("drm/sun4i: support TCONs without channel 1") Fixes: 34d698f6e349 ("drm/sun4i: Add has_channel_0 TCON quirk") Signed-off-by: XuDong Liu Reviewed-by: Dongliang Mu --- The issue is discovered by static analysis, and the patch is not tested yet. --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun= 4i_tcon.c index 523a6d787921..936796851ffd 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -778,21 +778,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *= private) static int sun4i_tcon_init_clocks(struct device *dev, struct sun4i_tcon *tcon) { - tcon->clk =3D devm_clk_get(dev, "ahb"); + tcon->clk =3D devm_clk_get_enabled(dev, "ahb"); if (IS_ERR(tcon->clk)) { dev_err(dev, "Couldn't get the TCON bus clock\n"); return PTR_ERR(tcon->clk); } - clk_prepare_enable(tcon->clk); =20 if (tcon->quirks->has_channel_0) { - tcon->sclk0 =3D devm_clk_get(dev, "tcon-ch0"); + tcon->sclk0 =3D devm_clk_get_enabled(dev, "tcon-ch0"); if (IS_ERR(tcon->sclk0)) { dev_err(dev, "Couldn't get the TCON channel 0 clock\n"); return PTR_ERR(tcon->sclk0); } } - clk_prepare_enable(tcon->sclk0); =20 if (tcon->quirks->has_channel_1) { tcon->sclk1 =3D devm_clk_get(dev, "tcon-ch1"); @@ -805,12 +803,6 @@ static int sun4i_tcon_init_clocks(struct device *dev, return 0; } =20 -static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) -{ - clk_disable_unprepare(tcon->sclk0); - clk_disable_unprepare(tcon->clk); -} - static int sun4i_tcon_init_irq(struct device *dev, struct sun4i_tcon *tcon) { @@ -1223,14 +1215,14 @@ static int sun4i_tcon_bind(struct device *dev, stru= ct device *master, ret =3D sun4i_tcon_init_regmap(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON regmap\n"); - goto err_free_clocks; + goto err_assert_reset; } =20 if (tcon->quirks->has_channel_0) { ret =3D sun4i_dclk_create(dev, tcon); if (ret) { dev_err(dev, "Couldn't create our TCON dot clock\n"); - goto err_free_clocks; + goto err_assert_reset; } } =20 @@ -1293,8 +1285,6 @@ static int sun4i_tcon_bind(struct device *dev, struct= device *master, err_free_dotclock: if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); -err_free_clocks: - sun4i_tcon_free_clocks(tcon); err_assert_reset: reset_control_assert(tcon->lcd_rst); return ret; @@ -1308,7 +1298,6 @@ static void sun4i_tcon_unbind(struct device *dev, str= uct device *master, list_del(&tcon->list); if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); - sun4i_tcon_free_clocks(tcon); } =20 static const struct component_ops sun4i_tcon_ops =3D { --=20 2.34.1