aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ufs
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2021-10-18 21:42:07 +0900
committerMartin K. Petersen <martin.petersen@oracle.com>2021-10-27 23:10:11 -0400
commit91c49e7e82d739a7e14f883422e1003ee7a447d8 (patch)
tree26c67fc6d10a5d03bec926f8498f35c0057efb1d /drivers/scsi/ufs
parentscsi: ufs: ufs-exynos: Add refclkout_stop control (diff)
downloadlinux-dev-91c49e7e82d739a7e14f883422e1003ee7a447d8.tar.xz
linux-dev-91c49e7e82d739a7e14f883422e1003ee7a447d8.zip
scsi: ufs: ufs-exynos: Add setup_clocks callback
Add setup_clocks callback to control/gate clocks by ufshcd. To avoid calling before initialization, check whether UFS is on or not and call it initially from pre_link callback. Link: https://lore.kernel.org/r/20211018124216.153072-7-chanho61.park@samsung.com Cc: Alim Akhtar <alim.akhtar@samsung.com> Cc: Kiwoong Kim <kwmad.kim@samsung.com> Cc: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Signed-off-by: Chanho Park <chanho61.park@samsung.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r--drivers/scsi/ufs/ufs-exynos.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index f320b5689830..d81a2eb894ad 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -794,6 +794,27 @@ static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index)
}
}
+static int exynos_ufs_setup_clocks(struct ufs_hba *hba, bool on,
+ enum ufs_notify_change_status status)
+{
+ struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+ if (!ufs)
+ return 0;
+
+ if (on && status == PRE_CHANGE) {
+ if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
+ exynos_ufs_disable_auto_ctrl_hcc(ufs);
+ exynos_ufs_ungate_clks(ufs);
+ } else if (!on && status == POST_CHANGE) {
+ exynos_ufs_gate_clks(ufs);
+ if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
+ exynos_ufs_enable_auto_ctrl_hcc(ufs);
+ }
+
+ return 0;
+}
+
static int exynos_ufs_pre_link(struct ufs_hba *hba)
{
struct exynos_ufs *ufs = ufshcd_get_variant(hba);
@@ -812,6 +833,8 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba)
exynos_ufs_config_phy_time_attr(ufs);
exynos_ufs_config_phy_cap_attr(ufs);
+ exynos_ufs_setup_clocks(hba, true, PRE_CHANGE);
+
if (ufs->drv_data->pre_link)
ufs->drv_data->pre_link(ufs);
@@ -1202,6 +1225,7 @@ static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
.hce_enable_notify = exynos_ufs_hce_enable_notify,
.link_startup_notify = exynos_ufs_link_startup_notify,
.pwr_change_notify = exynos_ufs_pwr_change_notify,
+ .setup_clocks = exynos_ufs_setup_clocks,
.setup_xfer_req = exynos_ufs_specify_nexus_t_xfer_req,
.setup_task_mgmt = exynos_ufs_specify_nexus_t_tm_req,
.hibern8_notify = exynos_ufs_hibern8_notify,