Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: Bart Van Assche <bvanassche@acm.org>
To: "Martin K . Petersen" <martin.petersen@oracle.com>
Cc: linux-scsi@vger.kernel.org, Bart Van Assche <bvanassche@acm.org>,
	"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	Peter Wang <peter.wang@mediatek.com>,
	Avri Altman <avri.altman@sandisk.com>,
	Bean Huo <beanhuo@micron.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	"Bao D. Nguyen" <quic_nguyenb@quicinc.com>
Subject: [PATCH 4/7] ufs: core: Switch from clock gating to RPM
Date: Fri, 16 Jan 2026 10:26:06 -0800	[thread overview]
Message-ID: <20260116182628.3255116-5-bvanassche@acm.org> (raw)
In-Reply-To: <20260116182628.3255116-1-bvanassche@acm.org>

Make ufshcd_hold() and ufshcd_release() call RPM functions instead of
controlling clock gating directly. This patch does not change the power
consumption of systems with UFS devices: both clock gating and RPM
switch to the same low power state if the UFS device is not in use.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/ufs/core/ufshcd.c | 103 +++-----------------------------------
 1 file changed, 8 insertions(+), 95 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 900b945444d1..b3d75152abd9 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -1936,72 +1936,10 @@ static void ufshcd_ungate_work(struct work_struct *work)
  */
 void ufshcd_hold(struct ufs_hba *hba)
 {
-	bool flush_result;
-	unsigned long flags;
-
-	if (!ufshcd_is_clkgating_allowed(hba) ||
-	    !hba->clk_gating.is_initialized)
-		return;
-	spin_lock_irqsave(&hba->clk_gating.lock, flags);
-	hba->clk_gating.active_reqs++;
-
-start:
-	switch (hba->clk_gating.state) {
-	case CLKS_ON:
-		/*
-		 * Wait for the ungate work to complete if in progress.
-		 * Though the clocks may be in ON state, the link could
-		 * still be in hibner8 state if hibern8 is allowed
-		 * during clock gating.
-		 * Make sure we exit hibern8 state also in addition to
-		 * clocks being ON.
-		 */
-		if (ufshcd_can_hibern8_during_gating(hba) &&
-		    ufshcd_is_link_hibern8(hba)) {
-			spin_unlock_irqrestore(&hba->clk_gating.lock, flags);
-			flush_result = flush_work(&hba->clk_gating.ungate_work);
-			if (hba->clk_gating.is_suspended && !flush_result)
-				return;
-			spin_lock_irqsave(&hba->clk_gating.lock, flags);
-			goto start;
-		}
-		break;
-	case REQ_CLKS_OFF:
-		if (cancel_delayed_work(&hba->clk_gating.gate_work)) {
-			hba->clk_gating.state = CLKS_ON;
-			trace_ufshcd_clk_gating(hba,
-						hba->clk_gating.state);
-			break;
-		}
-		/*
-		 * If we are here, it means gating work is either done or
-		 * currently running. Hence, fall through to cancel gating
-		 * work and to enable clocks.
-		 */
-		fallthrough;
-	case CLKS_OFF:
-		hba->clk_gating.state = REQ_CLKS_ON;
-		trace_ufshcd_clk_gating(hba,
-					hba->clk_gating.state);
-		queue_work(hba->clk_gating.clk_gating_workq,
-			   &hba->clk_gating.ungate_work);
-		/*
-		 * fall through to check if we should wait for this
-		 * work to be done or not.
-		 */
-		fallthrough;
-	case REQ_CLKS_ON:
-		spin_unlock_irqrestore(&hba->clk_gating.lock, flags);
-		flush_work(&hba->clk_gating.ungate_work);
-		/* Make sure state is CLKS_ON before returning */
-		spin_lock_irqsave(&hba->clk_gating.lock, flags);
-		goto start;
-	default:
-		dev_err(hba->dev, "%s: clk gating is in invalid state %d\n",
-				__func__, hba->clk_gating.state);
-		break;
-	}
-	spin_unlock_irqrestore(&hba->clk_gating.lock, flags);
+	/* blk_pm_runtime_init() sets q->dev */
+	if (hba->ufs_device_wlun && hba->ufs_device_wlun->request_queue->dev &&
+	    !hba->pm_op_in_progress)
+		ufshcd_rpm_get_sync(hba);
 }
 EXPORT_SYMBOL_GPL(ufshcd_hold);
 
