Linux SCSI subsystem development
 help / color / mirror / Atom feed
* [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement
@ 2026-09-01 15:38 Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 01/24] dt-bindings: phy: Add mediatek,mt8196-ufsphy variant Louis-Alexis Eyraud
                   ` (23 more replies)
  0 siblings, 24 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Conor Dooley,
	Louis-Alexis Eyraud, Krzysztof Kozlowski

This series is a continuation of Nicolas Frattaroli's series, that does
major cleanups in the Mediatek UFS driver code and dt-bindings and adds
the support for the MT8196 SoC and its variants (MT8894 SoC).
Theses new revisions of the series (v10 and later) take into account the
remaining peer reviews and issues reports for v9.

First, it fixes several build and check issues: kernel test report build
report [1], patch per patch compilations.

Second, regarding the opened issues in v9 on the dt-bindings patches
2 ("dt-bindings: ufs: mediatek,ufs: Complete the binding") and 3
("dt-bindings: ufs: mediatek,ufs: Add mt8196 variant") [2],
this revision has two major changes to address them:
1) It renames all the clock names starting with ufs_ prefix and the one
that was named "ufs". No driver changes is needed for those because
they are not explicitely used by their names. The ufs_sel and ufs_fde
clocks in the driver were not renamed because they are not present 
in the dt-bindings (not anymore for the ufs_sel).
The devicetree patches for MT8195 SoC dtsi and the Mediatek Genio
1200-EVK and Radxa NIO-12L boards will be sent in a separate series to
address the dtbs_check warnings caused by the changes.
2) It drops the addition of all crypto and ufs_sel clocks, as it seems the
most likely and best solution to [2] after investigating on them and
what they are used for ([3]).

The Reviewed-by and Acked-by trailers, got by the patches 2 and 3 in
previous series revisions (v9 and earlier), were dropped so these
changes can be reviewed again. 

This new revision is based on linux-next kernel tree (tag:
next-20260831) and has been tested on Mediatek Genio 5100 Pro board
that integrates a MT8894 SoC (MT8196 variant).

[1]: https://lore.kernel.org/linux-mediatek/202603081809.R9OrrITa-lkp@intel.com/
[2]: https://lore.kernel.org/linux-mediatek/20260306163305.GA2680515-robh@kernel.org/
[3]: https://lore.kernel.org/linux-mediatek/8b013876c591f80ec4af86d69bf2f38f9ac481ad.camel@collabora.com/

Original Nicolas Frattaroli's cover letter:

In this series, the existing MediaTek UFS binding is expanded and
completed to correctly describe not just the existing compatibles, but
also to introduce a new compatible in the from of the MT8196 SoC.

The resets, which until now were completely absent from both the UFS
host controller binding and the UFS PHY binding, are introduced to both.
This also means the driver's undocumented and, in mainline, unused reset
logic is reworked. In particular, the PHY reset is no longer a reset of
the host controller node, but of the PHY node.

This means the host controller can reset the PHY through the common PHY
framework.

The resets remain optional.

Additionally, a massive number of driver cleanups are introduced. These
were prompted by me inspecting the driver more closely as I was
adjusting it to correspond to the binding.

The driver still implements vendor properties that are undocumented in
the binding. I did not touch most of those, as I neither want to
convince the bindings maintainers that they are needed without knowing
precisely what they're for, nor do I want to argue with the driver
authors when removing them.

Due to the "Marie Kondo with a chainsaw" nature of the driver cleanup
patches, I humbly request that reviewers do not comment on displeasing
code they see in the context portion of a patch before they've read the
whole patch series, as that displeasing code may in fact be reworked in
a subsequent patch of this series. Please keep comments focused on the
changed lines of the diff; I know there's more that can be done, but it
doesn't necessarily need to be part of this series.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
Changes in v11:
- Rebased onto next-20260831 and fix conflicts
- Fixed property typo in patch 2 ("clocks-names" -> "clock-names")
  (Sashiko)
- Patch 3:
  - Added new avdd09-1-supply property to describe the second 0.9V
    supply pin for MT8196 SoC (K. Kozlowski, Sashiko) and modify
    bindings accordingly
  - Reworded commit message to match patch modifications
- Patch 6:
  - Fixed ufs reset array order (Sashiko)
  - Fixed missing sleep call for null mphy case in ufs_mtk_crypto_enable
    (Sashiko)
- Fixed error logging in patch 7 (Sashiko)
- Added patch 8 to support a second 0.9V regulator in ufs_mediatek
  driver
- Patch 10:
  - Fixed missing new line in error log (Sashiko)
  - Fixed possible pointer type mismatch in ufs_mtk_boost_crypt
    (Sashiko)
- Replaced devm_phy_get use by devm_phy_optional_get in patch 14
  (Sashiko)
_ Removed additional dead code in patch 23 (Sashiko)
- Patch 24:
  - Fixed copyright date
  - Added new has_avdd09_1 flag in mt8196 platform data
- Added new Reviewed-by trailers
- Dropped devicetree-related patches as requested (to be sent in
  a separate series)
- Updated cover letter
- Link to v10: https://lore.kernel.org/r/20260730-mt8196-ufs-v10-0-bc5ecef202dc@collabora.com

Changes in v10:
- Rebased onto next-20260729 and fix conflicts
- Added Signed-off-by for all patches 
- Patch 2: 
  - Removed "ufs" prefix from clock names
  - Renamed "ufs" clock to "main"
  - Removed all crypto clock additions
  - Aligned example to patch changes
  - Reworded commit message to drop crypto clocks references
    and add clock names renaming
  - Dropped Reviewed-by/Acked-by trailers due to changes
- Patch 3:
  - Removed all ufs_sel clock additions
  - Aligned example to patch changes
  - Reworded commit message to drop ufs_sel clocks references
  - Dropped Reviewed-by/Acked-by trailers due to changes
- Fixed build failure on patch 9 due to ufs_mtk_of_match symbol being
  declared in the ufs-mediatek.c file after use.
- Moved ufs_mtk_of_match symbol at original place in patch 8
- Fixed build failure reported by Kernel Test Robot on patch 19 by
  fixing the incorrect FIELD_MODIFY val argument and using GENMASK
  for MTK_UFS_VER_PREFIX_M definition
- Added patch 24, 25, 26 devicetree patches for MT8195 SoC, Mediatek
  Genio 1200-EVK and Radxa NIO-12L boards to match the dt-bindings
  changes introduced by this series
- Added reviewed-by tag for patch 21
- Link to v9: https://lore.kernel.org/r/20260306-mt8196-ufs-v9-0-55b073f7a830@collabora.com

Changes in v9:
- Eliminate build failure in "Remove undocumented downstream reset
  cruft", including the of_node_put of the reset node that wasn't caught
- Pointlessly rename per-instance hibernate timer backup member to
  "ahit"
- Link to v8: https://lore.kernel.org/r/20260304-mt8196-ufs-v8-0-5b0eac23314f@collabora.com

Changes in v8:
- Split "Rework probe function" into two, turn the reset removal into
  its own patch and squash the PHY changes into the common PHY framework
  patch.
- Leave "device reset done" logging print at INFO level
- Remove redundant falsy check for reg_vcore in "Don't acquire
  dvfsrc-vcore twice".
- Change ufs_mtk_wait_idle_state to early-exit on all non-HIB states,
  and poll for VS_HCE_BASE instead.
- Link to v7: https://lore.kernel.org/r/20260216-mt8196-ufs-v7-0-b5f2907c6da7@collabora.com

Changes in v7:
- Rebase onto next-20260205, which drops "scsi: ufs: mediatek: Switch to
  newer PM ops helpers" as Arnd sent an equivalent patch that also fixes
  the PM-less build failure.
- Link to v6: https://lore.kernel.org/r/20260124-mt8196-ufs-v6-0-e7c005b60028@collabora.com

Changes in v6:
- Reword "Rework probe function" commit to better justify the changes
  being made.
- Drop "Add vendor prefix to clk-scale-up-vcore-min"
- Add patch to remove clk-scale-up-vcore-min entirely, describing the
  process for bringing it back (in a different form) in the commit
  message.
- Link to v5: https://lore.kernel.org/r/20260108-mt8196-ufs-v5-0-49215157ec41@collabora.com

Changes in v5:
- Drop "scsi: ufs: mediatek: Make scale_us in setup_clk_gating const" as
  someone else already got a patch in for this into next.
- Make mtk_init_boost_crypt void
- Don't disable/enable misc regulators during suspend/resume, but enable
  them once when acquiring with a devm helper.
- Link to v4: https://lore.kernel.org/r/20251218-mt8196-ufs-v4-0-ddec7a369dd2@collabora.com

Changes in v4:
- bindings: Redo the supply situation, as the avdd pins don't describe
  the vcc(q2) card supplies.
- bindings: format clock in mt8196 example more tersely.
- phy: use devm_reset_control_get_optional_exclusive directly
- driver: get and enable/disable the aforementioned avdd supplies.
- Link to v3: https://lore.kernel.org/r/20251023-mt8196-ufs-v3-0-0f04b4a795ff@collabora.com

Changes in v3:
- Split mediatek,ufs bindings change into two patches, one for
  completing the existing binding, one for the MT8196
- Add over a dozen driver cleanup patches
- Add explicit support for the MT8196 compatible to the driver
- Note: next-20251023, on which I based this, currently has a broken
  build due to an unrelated OPP core change that was merged with no
  build testing. I can't use next-20251022 either, as that lacks the
  recent mediatek UFS changes. It is what it is.
- Link to v2: https://lore.kernel.org/r/20251016-mt8196-ufs-v2-0-c373834c4e7a@collabora.com

Changes in v2:
- Reorder define in mtk_sip_svc.h
- Use bulk reset APIs in UFS host driver
- Link to v1: https://lore.kernel.org/r/20251014-mt8196-ufs-v1-0-195dceb83bc8@collabora.com

---
Louis-Alexis Eyraud (1):
      scsi: ufs: mediatek: Add dual 0.9V supply support

Nicolas Frattaroli (23):
      dt-bindings: phy: Add mediatek,mt8196-ufsphy variant
      dt-bindings: ufs: mediatek,ufs: Complete the binding
      dt-bindings: ufs: mediatek,ufs: Add mt8196 variant
      scsi: ufs: mediatek: Move MTK_SIP_UFS_CONTROL to mtk_sip_svc.h
      phy: mediatek: ufs: Add support for resets
      scsi: ufs: mediatek: Rework resets
      scsi: ufs: mediatek: Rework 0.9V regulator
      scsi: ufs: mediatek: Rework init function
      scsi: ufs: mediatek: Rework the crypt-boost stuff
      scsi: ufs: mediatek: Handle misc host voltage regulators
      scsi: ufs: mediatek: Remove undocumented downstream reset cruft
      scsi: ufs: mediatek: Remove vendor kernel quirks cruft
      scsi: ufs: mediatek: Use the common PHY framework
      scsi: ufs: mediatek: Remove mediatek,ufs-broken-rtc property
      scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths
      scsi: ufs: mediatek: Clean up logging prints
      scsi: ufs: mediatek: Rework ufs_mtk_wait_idle_state
      scsi: ufs: mediatek: Don't acquire dvfsrc-vcore twice
      scsi: ufs: mediatek: Rework hardware version reading
      scsi: ufs: mediatek: Back up idle timer in per-instance struct
      scsi: ufs: mediatek: Remove ret local from link_startup_notify
      scsi: ufs: mediatek: Remove undocumented "clk-scale-up-vcore-min"
      scsi: ufs: mediatek: Add MT8196 compatible, update copyright

 .../devicetree/bindings/phy/mediatek,ufs-phy.yaml  |  16 +
 .../devicetree/bindings/ufs/mediatek,ufs.yaml      | 136 ++-
 drivers/phy/mediatek/phy-mtk-ufs.c                 |  71 ++
 drivers/ufs/host/ufs-mediatek-sip.h                |   9 -
 drivers/ufs/host/ufs-mediatek.c                    | 997 +++++++++------------
 drivers/ufs/host/ufs-mediatek.h                    |  19 +-
 include/linux/soc/mediatek/mtk_sip_svc.h           |   3 +
 7 files changed, 643 insertions(+), 608 deletions(-)
---
base-commit: c7507e07687010738e5f16926078f78ac0d6509d
change-id: 20251014-mt8196-ufs-cec4b9a97e53

Best regards,
-- 
Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v11 01/24] dt-bindings: phy: Add mediatek,mt8196-ufsphy variant
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 02/24] dt-bindings: ufs: mediatek,ufs: Complete the binding Louis-Alexis Eyraud
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Conor Dooley,
	Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The MediaTek MT8196 SoC includes an M-PHY compatible with the already
existing mt8183 binding.

However, one omission from the original binding was that all of these
variants may have an optional reset.

Add the new compatible, and also the resets property, with an example.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 .../devicetree/bindings/phy/mediatek,ufs-phy.yaml        | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml
index 6e2edd43fc2a..ee71dfa4e0c0 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml
@@ -27,6 +27,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8195-ufsphy
+              - mediatek,mt8196-ufsphy
           - const: mediatek,mt8183-ufsphy
       - const: mediatek,mt8183-ufsphy
 
@@ -43,6 +44,10 @@ properties:
       - const: unipro
       - const: mp
 
+  resets:
+    items:
+      - description: Optional UFS M-PHY reset.
+
   "#phy-cells":
     const: 0
 
@@ -66,5 +71,16 @@ examples:
         clock-names = "unipro", "mp";
         #phy-cells = <0>;
     };
+  - |
+    #include <dt-bindings/reset/mediatek,mt8196-resets.h>
+    ufs-phy@16800000 {
+        compatible = "mediatek,mt8196-ufsphy", "mediatek,mt8183-ufsphy";
+        reg = <0x16800000 0x10000>;
+        clocks = <&ufs_ao_clk 3>,
+                 <&ufs_ao_clk 5>;
+        clock-names = "unipro", "mp";
+        resets = <&ufs_ao_clk MT8196_UFSAO_RST0_UFS_MPHY>;
+        #phy-cells = <0>;
+    };
 
 ...

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 02/24] dt-bindings: ufs: mediatek,ufs: Complete the binding
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 01/24] dt-bindings: phy: Add mediatek,mt8196-ufsphy variant Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 16:01   ` sashiko-bot
  2026-09-01 15:38 ` [PATCH v11 03/24] dt-bindings: ufs: mediatek,ufs: Add mt8196 variant Louis-Alexis Eyraud
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

As it stands, the mediatek,ufs.yaml binding is startlingly incomplete.
Its one example, which is the only real "user" of this binding in
mainline, uses the deprecated freq-table-hz property.

The resets, of which there are three optional ones, are completely
absent.

The clock description for MT8195 is incomplete, as is the one for
MT8192. It's not known if the one clock binding for MT8183 is even
correct, but I do not have access to the necessary code and
documentation to find this out myself.

The power supply situation is not much better; the binding describes one
required power supply, but it's the UFS card supply, not any of the
supplies feeding the controller silicon.

No second example is present in the binding, making verification
difficult.

Disallow freq-table-hz and move to operating-points-v2. It's fine to
break compatibility here, as the binding is currently unused and would
be impossible to correctly use in its current state.

Add the three resets and the corresponding reset-names property. These
resets appear to be optional, i.e. not required for the functioning of
the device.

Move the list of clock names out of the if condition, and expand it for
the confirmed clocks I could find by cross-referencing several clock
drivers. For MT8195, increase the minimum number of clocks to include
the rx_symbol ones, as they're internal to the SoC and should always
be present, and should therefore not be omitted.

MT8192 gets to have at least 3 clocks, as these were the ones I could
quickly confirm from a glance at various trees. I can't say this was an
exhaustive search though, but it's better than the current situation.

Properly document all supplies, with which pin name on the SoCs they
supply. Complete the example with them.

Also add a MT8195 example to the binding, using supply labels that I am
pretty sure would be the right ones for e.g. the Radxa NIO 12L.

Finally, remove the 'ufs_' prefix from all clock names containing it
and rename 'ufs' clock to 'main'.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 .../devicetree/bindings/ufs/mediatek,ufs.yaml      | 115 +++++++++++++++++----
 1 file changed, 96 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
index 15c347f5e660..945cb986b06b 100644
--- a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
+++ b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
@@ -19,11 +19,25 @@ properties:
 
   clocks:
     minItems: 1
-    maxItems: 8
+    maxItems: 10
 
   clock-names:
     minItems: 1
-    maxItems: 8
+    items:
+      - const: main
+      - const: aes
+      - const: tick
+      - const: unipro_sysclk
+      - const: unipro_tick
+      - const: unipro_mp_bclk
+      - const: tx_symbol
+      - const: mem_sub
+      - const: rx_symbol0
+      - const: rx_symbol1
+
+  operating-points-v2: true
+
+  freq-table-hz: false
 
   phys:
     maxItems: 1
@@ -31,8 +45,36 @@ properties:
   reg:
     maxItems: 1
 
+  resets:
+    items:
+      - description: reset for the UniPro layer
+      - description: reset for the cryptography engine
+      - description: reset for the host controller
+
+  reset-names:
+    items:
+      - const: unipro
+      - const: crypto
+      - const: hci
+
+  avdd09-supply:
+    description: Phandle to the 0.9V supply powering the AVDD09_UFS pin
+
+  avdd12-supply:
+    description: Phandle to the 1.2V supply powering the AVDD12_UFS pin
+
+  avdd12-ckbuf-supply:
+    description: Phandle to the 1.2V supply powering the AVDD12_CKBUF_UFS pin
+
+  avdd18-supply:
+    description: Phandle to the 1.8V supply powering the AVDD18_UFS pin
+
   vcc-supply: true
 
+  vccq-supply: true
+
+  vccq2-supply: true
+
   mediatek,ufs-disable-mcq:
     $ref: /schemas/types.yaml#/definitions/flag
     description: The mask to disable MCQ (Multi-Circular Queue) for UFS host.
@@ -54,29 +96,41 @@ allOf:
       properties:
         compatible:
           contains:
-            enum:
-              - mediatek,mt8195-ufshci
+            const: mediatek,mt8183-ufshci
     then:
       properties:
         clocks:
-          minItems: 8
+          maxItems: 1
         clock-names:
           items:
-            - const: ufs
-            - const: ufs_aes
-            - const: ufs_tick
-            - const: unipro_sysclk
-            - const: unipro_tick
-            - const: unipro_mp_bclk
-            - const: ufs_tx_symbol
-            - const: ufs_mem_sub
-    else:
+            - const: main
+        avdd12-ckbuf-supply: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mediatek,mt8192-ufshci
+    then:
       properties:
         clocks:
-          maxItems: 1
+          minItems: 3
+          maxItems: 3
         clock-names:
-          items:
-            - const: ufs
+          minItems: 3
+          maxItems: 3
+        avdd09-supply: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mediatek,mt8195-ufshci
+    then:
+      properties:
+        clocks:
+          minItems: 10
+        clock-names:
+          minItems: 10
+        avdd09-supply: false
 
 examples:
   - |
@@ -94,9 +148,32 @@ examples:
             phys = <&ufsphy>;
 
             clocks = <&infracfg_ao CLK_INFRA_UFS>;
-            clock-names = "ufs";
-            freq-table-hz = <0 0>;
+            clock-names = "main";
 
             vcc-supply = <&mt_pmic_vemc_ldo_reg>;
         };
     };
+  - |
+    ufshci@11270000 {
+        compatible = "mediatek,mt8195-ufshci";
+        reg = <0x11270000 0x2300>;
+        interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+        phys = <&ufsphy>;
+        clocks = <&infracfg_ao 63>, <&infracfg_ao 64>, <&infracfg_ao 65>,
+                 <&infracfg_ao 54>, <&infracfg_ao 55>, <&infracfg_ao 56>,
+                 <&infracfg_ao 90>, <&infracfg_ao 93>, <&topckgen 212>,
+                 <&topckgen 215>;
+        clock-names = "main", "aes", "tick", "unipro_sysclk", "unipro_tick",
+                      "unipro_mp_bclk", "tx_symbol", "mem_sub", "rx_symbol0",
+                      "rx_symbol1";
+
+        operating-points-v2 = <&ufs_opp_table>;
+
+        avdd12-supply = <&mt6359_vrf12_ldo_reg>;
+        avdd12-ckbuf-supply = <&mt6359_vbbck_ldo_reg>;
+        avdd18-supply = <&mt6359_vio18_ldo_reg>;
+        vcc-supply = <&mt6359_vemc_1_ldo_reg>;
+        vccq2-supply = <&mt6359_vufs_ldo_reg>;
+
+        mediatek,ufs-disable-mcq;
+    };

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 03/24] dt-bindings: ufs: mediatek,ufs: Add mt8196 variant
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 01/24] dt-bindings: phy: Add mediatek,mt8196-ufsphy variant Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 02/24] dt-bindings: ufs: mediatek,ufs: Complete the binding Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 04/24] scsi: ufs: mediatek: Move MTK_SIP_UFS_CONTROL to mtk_sip_svc.h Louis-Alexis Eyraud
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The MediaTek MT8196 SoC's UFS controller uses a different set of supplies.
It is therefore not compatible with the MT8195. It also have an additional
0.9V supply pin (AVDD09_UFS_1), that is specific to this SoC, thus not
currently described in the binding.

Add a compatible for this SoC and new property for the additional supply,
and modify the binding correspondingly.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 .../devicetree/bindings/ufs/mediatek,ufs.yaml       | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
index 945cb986b06b..99181ec9dda0 100644
--- a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
+++ b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
@@ -16,6 +16,7 @@ properties:
       - mediatek,mt8183-ufshci
       - mediatek,mt8192-ufshci
       - mediatek,mt8195-ufshci
+      - mediatek,mt8196-ufshci
 
   clocks:
     minItems: 1
@@ -60,6 +61,9 @@ properties:
   avdd09-supply:
     description: Phandle to the 0.9V supply powering the AVDD09_UFS pin
 
+  avdd09-1-supply:
+    description: Phandle to the 0.9V supply powering the AVDD09_UFS_1 pin
+
   avdd12-supply:
     description: Phandle to the 1.2V supply powering the AVDD12_UFS pin
 
@@ -104,6 +108,7 @@ allOf:
         clock-names:
           items:
             - const: main
+        avdd09-1-supply: false
         avdd12-ckbuf-supply: false
   - if:
       properties:
@@ -119,6 +124,7 @@ allOf:
           minItems: 3
           maxItems: 3
         avdd09-supply: false
+        avdd09-1-supply: false
   - if:
       properties:
         compatible:
@@ -131,6 +137,21 @@ allOf:
         clock-names:
           minItems: 10
         avdd09-supply: false
+        avdd09-1-supply: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mediatek,mt8196-ufshci
+    then:
+      properties:
+        clocks:
+          minItems: 10
+        clock-names:
+          minItems: 10
+        avdd18-supply: false
+      required:
+        - operating-points-v2
 
 examples:
   - |

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 04/24] scsi: ufs: mediatek: Move MTK_SIP_UFS_CONTROL to mtk_sip_svc.h
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (2 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 03/24] dt-bindings: ufs: mediatek,ufs: Add mt8196 variant Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 05/24] phy: mediatek: ufs: Add support for resets Louis-Alexis Eyraud
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

SMC commands used by multiple drivers need to live in a shared header
file somewhere to avoid code duplication. In order to rework the MPHY
reset control to be in the phy-mtk-ufs.c driver, both ufs-mediatek and
the phy driver need access to this command.

Move it to mtk_sip_svc.h, where other such command definitions already
live.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek-sip.h      | 1 -
 include/linux/soc/mediatek/mtk_sip_svc.h | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/host/ufs-mediatek-sip.h b/drivers/ufs/host/ufs-mediatek-sip.h
index 7d17aedf6fb8..d627dfb4a766 100644
--- a/drivers/ufs/host/ufs-mediatek-sip.h
+++ b/drivers/ufs/host/ufs-mediatek-sip.h
@@ -11,7 +11,6 @@
 /*
  * SiP (Slicon Partner) commands
  */
-#define MTK_SIP_UFS_CONTROL               MTK_SIP_SMC_CMD(0x276)
 #define UFS_MTK_SIP_VA09_PWR_CTRL         BIT(0)
 #define UFS_MTK_SIP_DEVICE_RESET          BIT(1)
 #define UFS_MTK_SIP_CRYPTO_CTRL           BIT(2)
diff --git a/include/linux/soc/mediatek/mtk_sip_svc.h b/include/linux/soc/mediatek/mtk_sip_svc.h
index 6c95a29b79fa..36ab3153fe44 100644
--- a/include/linux/soc/mediatek/mtk_sip_svc.h
+++ b/include/linux/soc/mediatek/mtk_sip_svc.h
@@ -22,6 +22,9 @@
 	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \
 			   ARM_SMCCC_OWNER_SIP, fn_id)
 
+/* UFS related SMC call */
+#define MTK_SIP_UFS_CONTROL		MTK_SIP_SMC_CMD(0x276)
+
 /* Modem related SMC call */
 #define MTK_SIP_KERNEL_CCCI_CONTROL	MTK_SIP_SMC_CMD(0x505)
 

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 05/24] phy: mediatek: ufs: Add support for resets
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (3 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 04/24] scsi: ufs: mediatek: Move MTK_SIP_UFS_CONTROL to mtk_sip_svc.h Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 06/24] scsi: ufs: mediatek: Rework resets Louis-Alexis Eyraud
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The MediaTek UFS PHY supports PHY resets. Until now, they've been
implemented in the UFS host driver. Since they were never documented in
the UFS HCI node's DT bindings, and no mainline DT uses it, it's fine if
it's moved to the correct location, which is the PHY driver.

Implement the MPHY reset logic in this driver and expose it through the
phy subsystem's reset op. The reset itself is optional, as judging by
other mainline devices that use this hardware, it's not required for the
device to function.

If no reset is present, the reset op returns -EOPNOTSUPP, which means
that the ufshci driver can detect it's present and not double sleep in
its own reset function, where it will call the phy reset.

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/phy/mediatek/phy-mtk-ufs.c | 71 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c
index fc19e0fa8ed5..4439a9eb6b7a 100644
--- a/drivers/phy/mediatek/phy-mtk-ufs.c
+++ b/drivers/phy/mediatek/phy-mtk-ufs.c
@@ -4,12 +4,15 @@
  * Author: Stanley Chu <stanley.chu@mediatek.com>
  */
 
+#include <linux/arm-smccc.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/soc/mediatek/mtk_sip_svc.h>
 
 #include "phy-mtk-io.h"
 
@@ -35,9 +38,17 @@
 
 #define UFSPHY_CLKS_CNT    2
 
+#define UFS_MTK_SIP_MPHY_CTRL       BIT(8)
+
+enum ufs_mtk_mphy_op {
+	UFS_MPHY_BACKUP = 0,
+	UFS_MPHY_RESTORE
+};
+
 struct ufs_mtk_phy {
 	struct device *dev;
 	void __iomem *mmio;
+	struct reset_control *reset;
 	struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
 };
 
@@ -140,9 +151,59 @@ static int ufs_mtk_phy_power_off(struct phy *generic_phy)
 	return 0;
 }
 
+static int ufs_mtk_phy_ctrl(struct ufs_mtk_phy *phy, enum ufs_mtk_mphy_op op)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(MTK_SIP_UFS_CONTROL, UFS_MTK_SIP_MPHY_CTRL, op,
+		      0, 0, 0, 0, 0, &res);
+
+	switch (res.a0) {
+	case SMCCC_RET_NOT_SUPPORTED:
+		return -EOPNOTSUPP;
+	case SMCCC_RET_INVALID_PARAMETER:
+		return -EINVAL;
+	default:
+		return 0;
+	}
+}
+
+static int ufs_mtk_phy_reset(struct phy *generic_phy)
+{
+	struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
+	int ret;
+
+	if (!phy->reset)
+		return -EOPNOTSUPP;
+
+	ret = reset_control_assert(phy->reset);
+	if (ret)
+		return ret;
+
+	usleep_range(100, 110);
+
+	ret = reset_control_deassert(phy->reset);
+	if (ret)
+		return ret;
+
+	/*
+	 * To avoid double-sleep and other unintended side-effects in the ufshci
+	 * driver, don't return the phy_ctrl retval here, but just return -EPROTO.
+	 */
+	ret = ufs_mtk_phy_ctrl(phy, UFS_MPHY_RESTORE);
+	if (ret) {
+		dev_err(phy->dev, "UFS_MPHY_RESTORE SMC command failed: %pe\n",
+			ERR_PTR(ret));
+		return -EPROTO;
+	}
+
+	return 0;
+}
+
 static const struct phy_ops ufs_mtk_phy_ops = {
 	.power_on       = ufs_mtk_phy_power_on,
 	.power_off      = ufs_mtk_phy_power_off,
+	.reset          = ufs_mtk_phy_reset,
 	.owner          = THIS_MODULE,
 };
 
@@ -162,8 +223,18 @@ static int ufs_mtk_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(phy->mmio))
 		return PTR_ERR(phy->mmio);
 
+	phy->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
+	if (IS_ERR(phy->reset))
+		return dev_err_probe(dev, PTR_ERR(phy->reset), "Failed to get reset\n");
+
 	phy->dev = dev;
 
+	if (phy->reset) {
+		ret = ufs_mtk_phy_ctrl(phy, UFS_MPHY_BACKUP);
+		if (ret)
+			return dev_err_probe(dev, ret, "Failed to back up MPHY\n");
+	}
+
 	ret = ufs_mtk_phy_clk_init(phy);
 	if (ret)
 		return ret;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 06/24] scsi: ufs: mediatek: Rework resets
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (4 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 05/24] phy: mediatek: ufs: Add support for resets Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:58   ` sashiko-bot
  2026-09-01 15:38 ` [PATCH v11 07/24] scsi: ufs: mediatek: Rework 0.9V regulator Louis-Alexis Eyraud
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Rework the reset control getting in the driver's probe function to use
the bulk reset APIs. Use the optional variant instead of defaulting to
NULL if the resets fail, so that absent resets can be distinguished from
erroneous resets.

Also remove all remnants of the MPHY reset ever having lived in this
driver.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek-sip.h |  8 ----
 drivers/ufs/host/ufs-mediatek.c     | 79 +++++++++++++++++++------------------
 drivers/ufs/host/ufs-mediatek.h     |  7 ++--
 3 files changed, 43 insertions(+), 51 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek-sip.h b/drivers/ufs/host/ufs-mediatek-sip.h
index d627dfb4a766..256598cc3b5b 100644
--- a/drivers/ufs/host/ufs-mediatek-sip.h
+++ b/drivers/ufs/host/ufs-mediatek-sip.h
@@ -31,11 +31,6 @@ enum ufs_mtk_vcc_num {
 	UFS_VCC_MAX
 };
 
-enum ufs_mtk_mphy_op {
-	UFS_MPHY_BACKUP = 0,
-	UFS_MPHY_RESTORE
-};
-
 /*
  * SMC call wrapper function
  */
@@ -84,9 +79,6 @@ static inline void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
 #define ufs_mtk_device_pwr_ctrl(on, ufs_version, res) \
 	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_version)
 
-#define ufs_mtk_mphy_ctrl(op, res) \
-	ufs_mtk_smc(UFS_MTK_SIP_MPHY_CTRL, &(res), op)
-
 #define ufs_mtk_mtcmos_ctrl(op, res) \
 	ufs_mtk_smc(UFS_MTK_SIP_MTCMOS_CTRL, &(res), op)
 
diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 865be3ddf448..80c6ba3d026d 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -94,6 +94,12 @@ static const char *const ufs_uic_dl_err_str[] = {
 	"PA_INIT"
 };
 
+static const char *const ufs_reset_names[] = {
+	"hci",
+	"crypto",
+	"unipro",
+};
+
 static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
@@ -204,49 +210,46 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba)
 static void ufs_mtk_host_reset(struct ufs_hba *hba)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-	struct arm_smccc_res res;
-
-	reset_control_assert(host->hci_reset);
-	reset_control_assert(host->crypto_reset);
-	reset_control_assert(host->unipro_reset);
-	reset_control_assert(host->mphy_reset);
-
-	usleep_range(100, 110);
+	int ret;
 
-	reset_control_deassert(host->unipro_reset);
-	reset_control_deassert(host->crypto_reset);
-	reset_control_deassert(host->hci_reset);
-	reset_control_deassert(host->mphy_reset);
+	ret = reset_control_bulk_assert(MTK_UFS_NUM_RESETS, host->resets);
+	if (ret)
+		dev_warn(hba->dev, "Host reset assert failed: %pe\n", ERR_PTR(ret));
 
-	/* restore mphy setting aftre mphy reset */
-	if (host->mphy_reset)
-		ufs_mtk_mphy_ctrl(UFS_MPHY_RESTORE, res);
-}
+	ret = phy_reset(host->mphy);
 
-static void ufs_mtk_init_reset_control(struct ufs_hba *hba,
-				       struct reset_control **rc,
-				       char *str)
-{
-	*rc = devm_reset_control_get(hba->dev, str);
-	if (IS_ERR(*rc)) {
-		dev_info(hba->dev, "Failed to get reset control %s: %ld\n",
-			 str, PTR_ERR(*rc));
-		*rc = NULL;
+	/*
+	 * Only sleep if there is no MPHY or MPHY doesn't have a reset
+	 * implemented (which already sleeps) or the PHY reset function failed
+	 * somehow, just to be safe
+	 */
+	if (!host->mphy || ret) {
+		usleep_range(100, 110);
+		if (ret != -EOPNOTSUPP)
+			dev_warn(hba->dev, "PHY reset failed: %pe\n", ERR_PTR(ret));
 	}
+
+	ret = reset_control_bulk_deassert(MTK_UFS_NUM_RESETS, host->resets);
+	if (ret)
+		dev_warn(hba->dev, "Host reset deassert failed: %pe\n", ERR_PTR(ret));
 }
 
-static void ufs_mtk_init_reset(struct ufs_hba *hba)
+static int ufs_mtk_init_reset(struct ufs_hba *hba)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+	int ret, i;
+
+	for (i = 0; i < MTK_UFS_NUM_RESETS; i++)
+		host->resets[i].id = ufs_reset_names[i];
 
-	ufs_mtk_init_reset_control(hba, &host->hci_reset,
-				   "hci_rst");
-	ufs_mtk_init_reset_control(hba, &host->unipro_reset,
-				   "unipro_rst");
-	ufs_mtk_init_reset_control(hba, &host->crypto_reset,
-				   "crypto_rst");
-	ufs_mtk_init_reset_control(hba, &host->mphy_reset,
-				   "mphy_rst");
+	ret = devm_reset_control_bulk_get_optional_exclusive(hba->dev, MTK_UFS_NUM_RESETS,
+							     host->resets);
+	if (ret) {
+		dev_err(hba->dev, "Failed to get resets: %pe\n", ERR_PTR(ret));
+		return ret;
+	}
+
+	return 0;
 }
 
 static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
@@ -1248,11 +1251,9 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	if (err)
 		goto out_variant_clear;
 
-	ufs_mtk_init_reset(hba);
-
-	/* backup mphy setting if mphy can reset */
-	if (host->mphy_reset)
-		ufs_mtk_mphy_ctrl(UFS_MPHY_BACKUP, res);
+	err = ufs_mtk_init_reset(hba);
+	if (err)
+		goto out_variant_clear;
 
 	/* Enable runtime autosuspend */
 	hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 73cdc726f290..f95f12eb9926 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -7,12 +7,14 @@
 #define _UFS_MEDIATEK_H
 
 #include <linux/bitops.h>
+#include <linux/reset.h>
 
 /*
  * MCQ define and struct
  */
 #define UFSHCD_MAX_Q_NR 8
 #define MTK_MCQ_INVALID_IRQ	0xFFFF
+#define MTK_UFS_NUM_RESETS 3
 
 /* REG_UFS_MMIO_OPT_CTRL_0 160h */
 #define EHS_EN                  BIT(0)
@@ -175,10 +177,7 @@ struct ufs_mtk_mcq_intr_info {
 struct ufs_mtk_host {
 	struct phy *mphy;
 	struct regulator *reg_va09;
-	struct reset_control *hci_reset;
-	struct reset_control *unipro_reset;
-	struct reset_control *crypto_reset;
-	struct reset_control *mphy_reset;
+	struct reset_control_bulk_data resets[MTK_UFS_NUM_RESETS];
 	struct ufs_hba *hba;
 	struct ufs_mtk_crypt_cfg *crypt;
 	struct ufs_mtk_clk mclk;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 07/24] scsi: ufs: mediatek: Rework 0.9V regulator
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (5 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 06/24] scsi: ufs: mediatek: Rework resets Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:59   ` sashiko-bot
  2026-09-01 15:38 ` [PATCH v11 08/24] scsi: ufs: mediatek: Add dual 0.9V supply support Louis-Alexis Eyraud
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The mediatek UFS host driver does some pretty bad stuff with regards to
the 0.9V regulator. Instead of just checking for the presence of the
regulator, it adds a cap if it's there, and then checks for the cap. It
also sleeps to stabilise the supply after enabling the regulator, which
is something that should be done by the regulator framework with the
appropriate delay properties in the DTS instead of random sleeps in the
driver code.

Rework this code and rename it to the avdd09 name I've chosen in the
binding for this supply name, instead of the downstream "va09" name that
isn't used by the datasheets for any of these chips.

Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 142 +++++++++++++++++++++++++++-------------
 drivers/ufs/host/ufs-mediatek.h |   3 +-
 2 files changed, 96 insertions(+), 49 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 80c6ba3d026d..eb7a0cc464f4 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -39,6 +39,10 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up);
 #define MAX_SUPP_MAC 64
 #define MCQ_QUEUE_OFFSET(c) ((((c) >> 16) & 0xFF) * 0x200)
 
+struct ufs_mtk_soc_data {
+	bool has_avdd09;
+};
+
 static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
 	{ .wmanufacturerid = UFS_ANY_VENDOR,
 	  .model = UFS_ANY_MODEL,
@@ -49,8 +53,13 @@ static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
 	{}
 };
 
+static const struct ufs_mtk_soc_data mt8183_data = {
+	.has_avdd09 = true,
+};
+
 static const struct of_device_id ufs_mtk_of_match[] = {
-	{ .compatible = "mediatek,mt8183-ufshci" },
+	{ .compatible = "mediatek,mt8183-ufshci", .data = &mt8183_data },
+	{ .compatible = "mediatek,mt8192-ufshci" },
 	{ .compatible = "mediatek,mt8195-ufshci" },
 	{},
 };
@@ -107,13 +116,6 @@ static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba)
 	return host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE;
 }
 
-static bool ufs_mtk_is_va09_supported(struct ufs_hba *hba)
-{
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-
-	return host->caps & UFS_MTK_CAP_VA09_PWR_CTRL;
-}
-
 static bool ufs_mtk_is_broken_vcc(struct ufs_hba *hba)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
@@ -508,44 +510,70 @@ static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
 	return -ETIMEDOUT;
 }
 
+static int ufs_mtk_09v_off(struct ufs_mtk_host *host)
+{
+	struct arm_smccc_res res;
+	int ret;
+
+	if (!host->reg_avdd09)
+		return 0;
+
+	ufs_mtk_va09_pwr_ctrl(res, 0);
+	ret = regulator_disable(host->reg_avdd09);
+	if (ret) {
+		dev_err(host->hba->dev, "Failed to disable avdd09-supply: %pe\n",
+			ERR_PTR(ret));
+		ufs_mtk_va09_pwr_ctrl(res, 1);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ufs_mtk_09v_on(struct ufs_mtk_host *host)
+{
+	struct arm_smccc_res res;
+	int ret;
+
+	if (!host->reg_avdd09)
+		return 0;
+
+	ret = regulator_enable(host->reg_avdd09);
+	if (ret) {
+		dev_err(host->hba->dev, "Failed to enable avdd09-supply: %pe\n",
+			ERR_PTR(ret));
+		return ret;
+	}
+
+	ufs_mtk_va09_pwr_ctrl(res, 1);
+
+	return 0;
+}
+
 static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	struct phy *mphy = host->mphy;
-	struct arm_smccc_res res;
-	int ret = 0;
+	int ret;
 
-	if (!mphy || !(on ^ host->mphy_powered_on))
+	if (!mphy || on == host->mphy_powered_on)
 		return 0;
 
 	if (on) {
-		if (ufs_mtk_is_va09_supported(hba)) {
-			ret = regulator_enable(host->reg_va09);
-			if (ret < 0)
-				goto out;
-			/* wait 200 us to stablize VA09 */
-			usleep_range(200, 210);
-			ufs_mtk_va09_pwr_ctrl(res, 1);
-		}
+		ret = ufs_mtk_09v_on(host);
+		if (ret)
+			return ret;
 		phy_power_on(mphy);
 	} else {
 		phy_power_off(mphy);
-		if (ufs_mtk_is_va09_supported(hba)) {
-			ufs_mtk_va09_pwr_ctrl(res, 0);
-			ret = regulator_disable(host->reg_va09);
-		}
-	}
-out:
-	if (ret) {
-		dev_info(hba->dev,
-			 "failed to %s va09: %d\n",
-			 on ? "enable" : "disable",
-			 ret);
-	} else {
-		host->mphy_powered_on = on;
+		ret = ufs_mtk_09v_off(host);
+		if (ret)
+			return ret;
 	}
 
-	return ret;
+	host->mphy_powered_on = on;
+
+	return 0;
 }
 
 static int ufs_mtk_get_host_clk(struct device *dev, const char *name,
@@ -680,17 +708,6 @@ static void ufs_mtk_init_boost_crypt(struct ufs_hba *hba)
 	return;
 }
 
-static void ufs_mtk_init_va09_pwr_ctrl(struct ufs_hba *hba)
-{
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-
-	host->reg_va09 = regulator_get(hba->dev, "va09");
-	if (IS_ERR(host->reg_va09))
-		dev_info(hba->dev, "failed to get va09");
-	else
-		host->caps |= UFS_MTK_CAP_VA09_PWR_CTRL;
-}
-
 static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
@@ -699,9 +716,6 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
 	if (of_property_read_bool(np, "mediatek,ufs-boost-crypt"))
 		ufs_mtk_init_boost_crypt(hba);
 
-	if (of_property_read_bool(np, "mediatek,ufs-support-va09"))
-		ufs_mtk_init_va09_pwr_ctrl(hba);
-
 	if (of_property_read_bool(np, "mediatek,ufs-disable-ah8"))
 		host->caps |= UFS_MTK_CAP_DISABLE_AH8;
 
@@ -1207,6 +1221,36 @@ static void ufs_mtk_init_mcq_irq(struct ufs_hba *hba)
 	host->mcq_nr_intr = 0;
 }
 
+/**
+ * ufs_mtk_get_supplies - acquire variant-specific supplies
+ * @host: pointer to driver's private &struct ufs_mtk_host instance
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
+{
+	struct device *dev = host->hba->dev;
+	const struct ufs_mtk_soc_data *data = of_device_get_match_data(dev);
+
+	if (!data || !data->has_avdd09)
+		return 0;
+
+	host->reg_avdd09 = devm_regulator_get_optional(dev, "avdd09");
+	if (IS_ERR(host->reg_avdd09)) {
+		if (PTR_ERR(host->reg_avdd09) == -ENODEV) {
+			host->reg_avdd09 = NULL;
+			return 0;
+		}
+
+		return dev_err_probe(dev,
+				     PTR_ERR(host->reg_avdd09),
+				     "Failed to get avdd09 regulator: %pe\n",
+				     host->reg_avdd09);
+	}
+
+	return 0;
+}
+
 /**
  * ufs_mtk_init - find other essential mmio bases
  * @hba: host controller instance
@@ -1290,6 +1334,10 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	ufs_mtk_init_clocks(hba);
 
+	err = ufs_mtk_get_supplies(host);
+	if (err)
+		goto out_variant_clear;
+
 	/*
 	 * ufshcd_vops_init() is invoked after
 	 * ufshcd_setup_clock(true) in ufshcd_hba_init() thus
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index f95f12eb9926..c63740b98e85 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -125,7 +125,6 @@ enum {
  */
 enum ufs_mtk_host_caps {
 	UFS_MTK_CAP_BOOST_CRYPT_ENGINE         = 1 << 0,
-	UFS_MTK_CAP_VA09_PWR_CTRL              = 1 << 1,
 	UFS_MTK_CAP_DISABLE_AH8                = 1 << 2,
 	UFS_MTK_CAP_BROKEN_VCC                 = 1 << 3,
 
@@ -176,7 +175,7 @@ struct ufs_mtk_mcq_intr_info {
 
 struct ufs_mtk_host {
 	struct phy *mphy;
-	struct regulator *reg_va09;
+	struct regulator *reg_avdd09;
 	struct reset_control_bulk_data resets[MTK_UFS_NUM_RESETS];
 	struct ufs_hba *hba;
 	struct ufs_mtk_crypt_cfg *crypt;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 08/24] scsi: ufs: mediatek: Add dual 0.9V supply support
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (6 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 07/24] scsi: ufs: mediatek: Rework 0.9V regulator Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:59   ` sashiko-bot
  2026-09-01 15:38 ` [PATCH v11 09/24] scsi: ufs: mediatek: Rework init function Louis-Alexis Eyraud
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

The MT8196 SoC has an additional pin in comparison of the MT8183 SoC,
that is used to feed the host controller with a 0.9V supply.

In preparation of this SoC support, add in platform data and
driver the management a second optional 0.9V regulator named
"avdd09-1".

Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 82 ++++++++++++++++++++++++++++++-----------
 drivers/ufs/host/ufs-mediatek.h |  1 +
 2 files changed, 61 insertions(+), 22 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index eb7a0cc464f4..f298ea6f6ecb 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -41,6 +41,7 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up);
 
 struct ufs_mtk_soc_data {
 	bool has_avdd09;
+	bool has_avdd09_1;
 };
 
 static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
@@ -515,16 +516,29 @@ static int ufs_mtk_09v_off(struct ufs_mtk_host *host)
 	struct arm_smccc_res res;
 	int ret;
 
-	if (!host->reg_avdd09)
+	if (!host->reg_avdd09 && !host->reg_avdd09_1)
 		return 0;
 
 	ufs_mtk_va09_pwr_ctrl(res, 0);
-	ret = regulator_disable(host->reg_avdd09);
-	if (ret) {
-		dev_err(host->hba->dev, "Failed to disable avdd09-supply: %pe\n",
-			ERR_PTR(ret));
-		ufs_mtk_va09_pwr_ctrl(res, 1);
-		return ret;
+
+	if (host->reg_avdd09) {
+		ret = regulator_disable(host->reg_avdd09);
+		if (ret) {
+			dev_err(host->hba->dev, "Failed to disable avdd09-supply: %pe\n",
+				ERR_PTR(ret));
+			ufs_mtk_va09_pwr_ctrl(res, 1);
+			return ret;
+		}
+	}
+
+	if (host->reg_avdd09_1) {
+		ret = regulator_disable(host->reg_avdd09_1);
+		if (ret) {
+			dev_err(host->hba->dev, "Failed to disable avdd09-1-supply: %pe\n",
+				ERR_PTR(ret));
+			ufs_mtk_va09_pwr_ctrl(res, 1);
+			return ret;
+		}
 	}
 
 	return 0;
@@ -535,14 +549,25 @@ static int ufs_mtk_09v_on(struct ufs_mtk_host *host)
 	struct arm_smccc_res res;
 	int ret;
 
-	if (!host->reg_avdd09)
+	if (!host->reg_avdd09 && !host->reg_avdd09_1)
 		return 0;
 
-	ret = regulator_enable(host->reg_avdd09);
-	if (ret) {
-		dev_err(host->hba->dev, "Failed to enable avdd09-supply: %pe\n",
-			ERR_PTR(ret));
-		return ret;
+	if (host->reg_avdd09) {
+		ret = regulator_enable(host->reg_avdd09);
+		if (ret) {
+			dev_err(host->hba->dev, "Failed to enable avdd09-supply: %pe\n",
+				ERR_PTR(ret));
+			return ret;
+		}
+	}
+
+	if (host->reg_avdd09_1) {
+		ret = regulator_enable(host->reg_avdd09_1);
+		if (ret) {
+			dev_err(host->hba->dev, "Failed to enable avdd09-1-supply: %pe\n",
+				ERR_PTR(ret));
+			return ret;
+		}
 	}
 
 	ufs_mtk_va09_pwr_ctrl(res, 1);
@@ -1232,20 +1257,33 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
 	struct device *dev = host->hba->dev;
 	const struct ufs_mtk_soc_data *data = of_device_get_match_data(dev);
 
-	if (!data || !data->has_avdd09)
+	if (!data)
 		return 0;
 
-	host->reg_avdd09 = devm_regulator_get_optional(dev, "avdd09");
-	if (IS_ERR(host->reg_avdd09)) {
-		if (PTR_ERR(host->reg_avdd09) == -ENODEV) {
+	if (data->has_avdd09) {
+		host->reg_avdd09 = devm_regulator_get_optional(dev, "avdd09");
+		if (IS_ERR(host->reg_avdd09)) {
+			if (PTR_ERR(host->reg_avdd09) != -ENODEV) {
+				return dev_err_probe(dev,
+						     PTR_ERR(host->reg_avdd09),
+						     "Failed to get avdd09 regulator: %pe\n",
+						     host->reg_avdd09);
+			}
 			host->reg_avdd09 = NULL;
-			return 0;
 		}
+	}
 
-		return dev_err_probe(dev,
-				     PTR_ERR(host->reg_avdd09),
-				     "Failed to get avdd09 regulator: %pe\n",
-				     host->reg_avdd09);
+	if (data->has_avdd09_1) {
+		host->reg_avdd09_1 = devm_regulator_get_optional(dev, "avdd09-1");
+		if (IS_ERR(host->reg_avdd09_1)) {
+			if (PTR_ERR(host->reg_avdd09_1) != -ENODEV) {
+				return dev_err_probe(dev,
+						     PTR_ERR(host->reg_avdd09_1),
+						     "Failed to get avdd09-1 regulator: %pe\n",
+						     host->reg_avdd09);
+			}
+			host->reg_avdd09_1 = NULL;
+		}
 	}
 
 	return 0;
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index c63740b98e85..477fb9e36555 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -176,6 +176,7 @@ struct ufs_mtk_mcq_intr_info {
 struct ufs_mtk_host {
 	struct phy *mphy;
 	struct regulator *reg_avdd09;
+	struct regulator *reg_avdd09_1;
 	struct reset_control_bulk_data resets[MTK_UFS_NUM_RESETS];
 	struct ufs_hba *hba;
 	struct ufs_mtk_crypt_cfg *crypt;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 09/24] scsi: ufs: mediatek: Rework init function
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (7 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 08/24] scsi: ufs: mediatek: Add dual 0.9V supply support Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 16:08   ` sashiko-bot
  2026-09-01 15:38 ` [PATCH v11 10/24] scsi: ufs: mediatek: Rework the crypt-boost stuff Louis-Alexis Eyraud
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Printing an error message on ENOMEM is pointless. The print will not
work because there is no memory.

Adding an of_match_device to the init function is pointless. Why would a
different device with a different probe function ever use the same init
function? Get rid of it.

zero-initialising an error variable just so you can then goto a bare
return statement with that error variable to signal success is also
pointless, just return directly, there's no unwind being done.

Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 43 +++++++++++++++--------------------------
 1 file changed, 16 insertions(+), 27 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index f298ea6f6ecb..c5089815696f 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -54,18 +54,6 @@ static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
 	{}
 };
 
-static const struct ufs_mtk_soc_data mt8183_data = {
-	.has_avdd09 = true,
-};
-
-static const struct of_device_id ufs_mtk_of_match[] = {
-	{ .compatible = "mediatek,mt8183-ufshci", .data = &mt8183_data },
-	{ .compatible = "mediatek,mt8192-ufshci" },
-	{ .compatible = "mediatek,mt8195-ufshci" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, ufs_mtk_of_match);
-
 /*
  * Details of UIC Errors
  */
@@ -1301,29 +1289,19 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
  */
 static int ufs_mtk_init(struct ufs_hba *hba)
 {
-	const struct of_device_id *id;
 	struct device *dev = hba->dev;
 	struct ufs_mtk_host *host;
 	struct Scsi_Host *shost = hba->host;
-	int err = 0;
+	int err;
 	struct arm_smccc_res res;
 
 	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
-	if (!host) {
-		err = -ENOMEM;
-		dev_info(dev, "%s: no memory for mtk ufs host\n", __func__);
-		goto out;
-	}
+	if (!host)
+		return -ENOMEM;
 
 	host->hba = hba;
 	ufshcd_set_variant(hba, host);
 
-	id = of_match_device(ufs_mtk_of_match, dev);
-	if (!id) {
-		err = -EINVAL;
-		goto out;
-	}
-
 	/* Initialize host capability */
 	ufs_mtk_init_host_caps(hba);
 
@@ -1397,11 +1375,10 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	ufs_mtk_get_hw_ip_version(hba);
 
-	goto out;
+	return 0;
 
 out_variant_clear:
 	ufshcd_set_variant(hba, NULL);
-out:
 	return err;
 }
 
@@ -2443,6 +2420,18 @@ static const struct ufs_hba_variant_ops ufs_hba_mtk_vops = {
 	.config_scsi_dev     = ufs_mtk_config_scsi_dev,
 };
 
+static const struct ufs_mtk_soc_data mt8183_data = {
+	.has_avdd09 = true,
+};
+
+static const struct of_device_id ufs_mtk_of_match[] = {
+	{ .compatible = "mediatek,mt8183-ufshci", .data = &mt8183_data },
+	{ .compatible = "mediatek,mt8192-ufshci" },
+	{ .compatible = "mediatek,mt8195-ufshci" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ufs_mtk_of_match);
+
 /**
  * ufs_mtk_probe - probe routine of the driver
  * @pdev: pointer to Platform device handle

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 10/24] scsi: ufs: mediatek: Rework the crypt-boost stuff
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (8 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 09/24] scsi: ufs: mediatek: Rework init function Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 15:38 ` [PATCH v11 11/24] scsi: ufs: mediatek: Handle misc host voltage regulators Louis-Alexis Eyraud
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

