Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp4507580rdh; Wed, 29 Nov 2023 03:33:29 -0800 (PST) X-Google-Smtp-Source: AGHT+IEw5+KPKx6631apSf0Xepmx518ouFrRtPkkJ0mUyMyujxgfkMKIyXSNs/I9DdAnvOAST66I X-Received: by 2002:a17:90b:314b:b0:285:a163:c25b with SMTP id ip11-20020a17090b314b00b00285a163c25bmr13586564pjb.5.1701257609065; Wed, 29 Nov 2023 03:33:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701257609; cv=none; d=google.com; s=arc-20160816; b=dFO8Kt84PgHbYixCHv7q+6IAQGcnsEM0aov54BOqXMzhefBryHXcl/gnhrmiaxDmEn iOeJiREJIInikgm7i3lA15Gw3bg8y3N7EZU0xun2QDyfWT9OIKUn90UBVi/FmRZhCqms 5Mc8xliiQlRRS/CfeJDFbuNNN78A8a9oPV6DR0ZIE/wmzvwQjnSZkwz8UWwSkA6iPdXG SK7R2jSuip7TJYXPU+iVOt5tZW01koMbxe67Vxl1qQkLnnYUj295TDV0cEFkzvMZFtoO y7PZuDiyfS/lDr1ekXmjjOCu/a59XXMAJORnLaVACnQgaspVpG46c6BsgSvEgjrxocZb X6vg== 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=FMAtC5RlO7Jbgcz7ACyP3z2tGyaNf1QQubxTNs/VVCs=; fh=/FlLlbJIyaSMb/z//GYuwqkY3Pecj8kRqDZsisUVoII=; b=jqkN5yAfrc9XYiszXGrdMZ7/vEHAq8qA4tBAaYsep2HIBLjtHP4o0SEDcubmxU+QAN Ebz7cSZtb76IVR3zUq9fMUfs22zDn6YI+I0xzNLmk/XZkYQJ05mBbP5xzaA/JN+BY0p0 I41KHu4w5fAvWvwLRDJ8RoQkYU2IoPBClV6nYjti8lbDc/twhmvKIb216UBXTwb6LwmU 9tqnd9uX3deTr0jT/SxaOWqAIp6gZx4O0cXrPNAvtHCIrOYP0GVrwbWYRHADEv5MDkUR ptBrQh1Wi/XTdNzLZCA+BU0Q8RfhiY0pXGEWOUK6s+4qYmTH3NX4KIrA6rK9m8pxn545 jQ4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=NWrmaJ+G; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Return-Path: Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id nd10-20020a17090b4cca00b002860a77a5f0si1197294pjb.28.2023.11.29.03.33.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 03:33:29 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=NWrmaJ+G; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id E87FC804A813; Wed, 29 Nov 2023 03:33:24 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232328AbjK2LdH (ORCPT + 99 others); Wed, 29 Nov 2023 06:33:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231922AbjK2LdG (ORCPT ); Wed, 29 Nov 2023 06:33:06 -0500 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD43084; Wed, 29 Nov 2023 03:33:12 -0800 (PST) Received: from eugen-station.. (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: ehristev) by madras.collabora.co.uk (Postfix) with ESMTPSA id E0A006601F02; Wed, 29 Nov 2023 11:33:10 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1701257591; bh=x16Rnq7CZEpFbM9s04wUl+znCtY6zt8f98/hPwnLU3c=; h=From:To:Cc:Subject:Date:From; b=NWrmaJ+GCcglxq208tXL5bSQmTfPx7i69hCbPXnCUxeWxkjyUeJC0uO/ZZ49Oig5q D1vd0wXcKPpaG8YHmzygzS8viumQuoOrtLZ4HlGhj26Ng4Bjtzt5A4ntoeAsxblAt6 Xw/z1zN5Gh98+BaWWdPt6vF+esqBVJSw0vZVx2QXrBg86+oFsdfHtP7iGog8zbtT6x HV63cXFbi8Pu58QlB9wIvpHYHXZZPf8i2S4Uf+fdWCm9zI8nSSx+IzPa7/fsy07Qh3 yfJ7ZCHeukygDPOEOD/k0+KOurbGnlyT4I8QGBSCnHUemBpwN0tLRjNt/3IOMyFKnG Mqjzf0Nhp/m2A== From: Eugen Hristev To: linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-pm@vger.kernel.org Cc: eballetbo@kernel.org, angelogioacchino.delregno@collabora.com, ulf.hansson@linaro.org, linux-kernel@vger.kernel.org, kernel@collabora.com, Eugen Hristev Subject: [PATCH] pmdomain: mediatek: fix race condition in power on/power off sequences Date: Wed, 29 Nov 2023 13:31:20 +0200 Message-Id: <20231129113120.4907-1-eugen.hristev@collabora.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Wed, 29 Nov 2023 03:33:25 -0800 (PST) It can happen that during the power off sequence for a power domain another power on sequence is started, and it can lead to powering on and off in the same time for the similar power domain. This can happen if parallel probing occurs: one device starts probing, and one power domain is probe deferred, this leads to all power domains being rolled back and powered off, while in the same time another device starts probing and requests powering on the same power domains or similar. This was encountered on MT8186, when the sequence is : Power on SSUSB Power on SSUSB_P1 Power on DIS -> probe deferred Power off DIS Power off SSUSB_P1 Power off SSUSB During the sequence of powering off SSUSB, some new similar sequence starts, and during the power on of SSUSB, clocks are enabled. In this case, powering off SSUSB fails from the first sequence, because power off ACK bit check times out (as clocks are powered back on by the second sequence). In consequence, powering it on also times out, and it leads to the whole power domain in a bad state. To solve this issue, added a mutex that locks the whole power off/power on sequence such that it would never happen that multiple sequences try to enable or disable the same power domain in parallel. Fixes: 59b644b01cf4 ("soc: mediatek: Add MediaTek SCPSYS power domains") Signed-off-by: Eugen Hristev --- drivers/pmdomain/mediatek/mtk-pm-domains.c | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c index d5f0ee05c794..4f136b47e539 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ struct scpsys { struct device *dev; struct regmap *base; const struct scpsys_soc_data *soc_data; + struct mutex mutex; struct genpd_onecell_data pd_data; struct generic_pm_domain *domains[]; }; @@ -238,9 +240,13 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) bool tmp; int ret; + mutex_lock(&scpsys->mutex); + ret = scpsys_regulator_enable(pd->supply); - if (ret) + if (ret) { + mutex_unlock(&scpsys->mutex); return ret; + } ret = clk_bulk_prepare_enable(pd->num_clks, pd->clks); if (ret) @@ -291,6 +297,7 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) goto err_enable_bus_protect; } + mutex_unlock(&scpsys->mutex); return 0; err_enable_bus_protect: @@ -305,6 +312,7 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) clk_bulk_disable_unprepare(pd->num_clks, pd->clks); err_reg: scpsys_regulator_disable(pd->supply); + mutex_unlock(&scpsys->mutex); return ret; } @@ -315,13 +323,15 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) bool tmp; int ret; + mutex_lock(&scpsys->mutex); + ret = scpsys_bus_protect_enable(pd); if (ret < 0) - return ret; + goto err_mutex_unlock; ret = scpsys_sram_disable(pd); if (ret < 0) - return ret; + goto err_mutex_unlock; if (pd->data->ext_buck_iso_offs && MTK_SCPD_CAPS(pd, MTK_SCPD_EXT_BUCK_ISO)) regmap_set_bits(scpsys->base, pd->data->ext_buck_iso_offs, @@ -340,13 +350,15 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret < 0) - return ret; + goto err_mutex_unlock; clk_bulk_disable_unprepare(pd->num_clks, pd->clks); scpsys_regulator_disable(pd->supply); - return 0; +err_mutex_unlock: + mutex_unlock(&scpsys->mutex); + return ret; } static struct @@ -700,6 +712,8 @@ static int scpsys_probe(struct platform_device *pdev) return PTR_ERR(scpsys->base); } + mutex_init(&scpsys->mutex); + ret = -ENODEV; for_each_available_child_of_node(np, node) { struct generic_pm_domain *domain; -- 2.34.1