[PATCH v4 20/25] scsi: ufs: mediatek: Don't acquire dvfsrc-vcore twice

Nicolas Frattaroli
2025-12-18T12:58:01Z

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.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/ufs/host/ufs-mediatek.c | 73 +++++++++++++++++++----------------------
drivers/ufs/host/ufs-mediatek.h | 3 +-
2 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index b07776f45acb..a54c3aeb7bab 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -519,15 +519,13 @@ 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))
+ if (!ufs_mtk_is_boost_crypt_enabled(hba) || !host->reg_vcore)
return;

cfg = host->crypt;
volt = cfg->vcore_volt;
- reg = cfg->reg_vcore;

ret = clk_prepare_enable(cfg->clk_crypt_mux);
if (ret) {
@@ -537,7 +535,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));
@@ -548,7 +546,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 {
@@ -559,7 +557,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));
@@ -576,16 +574,13 @@ static int ufs_mtk_init_boost_crypt(struct ufs_hba *hba)
struct device *dev = hba->dev;
int ret;

+ if (!host->reg_vcore)
+ return 0;
+
cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
if (!cfg)
return -ENOMEM;

- 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", cfg->reg_vcore);
- return PTR_ERR(cfg->reg_vcore);
- }
-
ret = of_property_read_u32(dev->of_node, "mediatek,boost-crypt-vcore-min",
&cfg->vcore_volt);
if (ret) {
@@ -891,7 +886,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;

/*
@@ -932,16 +926,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, "mediatek,clk-scale-up-vcore-min",
&volt)) {
@@ -949,12 +935,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);
}

@@ -1066,6 +1051,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;

@@ -1099,14 +1095,13 @@ static int ufs_mtk_get_supplies(struct ufs_mtk_host *host)

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;
+ if (PTR_ERR(host->reg_avdd09) != -ENODEV) {
+ dev_err(dev, "Failed to get avdd09 regulator: %pe\n",
+ host->reg_avdd09);
+ return PTR_ERR(host->reg_avdd09);
}

- dev_err(dev, "Failed to get avdd09 regulator: %pe\n",
- host->reg_avdd09);
- return PTR_ERR(host->reg_avdd09);
+ host->reg_avdd09 = NULL;
}

return 0;
@@ -1137,6 +1132,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);

@@ -1191,10 +1190,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
@@ -1940,7 +1935,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;
@@ -1951,9 +1945,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)
@@ -1977,7 +1970,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;
@@ -2017,7 +2010,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 5f096ed3f850..9586fe9c0441 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;
};

@@ -174,6 +172,7 @@ struct ufs_mtk_mcq_intr_info {
struct ufs_mtk_host {
struct phy *mphy;
struct regulator *reg_avdd09;
+ struct regulator *reg_vcore;
struct regulator_bulk_data *reg_misc;
u8 num_reg_misc;
struct reset_control_bulk_data resets[MTK_UFS_NUM_RESETS];