I don't know whether the crypt-boost functionality as it is currently
implemented is even appropriate for mainline. It might be better done in
some generic way. But what I do know is that I can rework the code to
make it less obtuse.

Prefix the boost stuff with the appropriate vendor prefix, remove the
pointless clock wrappers, and rework the function.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang (王信友) <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 89 ++++++++++++++---------------------------
 1 file changed, 31 insertions(+), 58 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index c5089815696f..6bbf53b658f2 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -589,21 +589,6 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
 	return 0;
 }
 
-static int ufs_mtk_get_host_clk(struct device *dev, const char *name,
-				struct clk **clk_out)
-{
-	struct clk *clk;
-	int err = 0;
-
-	clk = devm_clk_get(dev, name);
-	if (IS_ERR(clk))
-		err = PTR_ERR(clk);
-	else
-		*clk_out = clk;
-
-	return err;
-}
-
 static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
@@ -660,65 +645,53 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 	clk_disable_unprepare(cfg->clk_crypt_mux);
 }
 
-static int ufs_mtk_init_host_clk(struct ufs_hba *hba, const char *name,
-				 struct clk **clk)
-{
-	int ret;
-
-	ret = ufs_mtk_get_host_clk(hba->dev, name, clk);
-	if (ret) {
-		dev_info(hba->dev, "%s: failed to get %s: %d", __func__,
-			 name, ret);
-	}
-
-	return ret;
-}
-
 static void ufs_mtk_init_boost_crypt(struct ufs_hba *hba)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	struct ufs_mtk_crypt_cfg *cfg;
 	struct device *dev = hba->dev;
-	struct regulator *reg;
 	u32 volt;
+	int ret;
 
-	host->crypt = devm_kzalloc(dev, sizeof(*(host->crypt)),
-				   GFP_KERNEL);
-	if (!host->crypt)
-		goto disable_caps;
+	cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return;
 
-	reg = devm_regulator_get_optional(dev, "dvfsrc-vcore");
-	if (IS_ERR(reg)) {
-		dev_info(dev, "failed to get dvfsrc-vcore: %ld",
-			 PTR_ERR(reg));
-		goto disable_caps;
+	cfg->reg_vcore = devm_regulator_get_optional(dev, "dvfsrc-vcore");
+	if (IS_ERR(cfg->reg_vcore)) {
+		dev_err(dev, "Failed to get dvfsrc-vcore: %pe\n", cfg->reg_vcore);
+		return;
 	}
 
-	if (of_property_read_u32(dev->of_node, "boost-crypt-vcore-min",
-				 &volt)) {
-		dev_info(dev, "failed to get boost-crypt-vcore-min");
-		goto disable_caps;
+	ret = of_property_read_u32(dev->of_node, "mediatek,boost-crypt-vcore-min",
+				   &volt);
+	if (ret) {
+		dev_err(dev, "Failed to get mediatek,boost-crypt-vcore-min: %pe\n",
+			ERR_PTR(ret));
+		return;
 	}
+	cfg->vcore_volt = volt;
 
-	cfg = host->crypt;
-	if (ufs_mtk_init_host_clk(hba, "crypt_mux",
-				  &cfg->clk_crypt_mux))
-		goto disable_caps;
+	cfg->clk_crypt_mux = devm_clk_get(dev, "crypt_mux");
+	if (IS_ERR(cfg->clk_crypt_mux)) {
+		dev_err(dev, "Failed to get clock crypt_mux: %pe\n", cfg->clk_crypt_mux);
+		return;
+	}
 
-	if (ufs_mtk_init_host_clk(hba, "crypt_lp",
-				  &cfg->clk_crypt_lp))
-		goto disable_caps;
+	cfg->clk_crypt_lp = devm_clk_get(dev, "crypt_lp");
+	if (IS_ERR(cfg->clk_crypt_lp)) {
+		dev_err(dev, "Failed to get clock crypt_lp: %pe\n", cfg->clk_crypt_lp);
+		return;
+	}
 
-	if (ufs_mtk_init_host_clk(hba, "crypt_perf",
-				  &cfg->clk_crypt_perf))
-		goto disable_caps;
+	cfg->clk_crypt_perf = devm_clk_get(dev, "crypt_perf");
+	if (IS_ERR(cfg->clk_crypt_perf)) {
+		dev_err(dev, "Failed to get clock crypt_perf: %pe\n", cfg->clk_crypt_perf);
+		return;
+	}
 
-	cfg->reg_vcore = reg;
-	cfg->vcore_volt = volt;
+	host->crypt = cfg;
 	host->caps |= UFS_MTK_CAP_BOOST_CRYPT_ENGINE;
-
-disable_caps:
-	return;
 }
 
 static void ufs_mtk_init_host_caps(struct ufs_hba *hba)

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 11/24] scsi: ufs: mediatek: Handle misc host voltage regulators
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (9 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 10/24] scsi: ufs: mediatek: Rework the crypt-boost stuff Louis-Alexis Eyraud
@ 2026-09-01 15:38 ` Louis-Alexis Eyraud
  2026-09-01 16:11   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 12/24] scsi: ufs: mediatek: Remove undocumented downstream reset cruft Louis-Alexis Eyraud
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:38 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

MediaTek SoCs handled by this driver contain a per-SoC specific set of
miscellaneous supplies. These feed parts of the UFS controller silicon
inside the SoC, as opposed to the UFS card.

Add the necessary driver code to acquire these supplies using the
regulator bulk API. They should be kept on during suspend, so enable
them when acquiring.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 6bbf53b658f2..f61727879c3c 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -42,6 +42,8 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up);
 struct ufs_mtk_soc_data {
 	bool has_avdd09;
 	bool has_avdd09_1;
+	u8 num_reg_names;
+	const char *const *reg_names;
 };
 
 static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
@@ -1217,10 +1219,20 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
 {
 	struct device *dev = host->hba->dev;
 	const struct ufs_mtk_soc_data *data = of_device_get_match_data(dev);
+	int ret;
 
 	if (!data)
 		return 0;
 
+	if (data->num_reg_names) {
+		ret = devm_regulator_bulk_get_enable(dev, data->num_reg_names,
+						     data->reg_names);
+		if (ret) {
+			dev_err(dev, "Failed to get misc regulators: %pe\n", ERR_PTR(ret));
+			return ret;
+		}
+	}
+
 	if (data->has_avdd09) {
 		host->reg_avdd09 = devm_regulator_get_optional(dev, "avdd09");
 		if (IS_ERR(host->reg_avdd09)) {
@@ -2393,14 +2405,30 @@ static const struct ufs_hba_variant_ops ufs_hba_mtk_vops = {
 	.config_scsi_dev     = ufs_mtk_config_scsi_dev,
 };
 
+static const char *const ufs_mtk_regs_avdd12_avdd18[] = {
+	"avdd12", "avdd18"
+};
+
+static const char *const ufs_mtk_regs_avdd12_ckbuf_avdd18[] = {
+	"avdd12", "avdd12-ckbuf", "avdd18"
+};
+
 static const struct ufs_mtk_soc_data mt8183_data = {
 	.has_avdd09 = true,
+	.reg_names = ufs_mtk_regs_avdd12_avdd18,
+	.num_reg_names = ARRAY_SIZE(ufs_mtk_regs_avdd12_avdd18),
+};
+
+static const struct ufs_mtk_soc_data mt8192_8195_data = {
+	.has_avdd09 = false,
+	.reg_names = ufs_mtk_regs_avdd12_ckbuf_avdd18,
+	.num_reg_names = ARRAY_SIZE(ufs_mtk_regs_avdd12_ckbuf_avdd18),
 };
 
 static const struct of_device_id ufs_mtk_of_match[] = {
 	{ .compatible = "mediatek,mt8183-ufshci", .data = &mt8183_data },
-	{ .compatible = "mediatek,mt8192-ufshci" },
-	{ .compatible = "mediatek,mt8195-ufshci" },
+	{ .compatible = "mediatek,mt8192-ufshci", .data = &mt8192_8195_data },
+	{ .compatible = "mediatek,mt8195-ufshci", .data = &mt8192_8195_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ufs_mtk_of_match);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 12/24] scsi: ufs: mediatek: Remove undocumented downstream reset cruft
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (10 preceding siblings ...)
  2026-09-01 15:38 ` [PATCH v11 11/24] scsi: ufs: mediatek: Handle misc host voltage regulators Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 13/24] scsi: ufs: mediatek: Remove vendor kernel quirks cruft Louis-Alexis Eyraud
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The MediaTek UFS host driver's probe function allows using a
ti,syscon-reset as a reset, without going through the appropriate
abstractions, or by documenting this in the binding at all.

Remove this, it's downstream code and does not belong here.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 33 +++------------------------------
 1 file changed, 3 insertions(+), 30 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index f61727879c3c..b01fc37bd259 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -2442,38 +2442,12 @@ MODULE_DEVICE_TABLE(of, ufs_mtk_of_match);
 static int ufs_mtk_probe(struct platform_device *pdev)
 {
 	int err;
-	struct device *dev = &pdev->dev, *phy_dev = NULL;
-	struct device_node *reset_node, *phy_node = NULL;
-	struct platform_device *reset_pdev, *phy_pdev = NULL;
-	struct device_link *link;
 	struct ufs_hba *hba;
+	struct platform_device *phy_pdev = NULL;
+	struct device *dev = &pdev->dev, *phy_dev = NULL;
+	struct device_node *phy_node = NULL;
 	struct ufs_mtk_host *host;
 
-	reset_node = of_find_compatible_node(NULL, NULL,
-					     "ti,syscon-reset");
-	if (!reset_node) {
-		dev_notice(dev, "find ti,syscon-reset fail\n");
-		goto skip_reset;
-	}
-	reset_pdev = of_find_device_by_node(reset_node);
-	if (!reset_pdev) {
-		dev_notice(dev, "find reset_pdev fail\n");
-		goto skip_reset;
-	}
-	link = device_link_add(dev, &reset_pdev->dev,
-		DL_FLAG_AUTOPROBE_CONSUMER);
-	put_device(&reset_pdev->dev);
-	if (!link) {
-		dev_notice(dev, "add reset device_link fail\n");
-		goto skip_reset;
-	}
-	/* supplier is not probed */
-	if (link->status == DL_STATE_DORMANT) {
-		err = -EPROBE_DEFER;
-		goto out;
-	}
-
-skip_reset:
 	/* find phy node */
 	phy_node = of_parse_phandle(dev->of_node, "phys", 0);
 
@@ -2519,7 +2493,6 @@ static int ufs_mtk_probe(struct platform_device *pdev)
 
 out:
 	of_node_put(phy_node);
-	of_node_put(reset_node);
 	return err;
 }
 

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 13/24] scsi: ufs: mediatek: Remove vendor kernel quirks cruft
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (11 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 12/24] scsi: ufs: mediatek: Remove undocumented downstream reset cruft Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 14/24] scsi: ufs: mediatek: Use the common PHY framework Louis-Alexis Eyraud
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Krzysztof Kozlowski,
	Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Both ufs_mtk_vreg_fix_vcc and ufs_mtk_vreg_fix_vccqx look like they are
vendor kernel hacks to work around existing downstream device trees.
Mainline does not need or want them, so remove them.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 69 -----------------------------------------
 1 file changed, 69 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index b01fc37bd259..ae053f40aaf4 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1046,73 +1046,6 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 	}
 }
 
-#define MAX_VCC_NAME 30
-static int ufs_mtk_vreg_fix_vcc(struct ufs_hba *hba)
-{
-	struct ufs_vreg_info *info = &hba->vreg_info;
-	struct device_node *np = hba->dev->of_node;
-	struct device *dev = hba->dev;
-	char vcc_name[MAX_VCC_NAME];
-	struct arm_smccc_res res;
-	int err, ver;
-
-	if (info->vcc)
-		return 0;
-
-	if (of_property_read_bool(np, "mediatek,ufs-vcc-by-num")) {
-		ufs_mtk_get_vcc_num(res);
-		if (res.a1 > UFS_VCC_NONE && res.a1 < UFS_VCC_MAX)
-			snprintf(vcc_name, MAX_VCC_NAME, "vcc-opt%lu", res.a1);
-		else
-			return -ENODEV;
-	} else if (of_property_read_bool(np, "mediatek,ufs-vcc-by-ver")) {
-		ver = (hba->dev_info.wspecversion & 0xF00) >> 8;
-		snprintf(vcc_name, MAX_VCC_NAME, "vcc-ufs%u", ver);
-	} else {
-		return 0;
-	}
-
-	err = ufshcd_populate_vreg(dev, vcc_name, &info->vcc, false);
-	if (err)
-		return err;
-
-	err = ufshcd_get_vreg(dev, info->vcc);
-	if (err)
-		return err;
-
-	err = regulator_enable(info->vcc->reg);
-	if (!err) {
-		info->vcc->enabled = true;
-		dev_info(dev, "%s: %s enabled\n", __func__, vcc_name);
-	}
-
-	return err;
-}
-
-static void ufs_mtk_vreg_fix_vccqx(struct ufs_hba *hba)
-{
-	struct ufs_vreg_info *info = &hba->vreg_info;
-	struct ufs_vreg **vreg_on, **vreg_off;
-
-	if (hba->dev_info.wspecversion >= 0x0300) {
-		vreg_on = &info->vccq;
-		vreg_off = &info->vccq2;
-	} else {
-		vreg_on = &info->vccq2;
-		vreg_off = &info->vccq;
-	}
-
-	if (*vreg_on)
-		(*vreg_on)->always_on = true;
-
-	if (*vreg_off) {
-		regulator_disable((*vreg_off)->reg);
-		devm_kfree(hba->dev, (*vreg_off)->name);
-		devm_kfree(hba->dev, *vreg_off);
-		*vreg_off = NULL;
-	}
-}
-
 static void ufs_mtk_setup_clk_gating(struct ufs_hba *hba)
 {
 	unsigned long flags;
@@ -2031,8 +1964,6 @@ static void ufs_mtk_fixup_dev_quirks(struct ufs_hba *hba)
 	     host->ip_ver == IP_VER_MT6995_B0))
 		hba->quirks |= UFSHCD_QUIRK_VCC_ON_DELAY;
 
-	ufs_mtk_vreg_fix_vcc(hba);
-	ufs_mtk_vreg_fix_vccqx(hba);
 	ufs_mtk_fix_ahit(hba);
 	ufs_mtk_fix_clock_scaling(hba);
 }

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 14/24] scsi: ufs: mediatek: Use the common PHY framework
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (12 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 13/24] scsi: ufs: mediatek: Remove vendor kernel quirks cruft Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:28   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 15/24] scsi: ufs: mediatek: Remove mediatek,ufs-broken-rtc property Louis-Alexis Eyraud
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

There is no need to reinvent the PHY framework, especially not its OF
parsing.

Change the code to simply use the PHY framework to acquire the device's
PHY in the ufshcd init, so that it's device linked to the right device.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 134 +++++++++++++---------------------------
 drivers/ufs/host/ufs-mediatek.h |   1 -
 2 files changed, 42 insertions(+), 93 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index ae053f40aaf4..1df16ce29ea4 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -296,44 +296,6 @@ static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
 	return 0;
 }
 
-static int ufs_mtk_bind_mphy(struct ufs_hba *hba)
-{
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-	struct device *dev = hba->dev;
-	struct device_node *np = dev->of_node;
-	int err = 0;
-
-	host->mphy = devm_of_phy_get_by_index(dev, np, 0);
-
-	if (host->mphy == ERR_PTR(-EPROBE_DEFER)) {
-		/*
-		 * UFS driver might be probed before the phy driver does.
-		 * In that case we would like to return EPROBE_DEFER code.
-		 */
-		err = -EPROBE_DEFER;
-		dev_info(dev,
-			 "%s: required phy hasn't probed yet. err = %d\n",
-			__func__, err);
-	} else if (IS_ERR(host->mphy)) {
-		err = PTR_ERR(host->mphy);
-		if (err != -ENODEV) {
-			dev_info(dev, "%s: PHY get failed %d\n", __func__,
-				 err);
-		}
-	}
-
-	if (err)
-		host->mphy = NULL;
-	/*
-	 * Allow unbound mphy because not every platform needs specific
-	 * mphy control.
-	 */
-	if (err == -ENODEV)
-		err = 0;
-
-	return err;
-}
-
 static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
@@ -1225,13 +1187,21 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	ufs_mtk_init_mcq_irq(hba);
 
-	err = ufs_mtk_bind_mphy(hba);
-	if (err)
+	host->mphy = devm_phy_optional_get(dev, NULL);
+	if (IS_ERR(host->mphy)) {
+		err = dev_err_probe(dev, PTR_ERR(host->mphy), "Failed to get PHY\n");
+		goto out_variant_clear;
+	}
+
+	err = phy_init(host->mphy);
+	if (err) {
+		dev_err_probe(dev, err, "Failed to initialize PHY\n");
 		goto out_variant_clear;
+	}
 
 	err = ufs_mtk_init_reset(hba);
 	if (err)
-		goto out_variant_clear;
+		goto out_phy_exit;
 
 	/* Enable runtime autosuspend */
 	hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
@@ -1270,7 +1240,7 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	err = ufs_mtk_get_supplies(host);
 	if (err)
-		goto out_variant_clear;
+		goto out_phy_exit;
 
 	/*
 	 * ufshcd_vops_init() is invoked after
@@ -1295,11 +1265,22 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	return 0;
 
+out_phy_exit:
+	phy_exit(host->mphy);
 out_variant_clear:
 	ufshcd_set_variant(hba, NULL);
 	return err;
 }
 
+static void ufs_mtk_exit(struct ufs_hba *hba)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+	ufs_mtk_mphy_power_on(hba, false);
+
+	phy_exit(host->mphy);
+}
+
 static int ufs_mtk_negotiate_pwr_mode(struct ufs_hba *hba,
 				      const struct ufs_pa_layer_attr *dev_max_params,
 				      struct ufs_pa_layer_attr *dev_req_params)
@@ -2312,6 +2293,7 @@ static void ufs_mtk_config_scsi_dev(struct scsi_device *sdev)
 static const struct ufs_hba_variant_ops ufs_hba_mtk_vops = {
 	.name                = "mediatek.ufshci",
 	.init                = ufs_mtk_init,
+	.exit                = ufs_mtk_exit,
 	.get_ufs_hci_version = ufs_mtk_get_ufs_hci_version,
 	.setup_clocks        = ufs_mtk_setup_clocks,
 	.hce_enable_notify   = ufs_mtk_hce_enable_notify,
@@ -2372,48 +2354,15 @@ MODULE_DEVICE_TABLE(of, ufs_mtk_of_match);
  */
 static int ufs_mtk_probe(struct platform_device *pdev)
 {
-	int err;
+	struct device *dev = &pdev->dev;
 	struct ufs_hba *hba;
-	struct platform_device *phy_pdev = NULL;
-	struct device *dev = &pdev->dev, *phy_dev = NULL;
-	struct device_node *phy_node = NULL;
-	struct ufs_mtk_host *host;
-
-	/* find phy node */
-	phy_node = of_parse_phandle(dev->of_node, "phys", 0);
-
-	if (phy_node) {
-		phy_pdev = of_find_device_by_node(phy_node);
-		if (!phy_pdev)
-			goto skip_phy;
-		phy_dev = &phy_pdev->dev;
-
-		pm_runtime_set_active(phy_dev);
-		pm_runtime_enable(phy_dev);
-		pm_runtime_get_sync(phy_dev);
-
-		put_device(phy_dev);
-		dev_info(dev, "phys node found\n");
-	} else {
-		dev_notice(dev, "phys node not found\n");
-	}
+	int ret;
 
-skip_phy:
-	/* perform generic probe */
-	err = ufshcd_pltfrm_init(pdev, &ufs_hba_mtk_vops);
-	if (err) {
-		dev_err(dev, "probe failed %d\n", err);
-		goto out;
-	}
+	ret = ufshcd_pltfrm_init(pdev, &ufs_hba_mtk_vops);
+	if (ret)
+		return dev_err_probe(dev, ret, "Generic platform probe failed\n");
 
 	hba = platform_get_drvdata(pdev);
-	if (!hba)
-		goto out;
-
-	if (phy_node && phy_dev) {
-		host = ufshcd_get_variant(hba);
-		host->phy_dev = phy_dev;
-	}
 
 	/*
 	 * Because the default power setting of VSx (the upper layer of
@@ -2422,16 +2371,12 @@ static int ufs_mtk_probe(struct platform_device *pdev)
 	 */
 	ufs_mtk_dev_vreg_set_lpm(hba, false);
 
-out:
-	of_node_put(phy_node);
-	return err;
+	return 0;
 }
 
 /**
  * ufs_mtk_remove - set driver_data of the device to NULL
  * @pdev: pointer to platform device handle
- *
- * Always return 0
  */
 static void ufs_mtk_remove(struct platform_device *pdev)
 {
@@ -2488,9 +2433,8 @@ static int ufs_mtk_system_resume(struct device *dev)
 static int ufs_mtk_runtime_suspend(struct device *dev)
 {
 	struct ufs_hba *hba = dev_get_drvdata(dev);
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	struct arm_smccc_res res;
-	int ret = 0;
+	int ret;
 
 	ret = ufshcd_runtime_suspend(dev);
 	if (ret)
@@ -2501,8 +2445,11 @@ static int ufs_mtk_runtime_suspend(struct device *dev)
 	if (ufs_mtk_is_rtff_mtcmos(hba))
 		ufs_mtk_mtcmos_ctrl(false, res);
 
-	if (host->phy_dev)
-		pm_runtime_put_sync(host->phy_dev);
+	ret = ufs_mtk_mphy_power_on(hba, false);
+	if (ret) {
+		dev_err(dev, "Failed to power off PHY: %pe\n", ERR_PTR(ret));
+		return ret;
+	}
 
 	return 0;
 }
@@ -2510,14 +2457,17 @@ static int ufs_mtk_runtime_suspend(struct device *dev)
 static int ufs_mtk_runtime_resume(struct device *dev)
 {
 	struct ufs_hba *hba = dev_get_drvdata(dev);
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	struct arm_smccc_res res;
+	int ret;
 
 	if (ufs_mtk_is_rtff_mtcmos(hba))
 		ufs_mtk_mtcmos_ctrl(true, res);
 
-	if (host->phy_dev)
-		pm_runtime_get_sync(host->phy_dev);
+	ret = ufs_mtk_mphy_power_on(hba, true);
+	if (ret) {
+		dev_err(dev, "Failed to power on PHY: %pe\n", ERR_PTR(ret));
+		return ret;
+	}
 
 	ufs_mtk_dev_vreg_set_lpm(hba, false);
 
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 477fb9e36555..bde2b53f5798 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -196,7 +196,6 @@ struct ufs_mtk_host {
 	bool is_mcq_intr_enabled;
 	int mcq_nr_intr;
 	struct ufs_mtk_mcq_intr_info mcq_intr_info[UFSHCD_MAX_Q_NR];
-	struct device *phy_dev;
 };
 
 /* MTK delay of autosuspend: 500 ms */

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 15/24] scsi: ufs: mediatek: Remove mediatek,ufs-broken-rtc property
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (13 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 14/24] scsi: ufs: mediatek: Use the common PHY framework Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 16/24] scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths Louis-Alexis Eyraud
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

This flag property was never described in the binding, and its
capability wrapper seems pointless.

If one of the MediaTek SoCs needs the ufshcd quirk applied, then this
can be done per-compatible, without needing to give the device tree
author the option to forget to set it.

Remove it and the associated capability flag wrapping code.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 5 -----
 drivers/ufs/host/ufs-mediatek.h | 2 --
 2 files changed, 7 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 1df16ce29ea4..5d8c02b7a857 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -684,9 +684,6 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
 	if (of_property_read_bool(np, "mediatek,ufs-rtff-mtcmos"))
 		host->caps |= UFS_MTK_CAP_RTFF_MTCMOS;
 
-	if (of_property_read_bool(np, "mediatek,ufs-broken-rtc"))
-		host->caps |= UFS_MTK_CAP_MCQ_BROKEN_RTC;
-
 	dev_info(hba->dev, "caps: 0x%x", host->caps);
 }
 
@@ -1225,8 +1222,6 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	hba->quirks |= UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL;
 
 	hba->quirks |= UFSHCD_QUIRK_MCQ_BROKEN_INTR;
-	if (host->caps & UFS_MTK_CAP_MCQ_BROKEN_RTC)
-		hba->quirks |= UFSHCD_QUIRK_MCQ_BROKEN_RTC;
 
 	hba->vps->wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(80);
 
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index bde2b53f5798..d97951ee1f4e 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -138,8 +138,6 @@ enum ufs_mtk_host_caps {
 	UFS_MTK_CAP_DISABLE_MCQ                = 1 << 8,
 	/* Control MTCMOS with RTFF */
 	UFS_MTK_CAP_RTFF_MTCMOS                = 1 << 9,
-
-	UFS_MTK_CAP_MCQ_BROKEN_RTC             = 1 << 10,
 };
 
 struct ufs_mtk_crypt_cfg {

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 16/24] scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (14 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 15/24] scsi: ufs: mediatek: Remove mediatek,ufs-broken-rtc property Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:16   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 17/24] scsi: ufs: mediatek: Clean up logging prints Louis-Alexis Eyraud
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Errors should be printed at the correct log level. Additionally, it
looks like some "goto out"'s were omitted in the scale up case, which
looks like a mistake, as the scale down branch of the code does use
them.

Rework the error messages to make them nicer and at the correct
verbosity, and add the missing gotos.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 41 +++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 5d8c02b7a857..43fb5dbb250b 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -2011,16 +2011,16 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 
 	ret = clk_prepare_enable(clki->clk);
 	if (ret) {
-		dev_info(hba->dev,
-			 "clk_prepare_enable() fail, ret: %d\n", ret);
+		dev_err(hba->dev, "%s: Failed to enable clock: %pe\n", __func__, ERR_PTR(ret));
 		return;
 	}
 
 	if (clk_fde_scale) {
 		ret = clk_prepare_enable(fde_clki->clk);
 		if (ret) {
-			dev_info(hba->dev,
-				 "fde clk_prepare_enable() fail, ret: %d\n", ret);
+			dev_err(hba->dev, "%s: Failed to enable FDE clock: %pe\n",
+				__func__, ERR_PTR(ret));
+			clk_disable_unprepare(clki->clk);
 			return;
 		}
 	}
@@ -2029,51 +2029,48 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 		if (clk_bind_vcore) {
 			ret = regulator_set_voltage(reg, volt, INT_MAX);
 			if (ret) {
-				dev_info(hba->dev,
-					"Failed to set vcore to %d\n", volt);
+				dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
 				goto out;
 			}
 		}
 
 		ret = clk_set_parent(clki->clk, mclk->ufs_sel_max_clki->clk);
 		if (ret) {
-			dev_info(hba->dev, "Failed to set clk mux, ret = %d\n",
-				ret);
+			dev_err(hba->dev, "%s: Failed to set clock mux: %pe\n",
+				__func__, ERR_PTR(ret));
+			goto out;
 		}
 
 		if (clk_fde_scale) {
-			ret = clk_set_parent(fde_clki->clk,
-				mclk->ufs_fde_max_clki->clk);
+			ret = clk_set_parent(fde_clki->clk, mclk->ufs_fde_max_clki->clk);
 			if (ret) {
-				dev_info(hba->dev,
-					"Failed to set fde clk mux, ret = %d\n",
-					ret);
+				dev_err(hba->dev, "%s: Failed to set fde clock mux: %pe\n",
+					__func__, ERR_PTR(ret));
+				goto out;
 			}
 		}
 	} else {
 		if (clk_fde_scale) {
-			ret = clk_set_parent(fde_clki->clk,
-				mclk->ufs_fde_min_clki->clk);
+			ret = clk_set_parent(fde_clki->clk, mclk->ufs_fde_min_clki->clk);
 			if (ret) {
-				dev_info(hba->dev,
-					"Failed to set fde clk mux, ret = %d\n",
-					ret);
+				dev_err(hba->dev, "%s: Failed to set fde clock mux: %pe\n",
+					__func__, ERR_PTR(ret));
 				goto out;
 			}
 		}
 
 		ret = clk_set_parent(clki->clk, mclk->ufs_sel_min_clki->clk);
 		if (ret) {
-			dev_info(hba->dev, "Failed to set clk mux, ret = %d\n",
-				ret);
+			dev_err(hba->dev, "%s: Failed to set clock mux: %pe\n",
+				__func__, ERR_PTR(ret));
 			goto out;
 		}
 
 		if (clk_bind_vcore) {
 			ret = regulator_set_voltage(reg, 0, INT_MAX);
 			if (ret) {
-				dev_info(hba->dev,
-					"failed to set vcore to MIN\n");
+				dev_err(hba->dev, "%s: Failed to set vcore to minimum: %pe\n",
+					__func__, ERR_PTR(ret));
 			}
 		}
 	}

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 17/24] scsi: ufs: mediatek: Clean up logging prints
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (15 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 16/24] scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:18   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 18/24] scsi: ufs: mediatek: Rework ufs_mtk_wait_idle_state Louis-Alexis Eyraud
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The Linux kernel's log buffer provides many levels of verbosity,
associated with different semantic meanings. Care should be taken to
only log useful information to the info level, and log errors to the
error level.

The MediaTek UFS driver does not do this. It freely logs verbose debug
information to the info level, errors to the info level, and sometimes
errors to the warning level.

Adjust all the wrapped kprintf invocations to rectify this situation.
Use user-friendly %pe format codes for printing errors where possible.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 91 ++++++++++++++++++-----------------------
 1 file changed, 40 insertions(+), 51 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 43fb5dbb250b..a84bffe069eb 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -194,8 +194,8 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba)
 
 	ufs_mtk_crypto_ctrl(res, 1);
 	if (res.a0) {
-		dev_info(hba->dev, "%s: crypto enable failed, err: %lu\n",
-			 __func__, res.a0);
+		dev_err(hba->dev, "%s: crypto enable failed with error %lu, disabling\n",
+			__func__, res.a0);
 		hba->caps &= ~UFSHCD_CAP_CRYPTO;
 	}
 }
@@ -569,40 +569,38 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 
 	ret = clk_prepare_enable(cfg->clk_crypt_mux);
 	if (ret) {
-		dev_info(hba->dev, "clk_prepare_enable(): %d\n",
-			 ret);
+		dev_err(hba->dev, "%s: Failed to enable clk_crypt_mux: %pe\n",
+			__func__, ERR_PTR(ret));
 		return;
 	}
 
 	if (boost) {
 		ret = regulator_set_voltage(reg, volt, INT_MAX);
 		if (ret) {
-			dev_info(hba->dev,
-				 "failed to set vcore to %d\n", volt);
+			dev_err(hba->dev, "%s: Failed to set vcore to %d: %pe\n",
+				__func__, volt, ERR_PTR(ret));
 			goto out;
 		}
 
-		ret = clk_set_parent(cfg->clk_crypt_mux,
-				     cfg->clk_crypt_perf);
+		ret = clk_set_parent(cfg->clk_crypt_mux, cfg->clk_crypt_perf);
 		if (ret) {
-			dev_info(hba->dev,
-				 "failed to set clk_crypt_perf\n");
+			dev_err(hba->dev, "%s: Failed to reparent clk_crypt_perf: %pe\n",
+				__func__, ERR_PTR(ret));
 			regulator_set_voltage(reg, 0, INT_MAX);
 			goto out;
 		}
 	} else {
-		ret = clk_set_parent(cfg->clk_crypt_mux,
-				     cfg->clk_crypt_lp);
+		ret = clk_set_parent(cfg->clk_crypt_mux, cfg->clk_crypt_lp);
 		if (ret) {
-			dev_info(hba->dev,
-				 "failed to set clk_crypt_lp\n");
+			dev_err(hba->dev, "%s: Failed to reparent clk_crypt_lp: %pe\n",
+				__func__, ERR_PTR(ret));
 			goto out;
 		}
 
 		ret = regulator_set_voltage(reg, 0, INT_MAX);
 		if (ret) {
-			dev_info(hba->dev,
-				 "failed to set vcore to MIN\n");
+			dev_err(hba->dev, "%s: Failed to set vcore to minimum: %pe\n",
+				__func__, ERR_PTR(ret));
 		}
 	}
 out:
@@ -792,10 +790,8 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
 		if (clk_pwr_off) {
 			ufs_mtk_pwr_ctrl(hba, false);
 		} else {
-			dev_warn(hba->dev, "Clock is not turned off, hba->ahit = 0x%x, AHIT = 0x%x\n",
-				hba->ahit,
-				ufshcd_readl(hba,
-					REG_AUTO_HIBERNATE_IDLE_TIMER));
+			dev_warn(hba->dev, "Clock isn't off, hba->ahit = 0x%x, AHIT = 0x%x\n",
+				 hba->ahit, ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER));
 		}
 		ufs_mtk_mcq_disable_irq(hba);
 	} else if (on && status == POST_CHANGE) {
@@ -839,11 +835,11 @@ static void ufs_mtk_mcq_set_irq_affinity(struct ufs_hba *hba, unsigned int cpu)
 	_cpu = (cpu == 0) ? 3 : cpu;
 	ret = irq_set_affinity(irq, cpumask_of(_cpu));
 	if (ret) {
-		dev_err(hba->dev, "set irq %d affinity to CPU %d failed\n",
+		dev_err(hba->dev, "setting irq %d affinity to CPU %d failed\n",
 			irq, _cpu);
 		return;
 	}
-	dev_info(hba->dev, "set irq %d affinity to CPU: %d\n", irq, _cpu);
+	dev_dbg(hba->dev, "set irq %d affinity to CPU %d\n", irq, _cpu);
 }
 
 static bool ufs_mtk_is_legacy_chipset(struct ufs_hba *hba, u32 hw_ip_ver)
@@ -859,7 +855,8 @@ static bool ufs_mtk_is_legacy_chipset(struct ufs_hba *hba, u32 hw_ip_ver)
 	default:
 		break;
 	}
-	dev_info(hba->dev, "legacy IP version - 0x%x, is legacy : %d", hw_ip_ver, is_legacy);
+	dev_dbg(hba->dev, "IP version 0x%x, legacy = %s", hw_ip_ver,
+		str_true_false(is_legacy));
 
 	return is_legacy;
 }
@@ -964,15 +961,12 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 		}
 	}
 
-	list_for_each_entry(clki, head, list) {
-		dev_info(hba->dev, "clk \"%s\" present", clki->name);
-	}
+	list_for_each_entry(clki, head, list)
+		dev_dbg(hba->dev, "clk \"%s\" present", clki->name);
 
 	if (!ufs_mtk_is_clk_scale_ready(hba)) {
 		hba->caps &= ~UFSHCD_CAP_CLK_SCALING;
-		dev_info(hba->dev,
-			 "%s: Clk-scaling not ready. Feature disabled.",
-			 __func__);
+		dev_info(hba->dev, "%s: Clock scaling unavailable", __func__);
 		return;
 	}
 
@@ -982,8 +976,8 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 	 */
 	reg = devm_regulator_get_optional(dev, "dvfsrc-vcore");
 	if (IS_ERR(reg)) {
-		dev_info(dev, "failed to get dvfsrc-vcore: %ld",
-			 PTR_ERR(reg));
+		if (PTR_ERR(reg) != -ENODEV)
+			dev_err(dev, "Failed to get dvfsrc-vcore: %pe\n", reg);
 		return;
 	}
 
@@ -997,12 +991,9 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 	host->mclk.vcore_volt = volt;
 
 	/* If default boot is max gear, request vcore */
-	if (reg && volt && host->clk_scale_up) {
-		if (regulator_set_voltage(reg, volt, INT_MAX)) {
-			dev_info(hba->dev,
-				"Failed to set vcore to %d\n", volt);
-		}
-	}
+	if (reg && volt && host->clk_scale_up)
+		if (regulator_set_voltage(reg, volt, INT_MAX))
+			dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
 }
 
 static void ufs_mtk_setup_clk_gating(struct ufs_hba *hba)
@@ -1089,7 +1080,7 @@ static void ufs_mtk_init_mcq_irq(struct ufs_hba *hba)
 		}
 		host->mcq_intr_info[i].hba = hba;
 		host->mcq_intr_info[i].irq = irq;
-		dev_info(hba->dev, "get platform mcq irq: %d, %d\n", i, irq);
+		dev_dbg(hba->dev, "get platform mcq irq: %d, %d\n", i, irq);
 	}
 
 	return;
@@ -1397,10 +1388,9 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
 		ret = ufshcd_uic_change_pwr_mode(hba,
 					FASTAUTO_MODE << 4 | FASTAUTO_MODE);
 
-		if (ret) {
-			dev_err(hba->dev, "%s: HSG1B FASTAUTO failed ret=%d\n",
-				__func__, ret);
-		}
+		if (ret)
+			dev_err(hba->dev, "%s: HSG1B FASTAUTO failed: %pe\n",
+				__func__, ERR_PTR(ret));
 	}
 
 	/* if already configured to the requested pwr_mode, skip adapt */
@@ -1450,7 +1440,7 @@ static int ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
 
 out:
 	if (ret) {
-		dev_warn(hba->dev, "exit h8 state fail, ret=%d\n", ret);
+		dev_err(hba->dev, "Failed to exit h8 state: %pe\n", ERR_PTR(ret));
 
 		ufshcd_force_error_recovery(hba);
 
@@ -1646,12 +1636,12 @@ static int ufs_mtk_link_set_hpm(struct ufs_hba *hba)
 	/* Check link state to make sure exit h8 success */
 	err = ufs_mtk_wait_idle_state(hba, 5);
 	if (err) {
-		dev_warn(hba->dev, "wait idle fail, err=%d\n", err);
+		dev_err(hba->dev, "Failed to wait for idle: %pe\n", ERR_PTR(err));
 		return err;
 	}
 	err = ufs_mtk_wait_link_state(hba, VS_LINK_UP, 100);
 	if (err) {
-		dev_warn(hba->dev, "exit h8 state fail, err=%d\n", err);
+		dev_err(hba->dev, "Failed to wait for link to be up: %pe\n", ERR_PTR(err));
 		return err;
 	}
 	ufshcd_set_link_active(hba);
@@ -1955,20 +1945,19 @@ static void ufs_mtk_event_notify(struct ufs_hba *hba,
 
 	/* Print details of UIC Errors */
 	if (evt <= UFS_EVT_DME_ERR) {
-		dev_info(hba->dev,
-			 "Host UIC Error Code (%s): %08x\n",
-			 ufs_uic_err_str[evt], val);
+		dev_err(hba->dev, "Host UIC Error Code (%s): %08x\n",
+			ufs_uic_err_str[evt], val);
 		reg = val;
 	}
 
 	if (evt == UFS_EVT_PA_ERR) {
 		for_each_set_bit(bit, &reg, ARRAY_SIZE(ufs_uic_pa_err_str))
-			dev_info(hba->dev, "%s\n", ufs_uic_pa_err_str[bit]);
+			dev_err(hba->dev, "%s\n", ufs_uic_pa_err_str[bit]);
 	}
 
 	if (evt == UFS_EVT_DL_ERR) {
 		for_each_set_bit(bit, &reg, ARRAY_SIZE(ufs_uic_dl_err_str))
-			dev_info(hba->dev, "%s\n", ufs_uic_dl_err_str[bit]);
+			dev_err(hba->dev, "%s\n", ufs_uic_dl_err_str[bit]);
 	}
 }
 
@@ -2183,7 +2172,7 @@ static int ufs_mtk_mcq_config_resource(struct ufs_hba *hba)
 
 	/* fail mcq initialization if interrupt is not filled properly */
 	if (!host->mcq_nr_intr) {
-		dev_info(hba->dev, "IRQs not ready. MCQ disabled.");
+		dev_err(hba->dev, "IRQs not ready. MCQ disabled.");
 		return -EINVAL;
 	}
 

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 18/24] scsi: ufs: mediatek: Rework ufs_mtk_wait_idle_state
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (16 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 17/24] scsi: ufs: mediatek: Clean up logging prints Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 19/24] scsi: ufs: mediatek: Don't acquire dvfsrc-vcore twice Louis-Alexis Eyraud
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

While ufs_mtk_wait_idle state has some code smells for me (the
VS_HCE_BASE early exit seems racey at best), it can still benefit from
some general cleanup to make the code flow less convoluted.

Use the iopoll helpers, for one, and specifically the one that sleeps
and does not busy delay, as it's being done for up to 5ms.

The register read is split out to a helper function that branches
between new and old style flow.

Every called uses the same 5ms timeout value, so there is no point in
making this a parameter. Just assume a 5ms timeout in the function.

Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 71 +++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 41 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index a84bffe069eb..c71a4034127e 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -383,51 +384,39 @@ static void ufs_mtk_dbg_sel(struct ufs_hba *hba)
 	}
 }
 
-static int ufs_mtk_wait_idle_state(struct ufs_hba *hba,
-			    unsigned long retry_ms)
+static u32 ufs_mtk_read_state(struct ufs_hba *hba, bool old_style)
 {
-	u64 timeout, time_checked;
-	u32 val, sm;
-	bool wait_idle;
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-
-	/* cannot use plain ktime_get() in suspend */
-	timeout = ktime_get_mono_fast_ns() + retry_ms * 1000000UL;
-
-	/* wait a specific time after check base */
-	udelay(10);
-	wait_idle = false;
+	u32 val;
 
-	do {
-		time_checked = ktime_get_mono_fast_ns();
-		if (host->legacy_ip_ver || host->ip_ver < IP_VER_MT6899) {
-			ufs_mtk_dbg_sel(hba);
-			val = ufshcd_readl(hba, REG_UFS_PROBE);
-		} else {
-			val = ufshcd_readl(hba, REG_UFS_UFS_MMIO_OTSD_CTRL);
-			val = val >> 16;
-		}
+	if (old_style) {
+		ufs_mtk_dbg_sel(hba);
+		val = ufshcd_readl(hba, REG_UFS_PROBE);
+	} else {
+		val = ufshcd_readl(hba, REG_UFS_UFS_MMIO_OTSD_CTRL) >> 16;
+	}
 
-		sm = val & 0x1f;
+	return FIELD_GET(0x1f, val);
+}
 
-		/*
-		 * if state is in H8 enter and H8 enter confirm
-		 * wait until return to idle state.
-		 */
-		if ((sm >= VS_HIB_ENTER) && (sm <= VS_HIB_EXIT)) {
-			wait_idle = true;
-			udelay(50);
-			continue;
-		} else if (!wait_idle)
-			break;
+static int ufs_mtk_wait_idle_state(struct ufs_hba *hba)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+	bool old_style = (host->legacy_ip_ver || host->ip_ver < IP_VER_MT6899);
+	u32 val;
+	int ret;
 
-		if (wait_idle && (sm == VS_HCE_BASE))
-			break;
-	} while (time_checked < timeout);
+	/* If the device isn't in a hibernate state after 10us, don't wait. */
+	udelay(10);
+	val = ufs_mtk_read_state(hba, old_style);
+	if (val < VS_HIB_ENTER || val > VS_HIB_EXIT)
+		return 0;
 
-	if (wait_idle && sm != VS_HCE_BASE) {
-		dev_info(hba->dev, "wait idle tmo: 0x%x\n", val);
-		return -ETIMEDOUT;
+	/* Poll to wait for idle */
+	ret = read_poll_timeout(ufs_mtk_read_state, val, (val == VS_HCE_BASE),
+				50, 5 * USEC_PER_MSEC, false, hba, old_style);
+	if (ret) {
+		dev_err(hba->dev, "Timed out waiting for idle state, val = 0x%x\n", val);
+		return ret;
 	}
 
 	return 0;
@@ -1432,7 +1421,7 @@ static int ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
 	ufshcd_writel(hba, 0, REG_AUTO_HIBERNATE_IDLE_TIMER);
 
 	/* wait host return to idle state when auto-hibern8 off */
-	ret = ufs_mtk_wait_idle_state(hba, 5);
+	ret = ufs_mtk_wait_idle_state(hba);
 	if (ret)
 		goto out;
 
@@ -1634,7 +1623,7 @@ static int ufs_mtk_link_set_hpm(struct ufs_hba *hba)
 		return err;
 
 	/* Check link state to make sure exit h8 success */
-	err = ufs_mtk_wait_idle_state(hba, 5);
+	err = ufs_mtk_wait_idle_state(hba);
 	if (err) {
 		dev_err(hba->dev, "Failed to wait for idle: %pe\n", ERR_PTR(err));
 		return err;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 19/24] scsi: ufs: mediatek: Don't acquire dvfsrc-vcore twice
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (17 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 18/24] scsi: ufs: mediatek: Rework ufs_mtk_wait_idle_state Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 20/24] scsi: ufs: mediatek: Rework hardware version reading Louis-Alexis Eyraud
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

As part of its featureset, the ufs-mediatek driver needs to play with an
optional dvfsrc-vcore regulator for some of them.

However, it currently does this by acquiring two different references to
it in two different places, needlessly duplicating logic.

Move reg_vcore to the host struct, acquire it in the same function as
avdd09 is acquired, and rework the users of reg_vcore.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 60 +++++++++++++++++++----------------------
 drivers/ufs/host/ufs-mediatek.h |  3 +--
 2 files changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index c71a4034127e..4e916d5ac2af 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -546,7 +546,6 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	struct ufs_mtk_crypt_cfg *cfg;
-	struct regulator *reg;
 	int volt, ret;
 
 	if (!ufs_mtk_is_boost_crypt_enabled(hba))
@@ -554,7 +553,6 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 
 	cfg = host->crypt;
 	volt = cfg->vcore_volt;
-	reg = cfg->reg_vcore;
 
 	ret = clk_prepare_enable(cfg->clk_crypt_mux);
 	if (ret) {
@@ -564,7 +562,7 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 	}
 
 	if (boost) {
-		ret = regulator_set_voltage(reg, volt, INT_MAX);
+		ret = regulator_set_voltage(host->reg_vcore, volt, INT_MAX);
 		if (ret) {
 			dev_err(hba->dev, "%s: Failed to set vcore to %d: %pe\n",
 				__func__, volt, ERR_PTR(ret));
@@ -575,7 +573,7 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 		if (ret) {
 			dev_err(hba->dev, "%s: Failed to reparent clk_crypt_perf: %pe\n",
 				__func__, ERR_PTR(ret));
-			regulator_set_voltage(reg, 0, INT_MAX);
+			regulator_set_voltage(host->reg_vcore, 0, INT_MAX);
 			goto out;
 		}
 	} else {
@@ -586,7 +584,7 @@ static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
 			goto out;
 		}
 
-		ret = regulator_set_voltage(reg, 0, INT_MAX);
+		ret = regulator_set_voltage(host->reg_vcore, 0, INT_MAX);
 		if (ret) {
 			dev_err(hba->dev, "%s: Failed to set vcore to minimum: %pe\n",
 				__func__, ERR_PTR(ret));
@@ -604,15 +602,12 @@ static void ufs_mtk_init_boost_crypt(struct ufs_hba *hba)
 	u32 volt;
 	int ret;
 
-	cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
-	if (!cfg)
+	if (!host->reg_vcore)
 		return;
 
-	cfg->reg_vcore = devm_regulator_get_optional(dev, "dvfsrc-vcore");
-	if (IS_ERR(cfg->reg_vcore)) {
-		dev_err(dev, "Failed to get dvfsrc-vcore: %pe\n", cfg->reg_vcore);
+	cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
 		return;
-	}
 
 	ret = of_property_read_u32(dev->of_node, "mediatek,boost-crypt-vcore-min",
 				   &volt);
@@ -918,7 +913,6 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 	struct list_head *head = &hba->clk_list_head;
 	struct ufs_clk_info *clki, *clki_tmp;
 	struct device *dev = hba->dev;
-	struct regulator *reg;
 	u32 volt;
 
 	/*
@@ -959,16 +953,8 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 		return;
 	}
 
-	/*
-	 * Default get vcore if dts have these settings.
-	 * No matter clock scaling support or not. (may disable by customer)
-	 */
-	reg = devm_regulator_get_optional(dev, "dvfsrc-vcore");
-	if (IS_ERR(reg)) {
-		if (PTR_ERR(reg) != -ENODEV)
-			dev_err(dev, "Failed to get dvfsrc-vcore: %pe\n", reg);
+	if (!host->reg_vcore)
 		return;
-	}
 
 	if (of_property_read_u32(dev->of_node, "clk-scale-up-vcore-min",
 				 &volt)) {
@@ -976,12 +962,11 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 		return;
 	}
 
-	host->mclk.reg_vcore = reg;
 	host->mclk.vcore_volt = volt;
 
 	/* If default boot is max gear, request vcore */
-	if (reg && volt && host->clk_scale_up)
-		if (regulator_set_voltage(reg, volt, INT_MAX))
+	if (volt && host->clk_scale_up)
+		if (regulator_set_voltage(host->reg_vcore, volt, INT_MAX))
 			dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
 }
 
@@ -1093,6 +1078,17 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
 	const struct ufs_mtk_soc_data *data = of_device_get_match_data(dev);
 	int ret;
 
+	host->reg_vcore = devm_regulator_get_optional(dev, "dvfsrc-vcore");
+	if (IS_ERR(host->reg_vcore)) {
+		if (PTR_ERR(host->reg_vcore) != -ENODEV) {
+			dev_err(dev, "Failed to get dvfsrc-vcore supply: %pe\n",
+				host->reg_vcore);
+			return PTR_ERR(host->reg_vcore);
+		}
+
+		host->reg_vcore = NULL;
+	}
+
 	if (!data)
 		return 0;
 
@@ -1159,6 +1155,10 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	host->hba = hba;
 	ufshcd_set_variant(hba, host);
 
+	err = ufs_mtk_get_supplies(host);
+	if (err)
+		goto out_variant_clear;
+
 	/* Initialize host capability */
 	ufs_mtk_init_host_caps(hba);
 
@@ -1213,10 +1213,6 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	ufs_mtk_init_clocks(hba);
 
-	err = ufs_mtk_get_supplies(host);
-	if (err)
-		goto out_phy_exit;
-
 	/*
 	 * ufshcd_vops_init() is invoked after
 	 * ufshcd_setup_clock(true) in ufshcd_hba_init() thus
@@ -1968,7 +1964,6 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 	struct ufs_mtk_clk *mclk = &host->mclk;
 	struct ufs_clk_info *clki = mclk->ufs_sel_clki;
 	struct ufs_clk_info *fde_clki = mclk->ufs_fde_clki;
-	struct regulator *reg;
 	int volt, ret = 0;
 	bool clk_bind_vcore = false;
 	bool clk_fde_scale = false;
@@ -1979,9 +1974,8 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 	if (!clki || !fde_clki)
 		return;
 
-	reg = host->mclk.reg_vcore;
 	volt = host->mclk.vcore_volt;
-	if (reg && volt != 0)
+	if (host->reg_vcore && volt)
 		clk_bind_vcore = true;
 
 	if (mclk->ufs_fde_max_clki && mclk->ufs_fde_min_clki)
@@ -2005,7 +1999,7 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 
 	if (scale_up) {
 		if (clk_bind_vcore) {
-			ret = regulator_set_voltage(reg, volt, INT_MAX);
+			ret = regulator_set_voltage(host->reg_vcore, volt, INT_MAX);
 			if (ret) {
 				dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
 				goto out;
@@ -2045,7 +2039,7 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 		}
 
 		if (clk_bind_vcore) {
-			ret = regulator_set_voltage(reg, 0, INT_MAX);
+			ret = regulator_set_voltage(host->reg_vcore, 0, INT_MAX);
 			if (ret) {
 				dev_err(hba->dev, "%s: Failed to set vcore to minimum: %pe\n",
 					__func__, ERR_PTR(ret));
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index d97951ee1f4e..6b81c8f76201 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -141,7 +141,6 @@ enum ufs_mtk_host_caps {
 };
 
 struct ufs_mtk_crypt_cfg {
-	struct regulator *reg_vcore;
 	struct clk *clk_crypt_perf;
 	struct clk *clk_crypt_mux;
 	struct clk *clk_crypt_lp;
@@ -155,7 +154,6 @@ struct ufs_mtk_clk {
 	struct ufs_clk_info *ufs_fde_clki; /* Mux */
 	struct ufs_clk_info *ufs_fde_max_clki; /* Max src */
 	struct ufs_clk_info *ufs_fde_min_clki; /* Min src */
-	struct regulator *reg_vcore;
 	int vcore_volt;
 };
 
@@ -175,6 +173,7 @@ struct ufs_mtk_host {
 	struct phy *mphy;
 	struct regulator *reg_avdd09;
 	struct regulator *reg_avdd09_1;
+	struct regulator *reg_vcore;
 	struct reset_control_bulk_data resets[MTK_UFS_NUM_RESETS];
 	struct ufs_hba *hba;
 	struct ufs_mtk_crypt_cfg *crypt;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 20/24] scsi: ufs: mediatek: Rework hardware version reading
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (18 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 19/24] scsi: ufs: mediatek: Don't acquire dvfsrc-vcore twice Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:24   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 21/24] scsi: ufs: mediatek: Back up idle timer in per-instance struct Louis-Alexis Eyraud
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Split assignment to the host struct out from the read function, and
utilise bitfield helpers to simplify the code. Also move the debug print
out of the legacy version helper, which means it no longer has to take a
struct ufs_hba as an input, and can be rewritten as a pure function.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 65 +++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 4e916d5ac2af..f405f511f41f 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -826,50 +826,47 @@ static void ufs_mtk_mcq_set_irq_affinity(struct ufs_hba *hba, unsigned int cpu)
 	dev_dbg(hba->dev, "set irq %d affinity to CPU %d\n", irq, _cpu);
 }
 
-static bool ufs_mtk_is_legacy_chipset(struct ufs_hba *hba, u32 hw_ip_ver)
+static bool __pure ufs_mtk_is_legacy_chipset(u32 hw_ip_ver)
 {
-	bool is_legacy = false;
-
 	switch (hw_ip_ver) {
 	case IP_LEGACY_VER_MT6893:
 	case IP_LEGACY_VER_MT6781:
 		/* can add other legacy chipset ID here accordingly */
-		is_legacy = true;
-		break;
-	default:
-		break;
+		return true;
 	}
-	dev_dbg(hba->dev, "IP version 0x%x, legacy = %s", hw_ip_ver,
-		str_true_false(is_legacy));
 
-	return is_legacy;
+	return false;
 }
 
-/*
- * HW version format has been changed from 01MMmmmm to 1MMMmmmm, since
- * project MT6878. In order to perform correct version comparison,
- * version number is changed by SW for the following projects.
- * IP_VER_MT6983	0x00360000 to 0x10360000
- * IP_VER_MT6897	0x01440000 to 0x10440000
- * IP_VER_MT6989	0x01450000 to 0x10450000
- * IP_VER_MT6991	0x01460000 to 0x10460000
+#define MTK_UFS_VER_PREFIX_M GENMASK(31, 24)
+
+/**
+ * ufs_mtk_get_hw_ip_version - read and return adjusted hardware version
+ * @hba: pointer to this device's &struct ufs_hba
+ *
+ * Reads, transforms and returns the hardware version.
+ *
+ * Since MT6878, the versioning scheme was changed from 01MMmmmm to 1MMMmmmm.
+ * In order to support version comparisons across these different versioning
+ * schemes, this function transforms the older style to the newer one.
+ *
+ * For example:
+ *  MT6983 is transformed from 0x00360000 to 0x10360000
+ *  MT6897 is transformed from 0x01440000 to 0x10440000
+ *  MT6989 is transformed from 0x01450000 to 0x10450000
+ *  MT6991 is transformed from 0x01460000 to 0x10460000
+ *
+ * Returns a u32 representing the hardware version.
  */
-static void ufs_mtk_get_hw_ip_version(struct ufs_hba *hba)
+static u32 ufs_mtk_get_hw_ip_version(struct ufs_hba *hba)
 {
-	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-	u32 hw_ip_ver;
+	u32 version = ufshcd_readl(hba, REG_UFS_MTK_IP_VER);
+	u32 prefix = FIELD_GET(MTK_UFS_VER_PREFIX_M, version);
 
-	hw_ip_ver = ufshcd_readl(hba, REG_UFS_MTK_IP_VER);
+	if (prefix <= 1)
+		FIELD_MODIFY(MTK_UFS_VER_PREFIX_M, &version, 0x10);
 
-	if (((hw_ip_ver & (0xFF << 24)) == (0x1 << 24)) ||
-	    ((hw_ip_ver & (0xFF << 24)) == 0)) {
-		hw_ip_ver &= ~(0xFF << 24);
-		hw_ip_ver |= (0x1 << 28);
-	}
-
-	host->ip_ver = hw_ip_ver;
-
-	host->legacy_ip_ver = ufs_mtk_is_legacy_chipset(hba, hw_ip_ver);
+	return version;
 }
 
 static void ufs_mtk_get_controller_version(struct ufs_hba *hba)
@@ -1232,7 +1229,11 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 
 	ufs_mtk_setup_clocks(hba, true, POST_CHANGE);
 
-	ufs_mtk_get_hw_ip_version(hba);
+	host->ip_ver = ufs_mtk_get_hw_ip_version(hba);
+	host->legacy_ip_ver = ufs_mtk_is_legacy_chipset(host->ip_ver);
+
+	dev_dbg(hba->dev, "IP version 0x%x, legacy = %s", host->ip_ver,
+		str_true_false(host->legacy_ip_ver));
 
 	return 0;
 

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 21/24] scsi: ufs: mediatek: Back up idle timer in per-instance struct
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (19 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 20/24] scsi: ufs: mediatek: Rework hardware version reading Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:33   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 22/24] scsi: ufs: mediatek: Remove ret local from link_startup_notify Louis-Alexis Eyraud
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The MediaTek UFS driver uses a function-scope static variable to back up
a hardware register across a power change in the
ufs_mtk_pwr_change_notify function. This is dangerous, as it's only
correct if only ever one instance of the driver is loaded, which isn't
true if there's more than one device on a SoC that needs it, or it
otherwise gets loaded a second time.

Back it up into a member of the host struct instead, as this struct is
per-instance. Rework the function to not use a pointless "ret" local as
well.

Fixes: f5ca8d0c7a63 ("scsi: ufs: host: mediatek: Disable auto-hibern8 during power mode changes")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 19 ++++++++-----------
 drivers/ufs/host/ufs-mediatek.h |  1 +
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index f405f511f41f..4782fdf54866 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1441,27 +1441,24 @@ static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status stage,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
-	int ret = 0;
-	static u32 reg;
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 
 	switch (stage) {
 	case PRE_CHANGE:
 		if (ufshcd_is_auto_hibern8_supported(hba)) {
-			reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
+			host->ahit = ufshcd_readl(
+				hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
 			ufs_mtk_auto_hibern8_disable(hba);
 		}
-		ret = ufs_mtk_pre_pwr_change(hba, dev_req_params);
-		break;
+		return ufs_mtk_pre_pwr_change(hba, dev_req_params);
 	case POST_CHANGE:
 		if (ufshcd_is_auto_hibern8_supported(hba))
-			ufshcd_writel(hba, reg, REG_AUTO_HIBERNATE_IDLE_TIMER);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
+			ufshcd_writel(hba, host->ahit,
+				      REG_AUTO_HIBERNATE_IDLE_TIMER);
+		return 0;
 	}
 
-	return ret;
+	return -EINVAL;
 }
 
 static int ufs_mtk_unipro_set_lpm(struct ufs_hba *hba, bool lpm)
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 6b81c8f76201..1fa14a83e8cd 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -188,6 +188,7 @@ struct ufs_mtk_host {
 	u16 ref_clk_gating_wait_us;
 	u32 ip_ver;
 	bool legacy_ip_ver;
+	u32 ahit;
 
 	bool mcq_set_intr;
 	bool is_mcq_intr_enabled;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 22/24] scsi: ufs: mediatek: Remove ret local from link_startup_notify
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (20 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 21/24] scsi: ufs: mediatek: Back up idle timer in per-instance struct Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:26   ` sashiko-bot
  2026-09-01 15:39 ` [PATCH v11 23/24] scsi: ufs: mediatek: Remove undocumented "clk-scale-up-vcore-min" Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 24/24] scsi: ufs: mediatek: Add MT8196 compatible, update copyright Louis-Alexis Eyraud
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Remove the "ret" local variable from ufs_mtk_link_startup_notify, as
it's pointless; in all cases it is assigned, it is returned right after
without being read first.

Rework the code to just return directly, and get rid of the default
branch while at it.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 4782fdf54866..bcde58e3aee8 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1543,21 +1543,15 @@ static void ufs_mtk_post_link(struct ufs_hba *hba)
 static int ufs_mtk_link_startup_notify(struct ufs_hba *hba,
 				       enum ufs_notify_change_status stage)
 {
-	int ret = 0;
-
 	switch (stage) {
 	case PRE_CHANGE:
-		ret = ufs_mtk_pre_link(hba);
-		break;
+		return ufs_mtk_pre_link(hba);
 	case POST_CHANGE:
 		ufs_mtk_post_link(hba);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
+		return 0;
 	}
 
-	return ret;
+	return -EINVAL;
 }
 
 static int ufs_mtk_device_reset(struct ufs_hba *hba)

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 23/24] scsi: ufs: mediatek: Remove undocumented "clk-scale-up-vcore-min"
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (21 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 22/24] scsi: ufs: mediatek: Remove ret local from link_startup_notify Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 15:39 ` [PATCH v11 24/24] scsi: ufs: mediatek: Add MT8196 compatible, update copyright Louis-Alexis Eyraud
  23 siblings, 0 replies; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

The MediaTek UFS driver contains support for an undocumented,
non-vendor-prefixed u32 property named "clk-scale-up-vcore-min".

Since it is not part of any binding, and would not pass a bindings
review in its current form, remove it.

To return this functionality, it needs to be resubmitted in a series
that also introduces it to the binding, and justifies what it is used
for. Compatibility with downstream device trees is not a valid
justification for its existence.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 42 +----------------------------------------
 drivers/ufs/host/ufs-mediatek.h |  1 -
 2 files changed, 1 insertion(+), 42 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index bcde58e3aee8..a894810a83de 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -909,8 +909,6 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 	struct list_head *head = &hba->clk_list_head;
 	struct ufs_clk_info *clki, *clki_tmp;
-	struct device *dev = hba->dev;
-	u32 volt;
 
 	/*
 	 * Find private clocks and store them in struct ufs_mtk_clk.
@@ -947,24 +945,7 @@ static void ufs_mtk_init_clocks(struct ufs_hba *hba)
 	if (!ufs_mtk_is_clk_scale_ready(hba)) {
 		hba->caps &= ~UFSHCD_CAP_CLK_SCALING;
 		dev_info(hba->dev, "%s: Clock scaling unavailable", __func__);
-		return;
-	}
-
-	if (!host->reg_vcore)
-		return;
-
-	if (of_property_read_u32(dev->of_node, "clk-scale-up-vcore-min",
-				 &volt)) {
-		dev_info(dev, "failed to get clk-scale-up-vcore-min");
-		return;
 	}
-
-	host->mclk.vcore_volt = volt;
-
-	/* If default boot is max gear, request vcore */
-	if (volt && host->clk_scale_up)
-		if (regulator_set_voltage(host->reg_vcore, volt, INT_MAX))
-			dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
 }
 
 static void ufs_mtk_setup_clk_gating(struct ufs_hba *hba)
@@ -1956,8 +1937,7 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 	struct ufs_mtk_clk *mclk = &host->mclk;
 	struct ufs_clk_info *clki = mclk->ufs_sel_clki;
 	struct ufs_clk_info *fde_clki = mclk->ufs_fde_clki;
-	int volt, ret = 0;
-	bool clk_bind_vcore = false;
+	int ret = 0;
 	bool clk_fde_scale = false;
 
 	if (!hba->clk_scaling.is_initialized)
@@ -1966,10 +1946,6 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 	if (!clki || !fde_clki)
 		return;
 
-	volt = host->mclk.vcore_volt;
-	if (host->reg_vcore && volt)
-		clk_bind_vcore = true;
-
 	if (mclk->ufs_fde_max_clki && mclk->ufs_fde_min_clki)
 		clk_fde_scale = true;
 
@@ -1990,14 +1966,6 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 	}
 
 	if (scale_up) {
-		if (clk_bind_vcore) {
-			ret = regulator_set_voltage(host->reg_vcore, volt, INT_MAX);
-			if (ret) {
-				dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
-				goto out;
-			}
-		}
-
 		ret = clk_set_parent(clki->clk, mclk->ufs_sel_max_clki->clk);
 		if (ret) {
 			dev_err(hba->dev, "%s: Failed to set clock mux: %pe\n",
@@ -2029,14 +1997,6 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
 				__func__, ERR_PTR(ret));
 			goto out;
 		}
-
-		if (clk_bind_vcore) {
-			ret = regulator_set_voltage(host->reg_vcore, 0, INT_MAX);
-			if (ret) {
-				dev_err(hba->dev, "%s: Failed to set vcore to minimum: %pe\n",
-					__func__, ERR_PTR(ret));
-			}
-		}
 	}
 
 out:
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 1fa14a83e8cd..4966aae5bd34 100644
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -154,7 +154,6 @@ struct ufs_mtk_clk {
 	struct ufs_clk_info *ufs_fde_clki; /* Mux */
 	struct ufs_clk_info *ufs_fde_max_clki; /* Max src */
 	struct ufs_clk_info *ufs_fde_min_clki; /* Min src */
-	int vcore_volt;
 };
 
 struct ufs_mtk_hw_ver {

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v11 24/24] scsi: ufs: mediatek: Add MT8196 compatible, update copyright
  2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
                   ` (22 preceding siblings ...)
  2026-09-01 15:39 ` [PATCH v11 23/24] scsi: ufs: mediatek: Remove undocumented "clk-scale-up-vcore-min" Louis-Alexis Eyraud
@ 2026-09-01 15:39 ` Louis-Alexis Eyraud
  2026-09-01 16:32   ` sashiko-bot
  23 siblings, 1 reply; 38+ messages in thread
From: Louis-Alexis Eyraud @ 2026-09-01 15:39 UTC (permalink / raw)
  To: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Peter Wang, Chaotian Jing,
	Alim Akhtar, Avri Altman, Bart Van Assche, Stanley Jhu,
	James E.J. Bottomley, Philipp Zabel, Liam Girdwood, Mark Brown,
	Manivannan Sadhasivam, Martin K. Petersen, Martin K. Petersen
  Cc: kernel, linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
	linux-kernel, linux-scsi, Nicolas Frattaroli, Louis-Alexis Eyraud

From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

THe MT8196's UFS controller has a new compatible. Add the necessary
struct definitions to support it.

Also update the copyrights and authors, without tabs following spaces to
avoid checkpatch errors, to list myself as having contributed to this
driver after the preceding rework patches.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
 drivers/ufs/host/ufs-mediatek.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index a894810a83de..e6a672888d04 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1,9 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2019 MediaTek Inc.
+ * Copyright (C) 2026 Collabora Ltd.
  * Authors:
- *	Stanley Chu <stanley.chu@mediatek.com>
- *	Peter Wang <peter.wang@mediatek.com>
+ *      Stanley Chu <stanley.chu@mediatek.com>
+ *      Peter Wang <peter.wang@mediatek.com>
+ *      Nicolas Frattaroli <nicolas.frattaroli@collabora.com> (Major cleanups)
  */
 
 #include <linux/arm-smccc.h>
@@ -2242,6 +2244,10 @@ static const char *const ufs_mtk_regs_avdd12_ckbuf_avdd18[] = {
 	"avdd12", "avdd12-ckbuf", "avdd18"
 };
 
+static const char *const ufs_mtk_regs_avdd12_ckbuf[] = {
+	"avdd12", "avdd12-ckbuf"
+};
+
 static const struct ufs_mtk_soc_data mt8183_data = {
 	.has_avdd09 = true,
 	.reg_names = ufs_mtk_regs_avdd12_avdd18,
@@ -2254,10 +2260,18 @@ static const struct ufs_mtk_soc_data mt8192_8195_data = {
 	.num_reg_names = ARRAY_SIZE(ufs_mtk_regs_avdd12_ckbuf_avdd18),
 };
 
+static const struct ufs_mtk_soc_data mt8196_data = {
+	.has_avdd09 = true,
+	.has_avdd09_1 = true,
+	.reg_names = ufs_mtk_regs_avdd12_ckbuf,
+	.num_reg_names = ARRAY_SIZE(ufs_mtk_regs_avdd12_ckbuf),
+};
+
 static const struct of_device_id ufs_mtk_of_match[] = {
 	{ .compatible = "mediatek,mt8183-ufshci", .data = &mt8183_data },
 	{ .compatible = "mediatek,mt8192-ufshci", .data = &mt8192_8195_data },
 	{ .compatible = "mediatek,mt8195-ufshci", .data = &mt8192_8195_data },
+	{ .compatible = "mediatek,mt8196-ufshci", .data = &mt8196_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ufs_mtk_of_match);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 06/24] scsi: ufs: mediatek: Rework resets
  2026-09-01 15:38 ` [PATCH v11 06/24] scsi: ufs: mediatek: Rework resets Louis-Alexis Eyraud
@ 2026-09-01 15:58   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 15:58 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: conor+dt, linux-scsi, robh, neil.armstrong, linux-phy, vkoul,
	olteanv, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] A spurious warning 'PHY reset failed: (null)' is logged during host reset when the optional MPHY is absent.
--

commit 37450d6f129323aed779a5a4a77bdb0dba397435
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Rework resets

This commit reworks the UFS Mediatek driver to use bulk reset APIs.
It also removes legacy MPHY reset components and transitions to optional
reset variants.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c

[ ... ]

> @@ -204,49 +210,46 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba)
>  static void ufs_mtk_host_reset(struct ufs_hba *hba)
>  {
>  	struct ufs_mtk_host *host = ufshcd_get_variant(hba);

[ ... ]

> +	ret = phy_reset(host->mphy);
>  
> -	/* restore mphy setting aftre mphy reset */
> -	if (host->mphy_reset)
> -		ufs_mtk_mphy_ctrl(UFS_MPHY_RESTORE, res);
> -}
> +	/*
> +	 * Only sleep if there is no MPHY or MPHY doesn't have a reset
> +	 * implemented (which already sleeps) or the PHY reset function failed
> +	 * somehow, just to be safe
> +	 */
> +	if (!host->mphy || ret) {
> +		usleep_range(100, 110);
> +		if (ret != -EOPNOTSUPP)
> +			dev_warn(hba->dev, "PHY reset failed: %pe\n", ERR_PTR(ret));

[Severity: Low]
Does this code inadvertently log a spurious warning when the optional MPHY is
absent?

In ufs_mtk_host_reset(), when host->mphy is NULL, phy_reset(NULL) returns 0.
The condition if (!host->mphy || ret) evaluates to true, and since 0 is not
equal to -EOPNOTSUPP, this path seems to incorrectly trigger the dev_warn() on
every reset. This will result in a confusing error message like
'PHY reset failed: (null)'.

>  	}
> +
> +	ret = reset_control_bulk_deassert(MTK_UFS_NUM_RESETS, host->resets);
> +	if (ret)
> +		dev_warn(hba->dev, "Host reset deassert failed: %pe\n", ERR_PTR(ret));
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=6

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 07/24] scsi: ufs: mediatek: Rework 0.9V regulator
  2026-09-01 15:38 ` [PATCH v11 07/24] scsi: ufs: mediatek: Rework 0.9V regulator Louis-Alexis Eyraud
@ 2026-09-01 15:59   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 15:59 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: neil.armstrong, vkoul, olteanv, conor+dt, linux-phy, devicetree,
	linux-scsi, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] State desynchronization and missing error handling in `ufs_mtk_mphy_power_on` can permanently break PHY power state.
--

commit 2b9c574603dcb6952e8a93e242a09ed30fb488bf
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Rework 0.9V regulator
    
The mediatek UFS host driver does some pretty bad stuff with regards to
the 0.9V regulator. Instead of just checking for the presence of the
regulator, it adds a cap if it's there, and then checks for the cap.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index 80c6ba3d026d2..eb7a0cc464f43 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
[ ... ]
> @@ -508,44 +510,70 @@ static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
>  static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
>  {
>  	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
>  	struct phy *mphy = host->mphy;
> -	struct arm_smccc_res res;
> -	int ret = 0;
> +	int ret;
>  
> -	if (!mphy || !(on ^ host->mphy_powered_on))
> +	if (!mphy || on == host->mphy_powered_on)
>  		return 0;
>  
>  	if (on) {
> -		if (ufs_mtk_is_va09_supported(hba)) {
> -			ret = regulator_enable(host->reg_va09);
> -			if (ret < 0)
> -				goto out;
> -			/* wait 200 us to stablize VA09 */
> -			usleep_range(200, 210);
> -			ufs_mtk_va09_pwr_ctrl(res, 1);
> -		}
> +		ret = ufs_mtk_09v_on(host);
> +		if (ret)
> +			return ret;
>  		phy_power_on(mphy);

[Severity: High]
This isn't a bug introduced by this patch, but does ignoring the return value
of phy_power_on() risk desynchronizing the power state?

If phy_power_on() fails (for example, if a clock enable fails in the
underlying implementation), this function will still return success and update
host->mphy_powered_on = true. This could cause subsequent UFS operations to
hang or trigger a synchronous external abort when accessing unclocked PHY
registers.

>  	} else {
>  		phy_power_off(mphy);
> -		if (ufs_mtk_is_va09_supported(hba)) {
> -			ufs_mtk_va09_pwr_ctrl(res, 0);
> -			ret = regulator_disable(host->reg_va09);
> -		}
> -	}
> -out:
> -	if (ret) {
> -		dev_info(hba->dev,
> -			 "failed to %s va09: %d\n",
> -			 on ? "enable" : "disable",
> -			 ret);
> -	} else {
> -		host->mphy_powered_on = on;
> +		ret = ufs_mtk_09v_off(host);
> +		if (ret)
> +			return ret;

[Severity: High]
This is a pre-existing issue, but if ufs_mtk_09v_off() fails here, the
function exits early and leaves host->mphy_powered_on incorrectly set to true.

Because phy_power_off() was already called, the PHY is physically shut down.
When attempting to power the PHY on again, the check
(on == host->mphy_powered_on) at the start of ufs_mtk_mphy_power_on() will
evaluate to true and bypass the power-on sequence entirely, leaving the PHY
permanently uninitialized.

Could we make sure host->mphy_powered_on remains consistent even on early
exits?

>  	}
>  
> -	return ret;
> +	host->mphy_powered_on = on;
> +
> +	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=7

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 08/24] scsi: ufs: mediatek: Add dual 0.9V supply support
  2026-09-01 15:38 ` [PATCH v11 08/24] scsi: ufs: mediatek: Add dual 0.9V supply support Louis-Alexis Eyraud
@ 2026-09-01 15:59   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 15:59 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: linux-scsi, conor+dt, vkoul, robh, linux-phy, devicetree,
	neil.armstrong, olteanv

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing rollback of avdd09 regulator state on avdd09-1 error paths in ufs_mtk_09v_on() and ufs_mtk_09v_off().
- [Medium] Incorrect variable passed to %pe format specifier in dev_err_probe() for avdd09-1 regulator error.
--

commit 233271811903bef688f03076564e8ae57965014c
Author: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>

scsi: ufs: mediatek: Add dual 0.9V supply support

The MT8196 SoC has an additional pin compared to the MT8183 SoC to feed
the host controller with a 0.9V supply. This patch adds management for a
second optional 0.9V regulator named "avdd09-1" in preparation for this
SoC support.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index eb7a0cc464f43..f298ea6f6ecb9 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
> @@ -515,16 +516,29 @@ static int ufs_mtk_09v_off(struct ufs_mtk_host *host)
>  	struct arm_smccc_res res;
>  	int ret;
>  
> -	if (!host->reg_avdd09)
> +	if (!host->reg_avdd09 && !host->reg_avdd09_1)
>  		return 0;
>  
>  	ufs_mtk_va09_pwr_ctrl(res, 0);
> -	ret = regulator_disable(host->reg_avdd09);
> -	if (ret) {
> -		dev_err(host->hba->dev, "Failed to disable avdd09-supply: %pe\n",
> -			ERR_PTR(ret));
> -		ufs_mtk_va09_pwr_ctrl(res, 1);
> -		return ret;
> +
> +	if (host->reg_avdd09) {
> +		ret = regulator_disable(host->reg_avdd09);
> +		if (ret) {
> +			dev_err(host->hba->dev, "Failed to disable avdd09-supply: %pe\n",
> +				ERR_PTR(ret));
> +			ufs_mtk_va09_pwr_ctrl(res, 1);
> +			return ret;
> +		}
> +	}
> +
> +	if (host->reg_avdd09_1) {
> +		ret = regulator_disable(host->reg_avdd09_1);
> +		if (ret) {
> +			dev_err(host->hba->dev, "Failed to disable avdd09-1-supply: %pe\n",
> +				ERR_PTR(ret));
> +			ufs_mtk_va09_pwr_ctrl(res, 1);
> +			return ret;
> +		}

[Severity: High]
Does this error path leave host->reg_avdd09 disabled if disabling
host->reg_avdd09_1 fails?

If the second disable fails, returning here means the power state becomes
desynchronized. Should host->reg_avdd09 be re-enabled here to match the
driver's expected state before returning the error?

>  	}
>  
>  	return 0;
> @@ -535,14 +549,25 @@ static int ufs_mtk_09v_on(struct ufs_mtk_host *host)
>  	struct arm_smccc_res res;
>  	int ret;
>  
> -	if (!host->reg_avdd09)
> +	if (!host->reg_avdd09 && !host->reg_avdd09_1)
>  		return 0;
>  
> -	ret = regulator_enable(host->reg_avdd09);
> -	if (ret) {
> -		dev_err(host->hba->dev, "Failed to enable avdd09-supply: %pe\n",
> -			ERR_PTR(ret));
> -		return ret;
> +	if (host->reg_avdd09) {
> +		ret = regulator_enable(host->reg_avdd09);
> +		if (ret) {
> +			dev_err(host->hba->dev, "Failed to enable avdd09-supply: %pe\n",
> +				ERR_PTR(ret));
> +			return ret;
> +		}
> +	}
> +
> +	if (host->reg_avdd09_1) {
> +		ret = regulator_enable(host->reg_avdd09_1);
> +		if (ret) {
> +			dev_err(host->hba->dev, "Failed to enable avdd09-1-supply: %pe\n",
> +				ERR_PTR(ret));
> +			return ret;
> +		}

[Severity: High]
Does this path leak a reference count for host->reg_avdd09?

If enabling host->reg_avdd09_1 fails after host->reg_avdd09 was successfully
enabled, the function returns immediately without disabling host->reg_avdd09.
Should host->reg_avdd09 be disabled before returning?

>  	}
>  
>  	ufs_mtk_va09_pwr_ctrl(res, 1);
> @@ -1232,20 +1257,33 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
>  	struct device *dev = host->hba->dev;
>  	const struct ufs_mtk_soc_data *data = of_device_get_match_data(dev);
>  
> -	if (!data || !data->has_avdd09)
> +	if (!data)
>  		return 0;

[ ... ]

> +	if (data->has_avdd09_1) {
> +		host->reg_avdd09_1 = devm_regulator_get_optional(dev, "avdd09-1");
> +		if (IS_ERR(host->reg_avdd09_1)) {
> +			if (PTR_ERR(host->reg_avdd09_1) != -ENODEV) {
> +				return dev_err_probe(dev,
> +						     PTR_ERR(host->reg_avdd09_1),
> +						     "Failed to get avdd09-1 regulator: %pe\n",
> +						     host->reg_avdd09);

[Severity: Medium]
Are we passing the correct variable to the %pe format specifier here?

It looks like host->reg_avdd09 is passed instead of host->reg_avdd09_1, which
would cause dev_err_probe() to print the pointer value or hash of the wrong
regulator instead of the actual error string.

> +			}
> +			host->reg_avdd09_1 = NULL;
> +		}
>  	}
>  
>  	return 0;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=8

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 02/24] dt-bindings: ufs: mediatek,ufs: Complete the binding
  2026-09-01 15:38 ` [PATCH v11 02/24] dt-bindings: ufs: mediatek,ufs: Complete the binding Louis-Alexis Eyraud
@ 2026-09-01 16:01   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:01 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: devicetree, linux-phy, olteanv, linux-scsi, neil.armstrong, robh,
	conor+dt, vkoul

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Changing clock names and constraints breaks DT validation for the existing in-tree user `mt8195.dtsi` and omits crypt clocks expected by the driver.
- [Low] Missing `#include <dt-bindings/interrupt-controller/arm-gic.h>` in the newly added device tree example.
--

commit 043addd7d18e6896e3ee286c9ea8d5a48e6e340a
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

dt-bindings: ufs: mediatek,ufs: Complete the binding

This commit updates the mediatek,ufs.yaml binding to make it more complete.
It disallows the deprecated freq-table-hz property, adds reset controls and
power supplies, modifies clock names by removing the ufs_ prefix, and
updates constraints for MT8183, MT8192, and MT8195. It also adds a second
example for MT8195.

> diff --git a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
> index 15c347f5e6604..945cb986b06b7 100644
> --- a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml
> +++ b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml

[ ... ]

> @@ -19,11 +19,25 @@ properties:
>  
>    clocks:
>      minItems: 1
> -    maxItems: 8
> +    maxItems: 10
>  
>    clock-names:
>      minItems: 1
> -    maxItems: 8
> +    items:
> +      - const: main
> +      - const: aes
> +      - const: tick
> +      - const: unipro_sysclk
> +      - const: unipro_tick
> +      - const: unipro_mp_bclk
> +      - const: tx_symbol
> +      - const: mem_sub
> +      - const: rx_symbol0
> +      - const: rx_symbol1
> +
> +  operating-points-v2: true
> +
> +  freq-table-hz: false

[Severity: Medium]
Will this change cause dtbs_check validation failures for existing in-tree
device trees?

The in-tree arch/arm64/boot/dts/mediatek/mt8195.dtsi still uses the old
clock names and the freq-table-hz property:

arch/arm64/boot/dts/mediatek/mt8195.dtsi:ufshci() {
    ...
    compatible = "mediatek,mt8195-ufshci";
    ...
    freq-table-hz = <0 0>, <0 0>, <0 0>;
    ...
}

Since this patch explicitly disallows freq-table-hz and renames the clocks
without updating the dtsi, running make dtbs_check against the unchanged
dtsi will fail.

Additionally, does this list of clock names omit the crypt clocks? The
driver actively requests the crypt_mux, crypt_lp, and crypt_perf clocks
(along with the mediatek,ufs-boost-crypt property) in
ufs_mtk_init_boost_crypt().

[ ... ]

> @@ -94,9 +148,32 @@ examples:
>              phys = <&ufsphy>;
>  
>              clocks = <&infracfg_ao CLK_INFRA_UFS>;
> -            clock-names = "ufs";
> -            freq-table-hz = <0 0>;
> +            clock-names = "main";
>  
>              vcc-supply = <&mt_pmic_vemc_ldo_reg>;
>          };
>      };
> +  - |
> +    ufshci@11270000 {
> +        compatible = "mediatek,mt8195-ufshci";
> +        reg = <0x11270000 0x2300>;
> +        interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;

[Severity: Low]
Does this new example fail to compile with dt_binding_check?

The example uses the C preprocessor macros GIC_SPI and IRQ_TYPE_LEVEL_HIGH
without including the header file that defines them. Since dt-schema parses
each example block independently, a missing
#include <dt-bindings/interrupt-controller/arm-gic.h>
will cause dtc compilation to fail during make dt_binding_check.

> +        phys = <&ufsphy>;
> +        clocks = <&infracfg_ao 63>, <&infracfg_ao 64>, <&infracfg_ao 65>,
> +                 <&infracfg_ao 54>, <&infracfg_ao 55>, <&infracfg_ao 56>,
> +                 <&infracfg_ao 90>, <&infracfg_ao 93>, <&topckgen 212>,
> +                 <&topckgen 215>;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=2

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 09/24] scsi: ufs: mediatek: Rework init function
  2026-09-01 15:38 ` [PATCH v11 09/24] scsi: ufs: mediatek: Rework init function Louis-Alexis Eyraud
@ 2026-09-01 16:08   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:08 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: vkoul, olteanv, robh, linux-phy, linux-scsi, conor+dt,
	neil.armstrong, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The return value of `ufs_mtk_mphy_power_on()` is ignored inside `ufs_mtk_init()`.
--

commit 2db99daf81ccd75c63d7195b2605aed5931e2cbe
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Rework init function

The commit cleans up ufs_mtk_init() by removing unnecessary error messages,
removing the unused of_match_device() call, and returning early on errors
instead of zero-initializing an error variable.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index f298ea6f6ecb9..c5089815696fe 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
[ ... ]
> @@ -1301,29 +1289,19 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
>   */
>  static int ufs_mtk_init(struct ufs_hba *hba)
>  {

[Severity: High]
This isn't a bug introduced by this patch, but while reviewing this
function's error handling, I noticed the return value of
ufs_mtk_mphy_power_on() is ignored further down:

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_init() {
    ...
    err = ufs_mtk_get_supplies(host);
    if (err)
        goto out_variant_clear;

    /*
     * ufshcd_vops_init() is invoked after
     * ufshcd_setup_clock(true) in ufshcd_hba_init() thus
     * phy clock setup is skipped.
     *
     * Enable phy clocks specifically here.
     */
    ufs_mtk_mphy_power_on(hba, true);

    if (ufs_mtk_is_rtff_mtcmos(hba)) {
    ...
}

Does ignoring the return value here lead to the driver operating on unpowered
hardware if the required voltage regulators fail to enable?

ufs_mtk_mphy_power_on() calls ufs_mtk_09v_on(), which can fail if
regulator_enable() fails (returning -ENOMEM or -EIO). Proceeding as if the
phy is powered on when it is not might trigger asynchronous bus errors
on arm hardware and crash the system.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=9

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 11/24] scsi: ufs: mediatek: Handle misc host voltage regulators
  2026-09-01 15:38 ` [PATCH v11 11/24] scsi: ufs: mediatek: Handle misc host voltage regulators Louis-Alexis Eyraud
@ 2026-09-01 16:11   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:11 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: conor+dt, olteanv, neil.armstrong, robh, devicetree, vkoul,
	linux-phy, linux-scsi

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Use of dev_err() instead of dev_err_probe() for a function that can return -EPROBE_DEFER.
--

commit 46d3c0154cbe65fe31d813b45eaa3cb1732757ae
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Handle misc host voltage regulators

MediaTek SoCs handled by this driver contain a per-SoC specific set of
miscellaneous supplies. Add the necessary driver code to acquire these
supplies using the regulator bulk API and keep them on during suspend.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index 6bbf53b658f2d..f61727879c3c7 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c

[ ... ]

> @@ -1217,10 +1219,20 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)
>  {
>  	struct device *dev = host->hba->dev;
>  	const struct ufs_mtk_soc_data *data = of_device_get_match_data(dev);
> +	int ret;
>  
>  	if (!data)
>  		return 0;
>  
> +	if (data->num_reg_names) {
> +		ret = devm_regulator_bulk_get_enable(dev, data->num_reg_names,
> +						     data->reg_names);
> +		if (ret) {
> +			dev_err(dev, "Failed to get misc regulators: %pe\n", ERR_PTR(ret));

[Severity: Low]
Could this spam dmesg during probe deferral?

If the regulators are not yet available when ufs_mtk_probe() calls
ufs_mtk_get_supplies(), devm_regulator_bulk_get_enable() will return
-EPROBE_DEFER. This causes dev_err() to print an error message on every probe
retry.

Would it be better to use dev_err_probe() here instead to quietly handle
-EPROBE_DEFER and avoid the log spam?

> +			return ret;
> +		}
> +	}
> +
>  	if (data->has_avdd09) {
>  		host->reg_avdd09 = devm_regulator_get_optional(dev, "avdd09");
>  		if (IS_ERR(host->reg_avdd09)) {

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=11

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 16/24] scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths
  2026-09-01 15:39 ` [PATCH v11 16/24] scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths Louis-Alexis Eyraud
@ 2026-09-01 16:16   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:16 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: devicetree, robh, olteanv, neil.armstrong, vkoul, conor+dt,
	linux-scsi, linux-phy

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] _ufs_mtk_clk_scale ignores hardware configuration failures, causing the UFS core to apply clock rates to the wrong parent.
--

commit ea79392ecd3d0415deb8de00d83deee028772b07
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths

This commit updates the error logging in _ufs_mtk_clk_scale to use
dev_err instead of dev_info. It also adds missing goto statements in
the scale-up branches to ensure proper cleanup on failure.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index 5d8c02b7a857b..43fb5dbb250b0 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c

[ ... ]

> @@ -2029,51 +2029,48 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up)
>  		if (clk_bind_vcore) {
>  			ret = regulator_set_voltage(reg, volt, INT_MAX);
>  			if (ret) {
> -				dev_info(hba->dev,
> -					"Failed to set vcore to %d\n", volt);
> +				dev_err(hba->dev, "Failed to set vcore to %d\n", volt);
>  				goto out;

[Severity: High]
This is a pre-existing issue, but by handling the error internally and 
returning void, _ufs_mtk_clk_scale() prevents error propagation.

If regulator_set_voltage() or clk_set_parent() fails here and jumps to out,
the calling function ufs_mtk_clk_scale() will incorrectly update the driver
state as if the operation succeeded:

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_clk_scale() {
    ...
    if (scale_up)
        _ufs_mtk_clk_scale(hba, true);
    ...
    host->clk_scale_up = scale_up;
    ...
    clki->curr_freq = clki->max_freq;
}

Because ufs_mtk_clk_scale_notify() unconditionally returns 0 to the UFS
core regardless of PRE_CHANGE failures, the UFS core will proceed as if the
clock scaling completed.

Will this mismatch between the physical hardware state and the driver state
cause the UFS core to apply target frequencies to the wrong clock parent,
potentially leading to controller hangs or data corruption? Should
_ufs_mtk_clk_scale() and ufs_mtk_clk_scale() be updated to return an int so
ufs_mtk_clk_scale_notify() can properly abort the scale operation?

>  			}
>  		}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=16

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 17/24] scsi: ufs: mediatek: Clean up logging prints
  2026-09-01 15:39 ` [PATCH v11 17/24] scsi: ufs: mediatek: Clean up logging prints Louis-Alexis Eyraud
@ 2026-09-01 16:18   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:18 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: robh, linux-scsi, devicetree, neil.armstrong, vkoul, conor+dt,
	linux-phy, olteanv

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Missing explicit `#include <linux/string_choices.h>` for `str_true_false()`.
--

commit 14b4b7d3f0923b03c71e3a5fddb58666e933f64a
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Clean up logging prints

This commit cleans up the logging levels in the MediaTek UFS driver to ensure
errors are logged at the error level rather than info or warning levels. It
also updates prints to use the user-friendly %pe format codes for errors.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index 43fb5dbb250b0..a84bffe069eb8 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
[ ... ]
> @@ -859,7 +855,8 @@ static bool ufs_mtk_is_legacy_chipset(struct ufs_hba *hba, u32 hw_ip_ver)
>  	default:
>  		break;
>  	}
> -	dev_info(hba->dev, "legacy IP version - 0x%x, is legacy : %d", hw_ip_ver, is_legacy);
> +	dev_dbg(hba->dev, "IP version 0x%x, legacy = %s", hw_ip_ver,
> +		str_true_false(is_legacy));

[Severity: Low]
Does this code rely on implicit header inclusions? Using str_true_false() 
in ufs_mtk_is_legacy_chipset() requires linux/string_choices.h, but it 
doesn't appear to be explicitly included in this file or added by this patch.

>  
>  	return is_legacy;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=17

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 20/24] scsi: ufs: mediatek: Rework hardware version reading
  2026-09-01 15:39 ` [PATCH v11 20/24] scsi: ufs: mediatek: Rework hardware version reading Louis-Alexis Eyraud
@ 2026-09-01 16:24   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:24 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: devicetree, vkoul, neil.armstrong, linux-phy, linux-scsi,
	conor+dt, olteanv, robh

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Ignored return values from `ufshcd_dme_get` lead to uninitialized stack variable usage.
- [High] Missing return value checks for `phy_power_on` and `ufs_mtk_mphy_power_on`.
--

commit ba11979e3018428c0d10fd5e9353229a8db31ad0
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Rework hardware version reading

Split assignment to the host struct out from the read function, and
utilise bitfield helpers to simplify the code. Also move the debug print
out of the legacy version helper, which means it no longer has to take a
struct ufs_hba as an input, and can be rewritten as a pure function.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index 4e916d5ac2af7..f405f511f41fd 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
[ ... ]
> @@ -1232,7 +1229,11 @@ static int ufs_mtk_init(struct ufs_hba *hba)
>  
>  	ufs_mtk_setup_clocks(hba, true, POST_CHANGE);
>  
> -	ufs_mtk_get_hw_ip_version(hba);
> +	host->ip_ver = ufs_mtk_get_hw_ip_version(hba);
> +	host->legacy_ip_ver = ufs_mtk_is_legacy_chipset(host->ip_ver);
> +
> +	dev_dbg(hba->dev, "IP version 0x%x, legacy = %s", host->ip_ver,
> +		str_true_false(host->legacy_ip_ver));
>  
>  	return 0;

[Severity: High]
This is a pre-existing issue and was not introduced by the patch under
review, but does ufs_mtk_init() ignore the return value of
ufs_mtk_mphy_power_on() when it is called earlier in this same function?

If ufs_mtk_mphy_power_on() fails (e.g. because regulators fail), probe
continues and eventually returns 0 (success). Attempting to communicate
over an unpowered PHY or accessing its registers can result in an
asynchronous bus fault, device timeout, or kernel hang.

Looking at ufs_mtk_mphy_power_on(), it also seems to ignore the error code
returned by the generic PHY power-on routine, incorrectly returning 0
(success) when phy_power_on(mphy) is called:

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_mphy_power_on() {
    ...
		ret = ufs_mtk_09v_on(host);
		if (ret)
			return ret;
		phy_power_on(mphy);
	} else {
    ...
}

[Severity: High]
This is also a pre-existing issue and was not introduced by the patch under
review, but do we use uninitialized stack variables in ufs_mtk_cfg_unipro_cg()
and ufs_mtk_post_link() if ufshcd_dme_get() fails?

In ufs_mtk_cfg_unipro_cg():

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_cfg_unipro_cg() {
    ...
		ufshcd_dme_get(hba,
			       UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp);
		tmp = tmp |
		      (1 << RX_SYMBOL_CLK_GATE_EN) |
		      (1 << SYS_CLK_GATE_EN) |
		      (1 << TX_CLK_GATE_EN);
		ufshcd_dme_set(hba,
			       UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp);
    ...
}

If ufshcd_dme_get() times out or fails due to intermittent link issues, tmp
retains stack garbage. Modifying and writing this garbage back to
VS_SAVEPOWERCONTROL can corrupt the UFS configuration, break the link, or
hang the bus.

A similar issue appears in ufs_mtk_post_link():

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_post_link() {
    ...
		ufshcd_dme_get(hba, UIC_ARG_MIB(VS_DEBUGOMC), &tmp);
		tmp |= 0x100;
		ufshcd_dme_set(hba, UIC_ARG_MIB(VS_DEBUGOMC), tmp);
    ...
}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=20

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 22/24] scsi: ufs: mediatek: Remove ret local from link_startup_notify
  2026-09-01 15:39 ` [PATCH v11 22/24] scsi: ufs: mediatek: Remove ret local from link_startup_notify Louis-Alexis Eyraud
@ 2026-09-01 16:26   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:26 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: conor+dt, vkoul, neil.armstrong, robh, linux-scsi, linux-phy,
	olteanv, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] The return value of ufshcd_dme_set() is overwritten on MT6989 platforms without being checked, losing the error state.
- [High] The return value of ufs_mtk_auto_hibern8_disable() is completely ignored in ufs_mtk_pwr_change_notify().
--

commit 8329ac726de58d3aa2453eb0ed319e7fbbfb2a6d
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Remove ret local from link_startup_notify

This commit removes the unused local ret variable from
ufs_mtk_link_startup_notify. It also refactors the function to return
directly from the switch statement.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index 4782fdf54866b..bcde58e3aee86 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
> @@ -1543,21 +1543,15 @@ static void ufs_mtk_post_link(struct ufs_hba *hba)
>  static int ufs_mtk_link_startup_notify(struct ufs_hba *hba,
>  				       enum ufs_notify_change_status stage)
>  {
> -	int ret = 0;
> -
>  	switch (stage) {
>  	case PRE_CHANGE:
> -		ret = ufs_mtk_pre_link(hba);
> -		break;
> +		return ufs_mtk_pre_link(hba);

[Severity: High]
This isn't a bug introduced by this patch, but looking at ufs_mtk_pre_link()
which is called here:

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_pre_link() {
	...
	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp);

	/* Enable the 1144 functions setting */
	if (host->ip_ver == IP_VER_MT6989) {
		ret = ufshcd_dme_get(hba, UIC_ARG_MIB(VS_DEBUGOMC), &tmp);
	...
}

Does this code unconditionally overwrite the return value of ufshcd_dme_set()
when the IP version matches MT6989 without being checked?

If ufshcd_dme_set() fails while disabling deep stall, the failure appears to
be silently ignored on these platforms.

Leaving deep stall inappropriately configured might lead to UFS bus lockups
and command timeouts.

>  	case POST_CHANGE:
>  		ufs_mtk_post_link(hba);
> -		break;
> -	default:
> -		ret = -EINVAL;
> -		break;
> +		return 0;
>  	}
>  
> -	return ret;
> +	return -EINVAL;
>  }

[ ... ]

[Severity: High]
This is also a pre-existing issue in this file, but while reviewing the notify
functions, I noticed this in ufs_mtk_pwr_change_notify():

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_pwr_change_notify() {
	...
	case PRE_CHANGE:
		if (ufshcd_is_auto_hibern8_supported(hba)) {
			host->ahit = ufshcd_readl(
				hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
			ufs_mtk_auto_hibern8_disable(hba);
		}
		return ufs_mtk_pre_pwr_change(hba, dev_req_params);
	...
}

Is the return value of ufs_mtk_auto_hibern8_disable() intentionally ignored
here?

If it fails and returns an error like -EBUSY, the code proceeds to execute
ufs_mtk_pre_pwr_change().

Executing power mode changes while the link is stuck in hibern8 and error
recovery is pending could result in hardware lockups and unresponsiveness in
the storage subsystem.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=22

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 14/24] scsi: ufs: mediatek: Use the common PHY framework
  2026-09-01 15:39 ` [PATCH v11 14/24] scsi: ufs: mediatek: Use the common PHY framework Louis-Alexis Eyraud
@ 2026-09-01 16:28   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:28 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: devicetree, olteanv, vkoul, neil.armstrong, linux-scsi, robh,
	linux-phy, conor+dt

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [High] Unhandled early return on PHY power-off failure in ufs_mtk_runtime_suspend leaves the UFS controller hardware suspended while the PM core believes it is active.
- [High] Unconditional PHY power-off in runtime suspend breaks active UFS links.
- [Medium] Regulator enable count leak in ufs_mtk_09v_on error path.

Pre-existing issues:
- [High] Ignoring the return value of phy_power_on() causes PHY framework power_count corruption.
- [High] Unbalanced PHY power off and PM runtime put due to error handling.
--

commit 1bc61edb6ca30c41119dffded499a3c42a9eb908
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Use the common PHY framework
    
The commit converts the MediaTek UFS driver to use the common PHY framework
instead of custom OF parsing for PHYs. It acquires the device's PHY during
initialization to link it to the right device.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index ae053f40aaf46..1df16ce29ea4e 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c

[ ... ]

> @@ -2488,9 +2433,8 @@ static int ufs_mtk_system_resume(struct device *dev)
>  static int ufs_mtk_runtime_suspend(struct device *dev)
>  {
>  	struct ufs_hba *hba = dev_get_drvdata(dev);
> -	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
>  	struct arm_smccc_res res;
> -	int ret = 0;
> +	int ret;
>  
>  	ret = ufshcd_runtime_suspend(dev);
>  	if (ret)
> @@ -2501,8 +2445,11 @@ static int ufs_mtk_runtime_suspend(struct device *dev)
>  	if (ufs_mtk_is_rtff_mtcmos(hba))
>  		ufs_mtk_mtcmos_ctrl(false, res);
>  
> -	if (host->phy_dev)
> -		pm_runtime_put_sync(host->phy_dev);
> +	ret = ufs_mtk_mphy_power_on(hba, false);
> +	if (ret) {

[Severity: High]
Does this unconditional power-off break active UFS links?

The UFS subsystem allows runtime PM to keep the link active depending on the
user-configured PM level (hba->rpm_lvl).

The underlying vendor suspend callback (ufs_mtk_suspend), which is called via
ufshcd_runtime_suspend() earlier in this function, explicitly checks
ufshcd_is_link_active(hba) and intentionally skips PHY power-off if the link
must remain active.

By adding an unconditional call to ufs_mtk_mphy_power_on(hba, false) here,
doesn't it override the link-state-aware logic and cut PHY power entirely,
killing the active electrical link?

[Severity: High]
This is a pre-existing issue, but does ignoring the return value of
phy_power_on() cause PHY framework power_count corruption?

Inside ufs_mtk_mphy_power_on():

	if (on) {
		ret = ufs_mtk_09v_on(host);
		if (ret)
			return ret;
		phy_power_on(mphy);
	}

If phy_power_on() fails, the PHY framework does not increment
phy->power_count and drops its PM runtime reference.

Because the return value is ignored, ufs_mtk_mphy_power_on() sets
host->mphy_powered_on = true.

Later, during suspend, it calls phy_power_off(), which decrements the zeroed
power_count (causing an underflow) and invokes phy_pm_runtime_put().

Can this cause an unbalanced PM put on the PHY device, leading to a negative
PM usage count and potential system instability?

[Severity: High]
This is a pre-existing issue, but does the error handling in
ufs_mtk_mphy_power_on() cause unbalanced PHY power off and PM runtime put?

Inside ufs_mtk_mphy_power_on():

	} else {
		phy_power_off(mphy);
		ret = ufs_mtk_09v_off(host);
		if (ret)
			return ret;
	}

	host->mphy_powered_on = on;

If ufs_mtk_09v_off() fails, it returns early and skips the assignment
host->mphy_powered_on = false.

The next time the device attempts to suspend, host->mphy_powered_on is still
true, and it executes the power-off branch again.

Doesn't this cause phy_power_off() to be called a second time for a single
power-on, double-decrementing power_count and causing an unbalanced PM runtime
put?

[Severity: Medium]
Does the error path in ufs_mtk_09v_on() leak the regulator enable count?

Inside ufs_mtk_09v_on():

	if (host->reg_avdd09_1) {
		ret = regulator_enable(host->reg_avdd09_1);
		if (ret) {
			dev_err(host->hba->dev, "Failed to enable avdd09-1-supply: %pe\n",
				ERR_PTR(ret));
			return ret;
		}
	}

If the second regulator (reg_avdd09_1) fails to enable, the function returns
the error directly without calling regulator_disable(host->reg_avdd09) to undo
the previous successful enable step.

Doesn't this leak the regulator enable count, keeping the resource active
indefinitely?

> +		dev_err(dev, "Failed to power off PHY: %pe\n", ERR_PTR(ret));
> +		return ret;

[Severity: High]
Can this unhandled early return leave the UFS controller hardware suspended
while the PM core believes it is active?

If ufs_mtk_mphy_power_on(hba, false) fails, returning the error code here
causes the PM core to abort the suspend attempt and treat the device as
remaining RPM_ACTIVE.

However, ufshcd_runtime_suspend() was already executed successfully just
before this, meaning the UFS host controller is physically suspended.

Doesn't this state mismatch mean the PM core will not issue a resume on the
next access, leading to I/O targeting powered-down hardware, which causes
register access timeouts, bus hangs, or crashes?

> +	}
>  
>  	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=14

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 24/24] scsi: ufs: mediatek: Add MT8196 compatible, update copyright
  2026-09-01 15:39 ` [PATCH v11 24/24] scsi: ufs: mediatek: Add MT8196 compatible, update copyright Louis-Alexis Eyraud
@ 2026-09-01 16:32   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:32 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: olteanv, linux-scsi, linux-phy, devicetree, robh, neil.armstrong,
	vkoul, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Inconsistent hardware state on rollback failure in ufs_mtk_09v_off() leads to regulator state mismatch and potential crash.
--

commit 532592d1862d942dd09400d688803111fc2d12cb
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Add MT8196 compatible, update copyright
    
THe MT8196's UFS controller has a new compatible. Add the necessary
struct definitions to support it.
    
Also update the copyrights and authors, without tabs following spaces to
avoid checkpatch errors, to list myself as having contributed to this
driver after the preceding rework patches.

> THe MT8196's UFS controller has a new compatible. Add the necessary

This isn't a bug, but there is a typo (THe) in the commit message.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index a894810a83de7..e6a672888d043 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c

[ ... ]

> @@ -2254,10 +2260,18 @@ static const struct ufs_mtk_soc_data mt8192_8195_data = {
>  	.num_reg_names = ARRAY_SIZE(ufs_mtk_regs_avdd12_ckbuf_avdd18),
>  };
>  
> +static const struct ufs_mtk_soc_data mt8196_data = {
> +	.has_avdd09 = true,
> +	.has_avdd09_1 = true,

[Severity: High]
This is a pre-existing issue, but this commit explicitly exposes a dormant
regulator state mismatch bug because mt8196_data is the first to set
has_avdd09_1 to true.

In ufs_mtk_09v_off(), if host->reg_avdd09 is successfully disabled but
host->reg_avdd09_1 subsequently fails to disable, the function enters an
error rollback path:

drivers/ufs/host/ufs-mediatek.c:ufs_mtk_09v_off() {
...
	if (host->reg_avdd09) {
		ret = regulator_disable(host->reg_avdd09);
...
	}

	if (host->reg_avdd09_1) {
		ret = regulator_disable(host->reg_avdd09_1);
		if (ret) {
			dev_err(host->hba->dev, "Failed to disable avdd09-1-supply: %pe\n",
				ERR_PTR(ret));
			ufs_mtk_va09_pwr_ctrl(res, 1);
			return ret;
		}
	}
...
}

It restores SMC power with ufs_mtk_va09_pwr_ctrl(res, 1) and returns an
error, but crucially misses calling regulator_enable(host->reg_avdd09) to
revert the previously disabled host->reg_avdd09 regulator.

This leaves the UFS PHY state marked as powered on, but the PHY is
physically disabled and its essential reg_avdd09 regulator is powered off.

Could subsequent accesses to the UFS controller attempt to operate on
unpowered hardware, likely causing a hardware hang or an asynchronous
external abort that crashes the system?

> +	.reg_names = ufs_mtk_regs_avdd12_ckbuf,
> +	.num_reg_names = ARRAY_SIZE(ufs_mtk_regs_avdd12_ckbuf),
> +};
> +

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=24

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v11 21/24] scsi: ufs: mediatek: Back up idle timer in per-instance struct
  2026-09-01 15:39 ` [PATCH v11 21/24] scsi: ufs: mediatek: Back up idle timer in per-instance struct Louis-Alexis Eyraud
@ 2026-09-01 16:33   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-01 16:33 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: robh, devicetree, linux-phy, vkoul, linux-scsi, neil.armstrong,
	olteanv, conor+dt

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] A failed power mode change will permanently disable the auto-hibern8 timer due to brittle backup/restore logic.
- [High] Concurrent sysfs write to `auto_hibern8` races with power mode changes, circumventing hardware constraints and losing user configuration.
--

commit dec217a616e37a6d6c6074f353ace1fc743596e2
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

scsi: ufs: mediatek: Back up idle timer in per-instance struct

The MediaTek UFS driver uses a function-scope static variable to back up
a hardware register across a power change in the
ufs_mtk_pwr_change_notify function. This is dangerous, as it's only
correct if only ever one instance of the driver is loaded, which isn't
true if there's more than one device on a SoC that needs it, or it
otherwise gets loaded a second time.

> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
> index f405f511f41fd..4782fdf54866b 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
> @@ -1441,27 +1441,24 @@ static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
>  				enum ufs_notify_change_status stage,
>  				struct ufs_pa_layer_attr *dev_req_params)
>  {
> -	int ret = 0;
> -	static u32 reg;
> +	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
>  
>  	switch (stage) {
>  	case PRE_CHANGE:
>  		if (ufshcd_is_auto_hibern8_supported(hba)) {
> -			reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
> +			host->ahit = ufshcd_readl(
> +				hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
>  			ufs_mtk_auto_hibern8_disable(hba);
>  		}

[Severity: High]
This isn't a bug introduced by this patch, but does this brittle caching logic
risk permanently disabling the auto-hibernate feature?

In ufshcd_change_power_mode(), PRE_CHANGE is called first, which reads the
hardware timer value and disables it. If the subsequent
ufshcd_dme_change_power_mode() fails (e.g., due to a UIC command timeout),
POST_CHANGE is bypassed.

This leaves the hardware timer physically disabled (0).

On the next power mode change attempt, PRE_CHANGE reads the now-disabled
value (0) and overwrites host->ahit with 0. When POST_CHANGE eventually
succeeds, it restores 0, permanently disabling the feature until a reboot.

Could we instead restore from the core driver's hba->ahit, which reliably
tracks the configured value, rather than caching the physical hardware state
here?

> -		ret = ufs_mtk_pre_pwr_change(hba, dev_req_params);
> -		break;
> +		return ufs_mtk_pre_pwr_change(hba, dev_req_params);
>  	case POST_CHANGE:
>  		if (ufshcd_is_auto_hibern8_supported(hba))
> -			ufshcd_writel(hba, reg, REG_AUTO_HIBERNATE_IDLE_TIMER);
> -		break;
> -	default:
> -		ret = -EINVAL;
> -		break;
> +			ufshcd_writel(hba, host->ahit,
> +				      REG_AUTO_HIBERNATE_IDLE_TIMER);

[Severity: High]
This is a pre-existing issue, but does blindly restoring this cached value risk
losing user configuration and violating hardware constraints during a race
with sysfs?

When ufshcd_devfreq_scale() changes power modes, it holds clk_scaling_lock and
scan_mutex, but does not acquire hba->host_sem. Concurrently, a sysfs write to
the auto_hibern8 node invokes auto_hibern8_store(), which updates the hardware
register under hba->host_sem but without holding clk_scaling_lock.

If a sysfs write occurs immediately after PRE_CHANGE disabled the
auto-hibernate timer, the timer is re-enabled during
ufshcd_dme_change_power_mode(), violating the constraint this function is
trying to enforce.

Furthermore, when POST_CHANGE executes, it overwrites the register with the
stale host->ahit value, completely undoing the user's sysfs configuration.

> +		return 0;
>  	}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260901-mt8196-ufs-v11-0-dbd007704490@collabora.com?part=21

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2026-09-01 16:33 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 15:38 [PATCH v11 00/24] MediaTek UFS Cleanup and MT8196 Enablement Louis-Alexis Eyraud
2026-09-01 15:38 ` [PATCH v11 01/24] dt-bindings: phy: Add mediatek,mt8196-ufsphy variant Louis-Alexis Eyraud
2026-09-01 15:38 ` [PATCH v11 02/24] dt-bindings: ufs: mediatek,ufs: Complete the binding Louis-Alexis Eyraud
2026-09-01 16:01   ` sashiko-bot
2026-09-01 15:38 ` [PATCH v11 03/24] dt-bindings: ufs: mediatek,ufs: Add mt8196 variant Louis-Alexis Eyraud
2026-09-01 15:38 ` [PATCH v11 04/24] scsi: ufs: mediatek: Move MTK_SIP_UFS_CONTROL to mtk_sip_svc.h Louis-Alexis Eyraud
2026-09-01 15:38 ` [PATCH v11 05/24] phy: mediatek: ufs: Add support for resets Louis-Alexis Eyraud
2026-09-01 15:38 ` [PATCH v11 06/24] scsi: ufs: mediatek: Rework resets Louis-Alexis Eyraud
2026-09-01 15:58   ` sashiko-bot
2026-09-01 15:38 ` [PATCH v11 07/24] scsi: ufs: mediatek: Rework 0.9V regulator Louis-Alexis Eyraud
2026-09-01 15:59   ` sashiko-bot
2026-09-01 15:38 ` [PATCH v11 08/24] scsi: ufs: mediatek: Add dual 0.9V supply support Louis-Alexis Eyraud
2026-09-01 15:59   ` sashiko-bot
2026-09-01 15:38 ` [PATCH v11 09/24] scsi: ufs: mediatek: Rework init function Louis-Alexis Eyraud
2026-09-01 16:08   ` sashiko-bot
2026-09-01 15:38 ` [PATCH v11 10/24] scsi: ufs: mediatek: Rework the crypt-boost stuff Louis-Alexis Eyraud
2026-09-01 15:38 ` [PATCH v11 11/24] scsi: ufs: mediatek: Handle misc host voltage regulators Louis-Alexis Eyraud
2026-09-01 16:11   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 12/24] scsi: ufs: mediatek: Remove undocumented downstream reset cruft Louis-Alexis Eyraud
2026-09-01 15:39 ` [PATCH v11 13/24] scsi: ufs: mediatek: Remove vendor kernel quirks cruft Louis-Alexis Eyraud
2026-09-01 15:39 ` [PATCH v11 14/24] scsi: ufs: mediatek: Use the common PHY framework Louis-Alexis Eyraud
2026-09-01 16:28   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 15/24] scsi: ufs: mediatek: Remove mediatek,ufs-broken-rtc property Louis-Alexis Eyraud
2026-09-01 15:39 ` [PATCH v11 16/24] scsi: ufs: mediatek: Rework _ufs_mtk_clk_scale error paths Louis-Alexis Eyraud
2026-09-01 16:16   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 17/24] scsi: ufs: mediatek: Clean up logging prints Louis-Alexis Eyraud
2026-09-01 16:18   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 18/24] scsi: ufs: mediatek: Rework ufs_mtk_wait_idle_state Louis-Alexis Eyraud
2026-09-01 15:39 ` [PATCH v11 19/24] scsi: ufs: mediatek: Don't acquire dvfsrc-vcore twice Louis-Alexis Eyraud
2026-09-01 15:39 ` [PATCH v11 20/24] scsi: ufs: mediatek: Rework hardware version reading Louis-Alexis Eyraud
2026-09-01 16:24   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 21/24] scsi: ufs: mediatek: Back up idle timer in per-instance struct Louis-Alexis Eyraud
2026-09-01 16:33   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 22/24] scsi: ufs: mediatek: Remove ret local from link_startup_notify Louis-Alexis Eyraud
2026-09-01 16:26   ` sashiko-bot
2026-09-01 15:39 ` [PATCH v11 23/24] scsi: ufs: mediatek: Remove undocumented "clk-scale-up-vcore-min" Louis-Alexis Eyraud
2026-09-01 15:39 ` [PATCH v11 24/24] scsi: ufs: mediatek: Add MT8196 compatible, update copyright Louis-Alexis Eyraud
2026-09-01 16:32   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox