From patchwork Fri Jun 2 18:54:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 13265754 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5159AC7EE29 for ; Fri, 2 Jun 2023 18:54:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jWViU1El4giPICwaE836Z2fcUXG+oLT12+yLO1jZfUg=; b=CdEqCebUz6RGB8 bGWFMJ5S0u0vOl29ySEBC9HZGxLWEtfXFuPzcMzEeGqDyfL8eIMHgrnxXBj4ZT9PxkCDt/ZyhGdRY fiTmRVTbrzPSPJsejP1rWMn0zy0bATHeCXeEBRicKtwP/fCsAxOz3oGz+Q2eQAOSe1YCLPaYRZqrf oUkP9+40tbQZSxVBttrU/7crvxp0nFKb2IUA6SJLRXOGCHzNw0RvjCnHL3tMuWi1KfsUzPPZNvMpo vdm8Rb3u1ljkxtluZULpMw3uhUWf8H3xuV/JLcruowM9f8KWfwqyDFWfYzU1MpJwg8tSh/hE9W3hb 2VX0BNOyRDfc/bJz9dNA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q59uy-007gop-1A; Fri, 02 Jun 2023 18:54:32 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q59uu-007gnb-27 for linux-arm-kernel@lists.infradead.org; Fri, 02 Jun 2023 18:54:30 +0000 Received: from dude02.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::28]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1q59un-0007kh-3x; Fri, 02 Jun 2023 20:54:21 +0200 From: Lucas Stach To: Shawn Guo Cc: Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Marek Vasut , patchwork-lst@pengutronix.de, linux-arm-kernel@lists.infradead.org, Luca Ceresoli Subject: [PATCH 2/2] soc: imx: gpcv2: prepare bus clocks early Date: Fri, 2 Jun 2023 20:54:17 +0200 Message-Id: <20230602185417.4098937-2-l.stach@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230602185417.4098937-1-l.stach@pengutronix.de> References: <20230602185417.4098937-1-l.stach@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::28 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230602_115428_719195_9544DC8F X-CRM114-Status: GOOD ( 17.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Prepare the bus clocks during PGC domain driver probe. This avoids a potential deadlock when there a clock providers inside the domain, as this might end up trying to take the CCF prepare_lock from two different contexts, when runtime PM is trying to resume the PGC domain for the clock provider. By keeping the bus clocks prepared as long as there is a PGC domain driver attached, we don't need to take the prepare_lock in the domain power up/down paths. We don't want to do this for regular reset clocks, as this might lead to some PLLs being kept prepared that could otherwise be shut down. For the bus clocks this isn't a concern, as all the bus clocks are derived from always-on system PLLs. Signed-off-by: Lucas Stach Reviewed-by: Marco Felsch --- drivers/soc/imx/gpcv2.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 706f852e5d87..428e2fd82f26 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -337,10 +337,14 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) reset_control_assert(domain->reset); - /* Enable reset clocks for all devices in the domain */ - ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks); + if (!domain->bus_clocks) + /* Enable reset clocks for all devices in the domain */ + ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks); + else + /* Enable bus clocks for this domain */ + ret = clk_bulk_enable(domain->num_clks, domain->clks); if (ret) { - dev_err(domain->dev, "failed to enable reset clocks\n"); + dev_err(domain->dev, "failed to enable clocks\n"); goto out_regulator_disable; } @@ -402,7 +406,10 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) return 0; out_clk_disable: - clk_bulk_disable_unprepare(domain->num_clks, domain->clks); + if (!domain->bus_clocks) + clk_bulk_disable_unprepare(domain->num_clks, domain->clks); + else + clk_bulk_disable(domain->num_clks, domain->clks); out_regulator_disable: if (!IS_ERR(domain->regulator)) regulator_disable(domain->regulator); @@ -466,8 +473,11 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) } } - /* Disable reset clocks for all devices in the domain */ - clk_bulk_disable_unprepare(domain->num_clks, domain->clks); + /* Disable bus or reset clocks for all devices in the domain */ + if (!domain->bus_clocks) + clk_bulk_disable_unprepare(domain->num_clks, domain->clks); + else + clk_bulk_disable(domain->num_clks, domain->clks); if (!IS_ERR(domain->regulator)) { ret = regulator_disable(domain->regulator); @@ -486,6 +496,8 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) out_clk_disable: if (!domain->bus_clocks) clk_bulk_disable_unprepare(domain->num_clks, domain->clks); + else + clk_bulk_disable(domain->num_clks, domain->clks); return ret; } @@ -1343,10 +1355,19 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) regmap_update_bits(domain->regmap, domain->regs->map, domain->bits.map, domain->bits.map); + if (domain->bus_clocks) { + ret = clk_bulk_prepare(domain->num_clks, domain->clks); + if (ret) { + dev_err(domain->dev, + "Failed to prepare domain's clocks\n"); + goto out_domain_unmap; + } + } + ret = pm_genpd_init(&domain->genpd, NULL, true); if (ret) { dev_err(domain->dev, "Failed to init power domain\n"); - goto out_domain_unmap; + goto out_disable_clocks; } if (IS_ENABLED(CONFIG_LOCKDEP) && @@ -1364,6 +1385,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) out_genpd_remove: pm_genpd_remove(&domain->genpd); +out_disable_clocks: + if (domain->bus_clocks) + clk_bulk_unprepare(domain->num_clks, domain->clks); out_domain_unmap: if (domain->bits.map) regmap_update_bits(domain->regmap, domain->regs->map, @@ -1380,6 +1404,9 @@ static int imx_pgc_domain_remove(struct platform_device *pdev) of_genpd_del_provider(domain->dev->of_node); pm_genpd_remove(&domain->genpd); + if (domain->bus_clocks) + clk_bulk_unprepare(domain->num_clks, domain->clks); + if (domain->bits.map) regmap_update_bits(domain->regmap, domain->regs->map, domain->bits.map, 0);