From mboxrd@z Thu Jan 1 00:00:00 1970 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 2C06CC79FAD for ; Wed, 9 Sep 2026 09:11:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version: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:In-Reply-To:References:List-Owner; bh=LLu4gYFl4Wew5iASt7rrMwLrvQqTxcczEstYXYC3JZs=; b=mPGbIpSoTmLcxBHdqUFfMVzYGr Dy9FP9PoMuhWgAd78rRoTq3xMuKPt0s7DLGu8T33HTV0P6EEKr/52pSak2MezR5sz6Gge6UIOMvlX 85yIUCr19EjES+U+zNPpeTiHgG+dzgiaYZG8Xh7R9+iMGyYUu6ZDJEf9lqSxE3yIqx8wmNTityVNk vBaZUa0lnNZnuocmjle3VBAc0X/0jPRW13kw+NWO+7GhJGe1+4zZD+v1rMiTutd3iM9pzYbrblRAM rjop/rdko9JgJPSqcyzei/soW+UIYMmMveMpTaMrheHpwKrM5DyTi0nhITzoCL8kjnmgP/R9o1EBu CdvO39yQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x4EL8-0000000BFp1-2tVP; Wed, 09 Sep 2026 09:11:34 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x4EL6-0000000BFo8-0sbW for linux-mediatek@lists.infradead.org; Wed, 09 Sep 2026 09:11:33 +0000 X-UUID: 6eae880aac2e11f1afed4741b24580c9-20260909 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=LLu4gYFl4Wew5iASt7rrMwLrvQqTxcczEstYXYC3JZs=; b=LvzQUMFk8JiLPZnQIR60Gv0pS3fCrZLjyDNOIICpXDWB1QA7Ooe3N31PC4suHWI3aQ3x9PQ0sxCUbkDOb+iDJB776iWdquO6cd4D9I2CbChsEA1iUr6DcuFn88C+z9eIldWQV0giqgcO4N9mw+3EfZeVUZiX982c+hlYNC2XmoY=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.19,REQID:f1f46aa7-ac28-4680-a04c-4c82dc489467,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:7db8b62,CLOUDID:fe4d1628-9ebf-4787-bb42-3cd26eee85aa,B ulkID:nil,BulkQuantity:0,SF:102|123|836|865|888|898,TC:-5,Content:0|15|50| 99,EDM:-3,IP:nil,URL:0,File:130,RT:0,Bulk:nil,QS:nil,BEC:-1,COL:0,OSI:0,OS A:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 6eae880aac2e11f1afed4741b24580c9-20260909 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 544062703; Wed, 09 Sep 2026 02:11:25 -0700 Received: from mtkmbs11n2.mediatek.inc (172.21.101.187) by MTKMBS09N2.mediatek.inc (172.21.101.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.29; Wed, 9 Sep 2026 17:11:22 +0800 Received: from mtksitap99.mediatek.inc (10.233.130.16) by mtkmbs11n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.2562.29 via Frontend Transport; Wed, 9 Sep 2026 17:11:22 +0800 From: To: , , , , , CC: , , , , , , , , , Subject: [PATCH v1] ufs: core: serialize AHIT register access between sysfs and host driver Date: Wed, 9 Sep 2026 17:10:07 +0800 Message-ID: <20260909091120.1134414-1-peter.wang@mediatek.com> X-Mailer: git-send-email 2.45.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260909_021132_289649_7C5F31C3 X-CRM114-Status: GOOD ( 18.44 ) X-BeenThere: linux-mediatek@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-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Peter Wang A race exists between ufshcd_auto_hibern8_update() and ufs_mtk_pwr_change_notify() when both paths concurrently access REG_AUTO_HIBERNATE_IDLE_TIMER. Additionally, the static local variable used to save/restore AHIT in the power change path is not re-entrant and may hold a stale value if a sysfs write races with a gear change. Introduce ahit_mutex and ahit_disable_depth in struct ufs_hba to serialize AHIT register access. The depth counter tracks how many host-driver paths have forced AHIT off; sysfs writes are suppressed while it is non-zero and the register is restored from hba->ahit only when the last disabler drops it to zero. Fixes: f5ca8d0c7a63 ("scsi: ufs: host: mediatek: Disable auto-hibern8 during power mode changes") Signed-off-by: Peter Wang --- drivers/ufs/core/ufshcd.c | 14 +++++++++++++- drivers/ufs/host/ufs-mediatek.c | 16 ++++++++++++---- include/ufs/ufshcd.h | 8 ++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2ba244cf40ac..e88b905eb7bc 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -4748,7 +4748,17 @@ void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) if (!pm_runtime_suspended(&hba->ufs_device_wlun->sdev_gendev)) { ufshcd_rpm_get_sync(hba); ufshcd_hold(hba); - ufshcd_configure_auto_hibern8(hba); + /* + * Serialize with the host driver's AHIT control. Skip the + * register write while the driver has AHIT forced off; the + * driver programs hba->ahit back when it re-enables it. + * Mutex is taken here (not across the rpm calls above) so it + * never blocks a resume that the driver's path may need. + */ + mutex_lock(&hba->ahit_mutex); + if (!hba->ahit_disable_depth) + ufshcd_configure_auto_hibern8(hba); + mutex_unlock(&hba->ahit_mutex); ufshcd_release(hba); ufshcd_rpm_put_sync(hba); } @@ -11268,6 +11278,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) mutex_init(&hba->wb_mutex); + mutex_init(&hba->ahit_mutex); + init_rwsem(&hba->clk_scaling_lock); ufshcd_init_clk_gating(hba); diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c index 814c1b7343b9..b6279edde176 100644 --- a/drivers/ufs/host/ufs-mediatek.c +++ b/drivers/ufs/host/ufs-mediatek.c @@ -1507,19 +1507,27 @@ static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba, struct ufs_pa_layer_attr *dev_req_params) { int ret = 0; - static u32 reg; switch (stage) { case PRE_CHANGE: if (ufshcd_is_auto_hibern8_supported(hba)) { - reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER); + /* Block sysfs AHIT writes while we force AHIT off */ + mutex_lock(&hba->ahit_mutex); + hba->ahit_disable_depth++; + mutex_unlock(&hba->ahit_mutex); ufs_mtk_auto_hibern8_disable(hba); } ret = ufs_mtk_pre_pwr_change(hba, dev_req_params); break; case POST_CHANGE: - if (ufshcd_is_auto_hibern8_supported(hba)) - ufshcd_writel(hba, reg, REG_AUTO_HIBERNATE_IDLE_TIMER); + if (ufshcd_is_auto_hibern8_supported(hba)) { + mutex_lock(&hba->ahit_mutex); + /* re-enable only when the last disabler drops off */ + if (!--hba->ahit_disable_depth) + ufshcd_writel(hba, hba->ahit, + REG_AUTO_HIBERNATE_IDLE_TIMER); + mutex_unlock(&hba->ahit_mutex); + } break; default: ret = -EINVAL; diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index dfd302f2dc7c..be62165b785e 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -1132,6 +1132,14 @@ struct ufs_hba { /* Auto-Hibernate Idle Timer register value */ u32 ahit; + /* Serializes AHIT register access between sysfs and the host driver */ + struct mutex ahit_mutex; + /* + * Nesting count of host-driver paths that have AHIT forced off. + * Non-zero blocks sysfs AHIT writes; AHIT is reprogrammed only when + * the last disabler drops it back to zero. Guarded by ahit_mutex. + */ + int ahit_disable_depth; unsigned long outstanding_tasks; spinlock_t outstanding_lock; -- 2.45.2