@@ -2073,37 +2011,12 @@ static void ufshcd_gate_work(struct work_struct *work)
 	}
 }
 
-static void __ufshcd_release(struct ufs_hba *hba)
-{
-	lockdep_assert_held(&hba->clk_gating.lock);
-
-	if (!ufshcd_is_clkgating_allowed(hba))
-		return;
-
-	hba->clk_gating.active_reqs--;
-
-	if (hba->clk_gating.active_reqs || hba->clk_gating.is_suspended ||
-	    !hba->clk_gating.is_initialized ||
-	    hba->clk_gating.state == CLKS_OFF)
-		return;
-
-	scoped_guard(spinlock_irqsave, hba->host->host_lock) {
-		if (ufshcd_has_pending_tasks(hba) ||
-		    hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)
-			return;
-	}
-
-	hba->clk_gating.state = REQ_CLKS_OFF;
-	trace_ufshcd_clk_gating(hba, hba->clk_gating.state);
-	queue_delayed_work(hba->clk_gating.clk_gating_workq,
-			   &hba->clk_gating.gate_work,
-			   msecs_to_jiffies(hba->clk_gating.delay_ms));
-}
-
 void ufshcd_release(struct ufs_hba *hba)
 {
-	guard(spinlock_irqsave)(&hba->clk_gating.lock);
-	__ufshcd_release(hba);
+	/* blk_pm_runtime_init() sets q->dev */
+	if (hba->ufs_device_wlun && hba->ufs_device_wlun->request_queue->dev &&
+	    !hba->pm_op_in_progress)
+		ufshcd_rpm_put(hba);
 }
 EXPORT_SYMBOL_GPL(ufshcd_release);
 

  parent reply	other threads:[~2026-01-16 18:27 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-16 18:26 [PATCH 0/7] ufs: Remove the clock gating code Bart Van Assche
2026-01-16 18:26 ` [PATCH 1/7] ufs: core: Change the type of an ufshcd_clkgate_delay_set() argument Bart Van Assche
2026-01-16 18:26 ` [PATCH 2/7] ufs: host: mediatek: Use ufshcd_clkgate_delay_set() Bart Van Assche
2026-01-16 18:26 ` [PATCH 3/7] ufs: core: Redirect clock gating to RPM Bart Van Assche
2026-01-17  2:05   ` kernel test robot
2026-01-17  2:16   ` kernel test robot
2026-01-16 18:26 ` Bart Van Assche [this message]
2026-01-16 18:26 ` [PATCH 5/7] ufs: core: Remove unused code and data structures Bart Van Assche
2026-01-17  2:16   ` kernel test robot
2026-01-16 18:26 ` [PATCH 6/7] ufs: core: Remove superfluous ufshcd_{hold,release}() calls Bart Van Assche
2026-01-16 18:26 ` [PATCH 7/7] ufs: core: Remove ufshcd_{hold,release}() calls from the I/O path Bart Van Assche
2026-01-22 17:30 ` [PATCH 0/7] ufs: Remove the clock gating code Manivannan Sadhasivam
2026-01-23  7:26   ` Peter Wang (王信友)
2026-01-23 23:27     ` Bart Van Assche
2026-01-26  3:44       ` Peter Wang (王信友)
2026-01-26 22:27         ` Bart Van Assche

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260116182628.3255116-5-bvanassche@acm.org \
    --to=bvanassche@acm.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=adrian.hunter@intel.com \
    --cc=avri.altman@sandisk.com \
    --cc=beanhuo@micron.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=peter.wang@mediatek.com \
    --cc=quic_nguyenb@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox