Re: [PATCH v4 10/25] scsi: ufs: mediatek: Handle misc host voltage regulators

Chaotian Jing (井朝天)
2025-12-24T05:35:07Z

On Thu, 2025-12-18 at 13:55 +0100, Nicolas Frattaroli wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> 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, and disable/enable them during suspend/resume.
>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
> drivers/ufs/host/ufs-mediatek.c | 61
> ++++++++++++++++++++++++++++++++++++++---
> drivers/ufs/host/ufs-mediatek.h | 2 ++
> 2 files changed, 59 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-
> mediatek.c
> index 9c0ac72d6e43..10d6b69e91a5 100644
> --- a/drivers/ufs/host/ufs-mediatek.c
> +++ b/drivers/ufs/host/ufs-mediatek.c
> @@ -40,6 +40,8 @@ static void _ufs_mtk_clk_scale(struct ufs_hba *hba,
> bool scale_up);
>
> struct ufs_mtk_soc_data {
> bool has_avdd09;
> + u8 num_reg_names;
> + const char *const *reg_names;
> };
>
> static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
> @@ -1190,8 +1192,37 @@ 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 || !data->has_avdd09)
> + if (!data)
> + return 0;
> +
> + if (data->num_reg_names) {
> + host->reg_misc = devm_kcalloc(dev, data-
> >num_reg_names,
> + sizeof(*host-
> >reg_misc), GFP_KERNEL);
> + if (!host->reg_misc)
> + return -ENOMEM;
> +
> + regulator_bulk_set_supply_names(host->reg_misc, data-
> >reg_names,
> + data->num_reg_names);
> +
> + ret = devm_regulator_bulk_get(dev, data-
> >num_reg_names, host->reg_misc);
> + if (ret) {
> + dev_err(dev, "Failed to get misc regulators:
> %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + host->num_reg_misc = data->num_reg_names;
> +
> + ret = regulator_bulk_enable(host->num_reg_misc, host-
> >reg_misc);
> + if (ret) {
> + dev_err(dev, "Failed to turn on misc
> regulators: %pe\n",
> + ERR_PTR(ret));
> + return ret;
> + }
> + }
> +
> + if (!data->has_avdd09)
> return 0;
>
> host->reg_avdd09 = devm_regulator_get_optional(dev,
> "avdd09");
> @@ -1833,7 +1864,9 @@ static int ufs_mtk_suspend(struct ufs_hba *hba,
> enum ufs_pm_op pm_op,
> _ufs_mtk_clk_scale(hba, false);
> }
>
> - return 0;
> + err = regulator_bulk_disable(host->num_reg_misc, host-
> >reg_misc);
> +
> + return err;
> fail:
> /*
> * Set link as off state enforcedly to trigger
> @@ -1850,6 +1883,10 @@ static int ufs_mtk_resume(struct ufs_hba *hba,
> enum ufs_pm_op pm_op)
> struct arm_smccc_res res;
> struct ufs_mtk_host *host = ufshcd_get_variant(hba);
>
> + err = regulator_bulk_enable(host->num_reg_misc, host-
> >reg_misc);
> + if (err)
> + return err;
> +
> if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)
> ufs_mtk_dev_vreg_set_lpm(hba, false);
>
> @@ -2333,14 +2370,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),
> };
These analog power cannot be powered off, even in suspend stage!
>
> 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);
> diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-
> mediatek.h
> index 24c8941f6b86..cb32fc987864 100644
> --- a/drivers/ufs/host/ufs-mediatek.h
> +++ b/drivers/ufs/host/ufs-mediatek.h
> @@ -176,6 +176,8 @@ struct ufs_mtk_mcq_intr_info {
> struct ufs_mtk_host {
> struct phy *mphy;
> struct regulator *reg_avdd09;
> + struct regulator_bulk_data *reg_misc;
> + u8 num_reg_misc;
> struct reset_control_bulk_data resets[MTK_UFS_NUM_RESETS];
> struct ufs_hba *hba;
> struct ufs_mtk_crypt_cfg *crypt;
>
> --
> 2.52.0
>