Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Bharat Uppal <bharat.uppal@samsung.com>,
	Nimesh Sati <nimesh.sati@samsung.com>,
	Bart Van Assche <bvanassche@acm.org>,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	Sasha Levin <sashal@kernel.org>,
	alim.akhtar@samsung.com, krzk@kernel.org,
	linux-scsi@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH AUTOSEL 6.17-6.12] scsi: ufs: exynos: fsd: Gate ref_clk and put UFS device in reset on suspend
Date: Sat, 25 Oct 2025 11:57:58 -0400	[thread overview]
Message-ID: <20251025160905.3857885-247-sashal@kernel.org> (raw)
In-Reply-To: <20251025160905.3857885-1-sashal@kernel.org>

From: Bharat Uppal <bharat.uppal@samsung.com>

[ Upstream commit 6d55af0f0740bf3d77943425fdafb77dc0fa6bb9 ]

On FSD platform, gating the reference clock (ref_clk) and putting the
UFS device in reset by asserting the reset signal during UFS suspend,
improves the power savings and ensures the PHY is fully turned off.

These operations are added as FSD specific suspend hook to avoid
unintended side effects on other SoCs supported by this driver.

Co-developed-by: Nimesh Sati <nimesh.sati@samsung.com>
Signed-off-by: Nimesh Sati <nimesh.sati@samsung.com>
Signed-off-by: Bharat Uppal <bharat.uppal@samsung.com>
Link: https://lore.kernel.org/r/20250821053923.69411-1-bharat.uppal@samsung.com
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

YES

- Adds FSD-only suspend hook: defines `fsd_ufs_suspend(struct exynos_ufs
  *ufs)` that gates the controller clocks and asserts the device reset
  line on suspend (`drivers/ufs/host/ufs-exynos.c:1899`).
  - Gates clocks via `exynos_ufs_gate_clks(ufs)` (`drivers/ufs/host/ufs-
    exynos.c:1901`), which calls `exynos_ufs_ctrl_clkstop(ufs, true)`
    (`drivers/ufs/host/ufs-exynos.c:202,204`).
  - `exynos_ufs_ctrl_clkstop()` sets the clock-stop enables and applies
    `CLK_STOP_MASK` to `HCI_CLKSTOP_CTRL` (`drivers/ufs/host/ufs-
    exynos.c:436-448`).
  - The `CLK_STOP_MASK` includes `REFCLK_STOP` and `REFCLKOUT_STOP`,
    ensuring the reference clock to the PHY is gated
    (`drivers/ufs/host/ufs-exynos.c:61-69`).
- Asserts reset: writes `0` to `HCI_GPIO_OUT` on suspend
  (`drivers/ufs/host/ufs-exynos.c:1902`), matching how a device reset is
  asserted (see `exynos_ufs_dev_hw_reset()` which pulses 0 then 1 on
  `HCI_GPIO_OUT`; `drivers/ufs/host/ufs-exynos.c:1558-1565`). This
  ensures the device and PHY are fully quiesced for maximal power
  savings.
- Scoped to FSD only: the new hook is wired into the FSD driver data via
  `.suspend = fsd_ufs_suspend` (`drivers/ufs/host/ufs-
  exynos.c:2158-2173`). Other SoCs use their own hooks (e.g., GS101:
  `.suspend = gs101_ufs_suspend`; `drivers/ufs/host/ufs-
  exynos.c:2175-2191`), avoiding unintended side effects on non-FSD
  systems.
- Integrates correctly with UFS core PM:
  - The vendor suspend callback is invoked by the UFS core at the
    POST_CHANGE phase of suspend (`ufshcd_vops_suspend(hba, pm_op,
    POST_CHANGE)`), which happens after link/device PM state transitions
    but before clocks are fully managed by the core
    (`drivers/ufs/core/ufshcd.c:9943-9951`).
  - On resume, the vendor resume callback runs before link transitions
    (`ufshcd_vops_resume()`; `drivers/ufs/core/ufshcd.c:10006-10013`),
    and the core will either exit HIBERN8 or, if the link is off,
    perform a full `ufshcd_reset_and_restore()`
    (`drivers/ufs/core/ufshcd.c:10018-10041`). During host (re)init, the
    Exynos driver pulses the device reset line high in
    `exynos_ufs_hce_enable_notify(PRE_CHANGE)` (`drivers/ufs/host/ufs-
    exynos.c:1612-1638`), matching the asserted reset in suspend.
- Mirrors proven pattern: GS101 already asserts the reset line during
  suspend (`gs101_ufs_suspend()` writes `0` to `HCI_GPIO_OUT`;
  `drivers/ufs/host/ufs-exynos.c:1704-1707`). This change extends a
  similar, already-accepted approach to FSD while additionally gating
  ref_clk.
- Fix nature and impact:
  - Addresses a real-world issue: excessive power usage and PHY not
    fully turning off on FSD during suspend. Gating `ref_clk` and
    asserting reset directly target these symptoms, aligning with the
    commit message intent.
  - Minimal, contained change (one new static function + one driver-data
    hook). No API/ABI or architectural changes; no feature additions.
  - Low regression risk for non-FSD platforms since behavior is
    explicitly guarded by the FSD driver-data wiring.
- Stable criteria alignment:
  - Fixes a platform-specific power management defect that affects users
    (improper power savings and PHY not fully off).
  - Small, self-contained change in a single driver file with explicit
    platform scoping.
  - No broad subsystem risk; integrates with existing suspend/resume
    flows and uses established helpers (`exynos_ufs_gate_clks`,
    `HCI_GPIO_OUT` semantics).

Given the above, this is a good stable backport candidate for trees that
include the Exynos UFS driver with FSD support.

 drivers/ufs/host/ufs-exynos.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
index f0adcd9dd553d..513cbcfa10acd 100644
--- a/drivers/ufs/host/ufs-exynos.c
+++ b/drivers/ufs/host/ufs-exynos.c
@@ -1896,6 +1896,13 @@ static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
 	return 0;
 }
 
+static int fsd_ufs_suspend(struct exynos_ufs *ufs)
+{
+	exynos_ufs_gate_clks(ufs);
+	hci_writel(ufs, 0, HCI_GPIO_OUT);
+	return 0;
+}
+
 static inline u32 get_mclk_period_unipro_18(struct exynos_ufs *ufs)
 {
 	return (16 * 1000 * 1000000UL / ufs->mclk_rate);
@@ -2162,6 +2169,7 @@ static const struct exynos_ufs_drv_data fsd_ufs_drvs = {
 	.pre_link               = fsd_ufs_pre_link,
 	.post_link              = fsd_ufs_post_link,
 	.pre_pwr_change         = fsd_ufs_pre_pwr_change,
+	.suspend                = fsd_ufs_suspend,
 };
 
 static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
-- 
2.51.0


  parent reply	other threads:[~2025-10-25 16:20 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20251025160905.3857885-1-sashal@kernel.org>
2025-10-25 15:54 ` [PATCH AUTOSEL 6.17-5.4] scsi: lpfc: Define size of debugfs entry for xri rebalancing Sasha Levin
2025-10-25 15:54 ` [PATCH AUTOSEL 6.17] scsi: ufs: ufs-qcom: Disable lane clocks during phy hibern8 Sasha Levin
2025-10-25 15:54 ` [PATCH AUTOSEL 6.17-6.12] PCI/ERR: Update device error_state already after reset Sasha Levin
2025-10-25 15:55 ` [PATCH AUTOSEL 6.17] scsi: ufs: core: Change MCQ interrupt enable flow Sasha Levin
2025-10-25 15:55 ` [PATCH AUTOSEL 6.17-5.4] scsi: lpfc: Check return status of lpfc_reset_flush_io_context during TGT_RESET Sasha Levin
2025-10-25 15:55 ` [PATCH AUTOSEL 6.17-6.1] scsi: ufs: host: mediatek: Fix invalid access in vccqx handling Sasha Levin
2025-10-25 15:56 ` [PATCH AUTOSEL 6.17-6.1] scsi: ufs: host: mediatek: Change reset sequence for improved stability Sasha Levin
2025-10-25 15:56 ` [PATCH AUTOSEL 6.17-5.15] scsi: mpi3mr: Fix controller init failure on fault during queue creation Sasha Levin
2025-10-25 15:56 ` [PATCH AUTOSEL 6.17-6.6] scsi: ufs: host: mediatek: Disable auto-hibern8 during power mode changes Sasha Levin
2025-10-25 15:56 ` [PATCH AUTOSEL 6.17-6.12] scsi: lpfc: Clean up allocated queues when queue setup mbox commands fail Sasha Levin
2025-10-25 15:56 ` [PATCH AUTOSEL 6.17] scsi: ufs: ufs-qcom: Align programming sequence of Shared ICE for UFS controller v5 Sasha Levin
2025-10-25 15:57 ` [PATCH AUTOSEL 6.17-6.12] scsi: ufs: host: mediatek: Fix PWM mode switch issue Sasha Levin
2025-10-25 15:57 ` [PATCH AUTOSEL 6.17-6.6] scsi: ufs: host: mediatek: Enhance recovery on hibernation exit failure Sasha Levin
2025-10-25 15:57 ` [PATCH AUTOSEL 6.17-5.15] scsi: libfc: Fix potential buffer overflow in fc_ct_ms_fill() Sasha Levin
2025-10-25 15:57 ` Sasha Levin [this message]
2025-10-25 15:58 ` [PATCH AUTOSEL 6.17-5.10] scsi: pm80xx: Fix race condition caused by static variables Sasha Levin
2025-10-25 15:58 ` [PATCH AUTOSEL 6.17] scsi: ufs: host: mediatek: Fix adapt issue after PA_Init Sasha Levin
2025-10-25 15:58 ` [PATCH AUTOSEL 6.17-6.6] scsi: ufs: core: Disable timestamp functionality if not supported Sasha Levin
2025-10-25 15:58 ` [PATCH AUTOSEL 6.17-6.1] scsi: ufs: host: mediatek: Assign power mode userdata before FASTAUTO mode change Sasha Levin
2025-10-25 15:59 ` [PATCH AUTOSEL 6.17-6.12] scsi: mpi3mr: Fix I/O failures during controller reset Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17] scsi: mpi3mr: Fix device loss during enclosure reboot due to zero link speed Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17-6.12] scsi: lpfc: Ensure PLOGI_ACC is sent prior to PRLI in Point to Point topology Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17-6.6] scsi: ufs: host: mediatek: Fix auto-hibern8 timer configuration Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17-6.12] scsi: ufs: host: mediatek: Fix unbalanced IRQ enable issue Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17-6.1] scsi: ufs: host: mediatek: Enhance recovery on resume failure Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17-6.1] scsi: mpt3sas: Add support for 22.5 Gbps SAS link rate Sasha Levin
2025-10-25 16:00 ` [PATCH AUTOSEL 6.17-6.12] scsi: lpfc: Decrement ndlp kref after FDISC retries exhausted Sasha Levin
2025-10-25 16:01 ` [PATCH AUTOSEL 6.17-5.4] scsi: pm8001: Use int instead of u32 to store error codes Sasha Levin
2025-10-25 16:01 ` [PATCH AUTOSEL 6.17-6.12] scsi: ufs: host: mediatek: Correct system PM flow Sasha Levin
2025-10-25 16:01 ` [PATCH AUTOSEL 6.17-5.15] scsi: lpfc: Remove ndlp kref decrement clause for F_Port_Ctrl in lpfc_cleanup Sasha Levin

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=20251025160905.3857885-247-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=alim.akhtar@samsung.com \
    --cc=bharat.uppal@samsung.com \
    --cc=bvanassche@acm.org \
    --cc=krzk@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=nimesh.sati@samsung.com \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    /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