[COMMON] ufs: support the multi-host for fmp
authorBoojin Kim <boojin.kim@samsung.com>
Thu, 15 Mar 2018 15:04:31 +0000 (00:04 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:11 +0000 (20:22 +0300)
Change-Id: I436f3bc3b420a4814c33f66bb0af7bc9bea66d58
Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
drivers/scsi/ufs/Kconfig
drivers/scsi/ufs/Makefile
drivers/scsi/ufs/ufs-exynos-fmp.c
drivers/scsi/ufs/ufs-exynos-fmp.h
drivers/scsi/ufs/ufs-exynos-smu.c [deleted file]
drivers/scsi/ufs/ufs-exynos-smu.h [deleted file]
drivers/scsi/ufs/ufs-exynos.c
drivers/scsi/ufs/ufs-exynos.h

index a5dd1caf2306fb346167e0c2449cd208c43a563a..ab619e61aac9f9298b521924afa99f99d401945f 100644 (file)
@@ -136,10 +136,11 @@ config SCSI_UFS_EXYNOS
          If you have a controller with this interface, say Y or M here.
 
          If unsure, say N.
+
 config SCSI_UFS_EXYNOS_FMP
        tristate "EXYNOS Flash Memory Protector for UFS Host"
-       default y
        depends on SCSI_UFS_EXYNOS && EXYNOS_FMP
+       select SCSI_UFS_EXYNOS_SMU
        ---help---
          This selects the EXYNOS UFS FMP Driver.
 
@@ -149,7 +150,6 @@ config SCSI_UFS_EXYNOS_FMP
 
 config SCSI_UFS_EXYNOS_SMU
        tristate "EXYNOS Secure Management Unit for UFS Host"
-       default y
        depends on SCSI_UFS_EXYNOS && EXYNOS_SMU
        ---help---
          This selects the EXYNOS UFS SMU Driver.
index 1b2ba71795d4d6082a4e5a690de7f2883509da37..80bc17ef1b43316400044e28aa7cea07cda90521 100644 (file)
@@ -9,5 +9,6 @@ obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
 obj-$(CONFIG_SCSI_UFS_EXYNOS) += ufs-exynos.o ufs-exynos-dbg.o
 obj-$(CONFIG_SOC_EXYNOS9810) += ufs-cal-9810.o
 obj-$(CONFIG_SOC_EXYNOS9610) += ufs-cal-9610.o
-obj-$(CONFIG_SCSI_UFS_EXYNOS_FMP) += ufs-exynos-fmp.o
-obj-$(CONFIG_SCSI_UFS_EXYNOS_SMU) += ufs-exynos-smu.o
+ifneq (,$(filter $(CONFIG_SCSI_UFS_EXYNOS_SMU) $(CONFIG_SCSI_UFS_EXYNOS_FMP),y))
+obj-y += ufs-exynos-fmp.o
+endif
index 64c55650093af90659556a8aa81ec0eac63efb9d..75aa28b334a4dd6c4819bb194639771f06aea644 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Samsung Electronics Co., Ltd.
+ * Author: Boojin Kim <boojin.kim@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <linux/of.h>
 #include <crypto/diskcipher.h>
 #include <crypto/fmp.h>
-
 #include "ufshcd.h"
 #include "ufs-exynos.h"
 
+/* smu functions */
+#if defined(CONFIG_SCSI_UFS_EXYNOS_SMU)
+static void exynos_ufs_smu_entry0_init(struct exynos_ufs *ufs)
+{
+       writel(0x0, ufs->reg_ufsp + UFSPSBEGIN0);
+       writel(0xffffffff, ufs->reg_ufsp + UFSPSEND0);
+       writel(0xff, ufs->reg_ufsp + UFSPSLUN0);
+       writel(0xf1, ufs->reg_ufsp + UFSPSCTRL0);
+}
+
+int exynos_ufs_smu_init(struct exynos_ufs *ufs)
+{
+       if (!ufs || (ufs->smu == SMU_ID_MAX)) {
+               exynos_ufs_smu_entry0_init(ufs);
+               return 0;
+       }
+
+       dev_info(ufs->dev, "%s with id:%d\n", __func__, ufs->smu);
+       return exynos_smu_init(ufs->smu, SMU_INIT);
+}
+
+int exynos_ufs_smu_resume(struct exynos_ufs *ufs)
+{
+       int fmp_id;
+
+       if (!ufs)
+               return 0;
+
+       if (ufs->smu < SMU_ID_MAX)
+               fmp_id = ufs->smu;
+       else if (ufs->fmp < SMU_ID_MAX)
+               fmp_id = ufs->fmp;
+       else {
+               exynos_ufs_smu_entry0_init(ufs);
+               return 0;
+       }
+
+       dev_info(ufs->dev, "%s with id:%d\n", __func__, fmp_id);
+       return exynos_smu_resume(fmp_id);
+}
+
+int exynos_ufs_smu_abort(struct exynos_ufs *ufs)
+{
+       if (!ufs || (ufs->smu == SMU_ID_MAX))
+               return 0;
+
+       dev_info(ufs->dev, "%s with id:%d\n", __func__, ufs->smu);
+       return exynos_smu_abort(ufs->smu, SMU_ABORT);
+}
+#endif
+/* fmp functions */
+#ifdef CONFIG_SCSI_UFS_EXYNOS_FMP
+int exynos_ufs_fmp_sec_cfg(struct exynos_ufs *ufs)
+{
+       if (!ufs || (ufs->fmp == SMU_ID_MAX))
+               return 0;
+
+       if (ufs->fmp != SMU_EMBEDDED)
+               dev_err(ufs->dev, "%s is fails id:%d\n",
+                               __func__, ufs->fmp);
+
+
+       dev_info(ufs->dev, "%s with id:%d\n", __func__, ufs->fmp);
+       return exynos_fmp_sec_config(ufs->fmp);
+}
+
+static struct bio *get_bio(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+       struct exynos_ufs *ufs;
+
+       if (!hba || !lrbp) {
+               pr_err("%s: Invalid MMC:%p data:%p\n", __func__, hba, lrbp);
+               return NULL;
+       }
+
+       ufs = dev_get_platdata(hba->dev);
+       if (ufs->fmp == SMU_ID_MAX)
+               return NULL;
+
+       if (!virt_addr_valid(lrbp->cmd)) {
+               dev_err(hba->dev, "Invalid cmd:%p\n", lrbp->cmd);
+               return NULL;
+       }
+
+       if (!virt_addr_valid(lrbp->cmd->request->bio)) {
+               if (lrbp->cmd->request->bio)
+                       dev_err(hba->dev, "Invalid bio:%p\n", lrbp->cmd->request->bio);
+               return NULL;
+       }
+       else
+               return lrbp->cmd->request->bio;
+}
+
 int exynos_ufs_fmp_cfg(struct ufs_hba *hba,
                       struct ufshcd_lrb *lrbp,
                       struct scatterlist *sg,
                       uint32_t index, int sector_offset)
 {
        struct fmp_request req;
-       struct scsi_cmnd *cmd = lrbp->cmd;
-       struct bio *bio;
        struct crypto_diskcipher *dtfm;
        sector_t iv;
+       struct bio *bio = get_bio(hba, lrbp);
 
-       if (!cmd || !virt_addr_valid(cmd)) {
-               dev_err(hba->dev, "Invalid cmd:%p\n", cmd);
-               goto no_crypto;
-       }
+       if (!bio)
+               return 0;
 
-       /* fill fmp_data_setting */
-       bio = cmd->request->bio;
        dtfm = crypto_diskcipher_get(bio);
        if (dtfm) {
-#ifdef EANBLE_DISKCIPHER_DEBUG
-               crypto_diskcipher_check(bio, sg_page(sg));
-#endif
                iv = bio->bi_iter.bi_sector + (sector_t) sector_offset;
                req.table = (void *)&lrbp->ucd_prdt_ptr[index];
                req.cmdq_enabled = 0;
@@ -47,18 +132,20 @@ int exynos_ufs_fmp_cfg(struct ufs_hba *hba,
                /* check fips flag. use fmp without diskcipher */
                if (!dtfm->algo) {
                        if (exynos_fmp_crypt((void *)dtfm, &req))
-                               goto no_crypto;
+                           pr_warn("%s: fails to test fips\n", __func__);
                        return 0;
                }
+#endif
+#ifdef FS_ENCRYPTION_DEBUG
+               crypto_diskcipher_check_fscrypt(bio, sg_page(sg));
 #endif
                if (crypto_diskcipher_set_crypt(dtfm, &req)) {
                        pr_warn("%s: fails to set crypt\n", __func__);
                        return -EINVAL;
                }
-
                return 0;
        }
-no_crypto:
+
        exynos_fmp_bypass(&lrbp->ucd_prdt_ptr[index], 0);
        return 0;
 }
@@ -72,15 +159,16 @@ int exynos_ufs_fmp_clear(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
        struct crypto_diskcipher *dtfm;
        struct fmp_crypto_info *ci;
        struct fmp_request req;
+       struct bio *bio = get_bio(hba, lrbp);
 
-       if (!lrbp->cmd)
-               goto out;
+       if (!bio)
+               return 0;
 
        sg_segments = scsi_sg_count(lrbp->cmd);
        if (!sg_segments)
-               goto out;
+               return 0;
 
-       dtfm = crypto_diskcipher_get(lrbp->cmd->request->bio);
+       dtfm = crypto_diskcipher_get(bio);
        if (dtfm) {
 #ifdef CONFIG_EXYNOS_FMP_FIPS
                /* check fips flag. use fmp without diskcipher */
@@ -90,10 +178,13 @@ int exynos_ufs_fmp_clear(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
                        scsi_for_each_sg(lrbp->cmd, sg, sg_segments, idx) {
                                req.table = (void *)&prd_table[idx];
                                ret = exynos_fmp_clear((void *)dtfm, &req);
-                               if (ret)
+                               if (ret) {
+                                       pr_warn("%s: fails to clear fips\n",
+                                               __func__);
                                        break;
+                               }
                        }
-                       goto out;
+                       return 0;
                }
 #endif
                /* clear key on descrptor */
@@ -104,13 +195,14 @@ int exynos_ufs_fmp_clear(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
                        scsi_for_each_sg(lrbp->cmd, sg, sg_segments, idx) {
                                req.table = (void *)&prd_table[idx];
                                ret = crypto_diskcipher_clear_crypt(dtfm, &req);
-                               if (ret)
+                               if (ret) {
+                                       pr_err("%s: fail to clear desc (%d)\n",
+                                               __func__, ret);
                                        break;
+                               }
                        }
                }
        }
-out:
-       if (ret)
-               pr_err("%s: Fail to clear desc (%d)\n", __func__, ret);
        return ret;
 }
+#endif
index 801562dfb2b773f4649bcb3b357d3296d481aa3b..4dabf2d08fb0435df5755b084d4652864caf61bf 100644 (file)
 #include "ufshcd.h"
 #include "ufs-exynos.h"
 
-#ifdef CONFIG_SCSI_UFS_EXYNOS_FMP
+#if defined(CONFIG_SCSI_UFS_EXYNOS_FMP)
 int exynos_ufs_fmp_cfg(struct ufs_hba *hba,
                                struct ufshcd_lrb *lrbp,
                                struct scatterlist *sg,
                                uint32_t index,
                                int sector_offset);
 int exynos_ufs_fmp_clear(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
+int exynos_ufs_fmp_sec_cfg(struct exynos_ufs *ufs);
 #else
 inline int exynos_ufs_fmp_cfg(struct ufs_hba *hba,
                                struct ufshcd_lrb *lrbp,
@@ -34,5 +35,35 @@ int exynos_ufs_fmp_clear(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 {
        return 0;
 }
+
+int exynos_ufs_fmp_sec_cfg(struct exynos_ufs *ufs)
+{
+       return 0;
+}
 #endif /* CONFIG_SCSI_UFS_EXYNOS_FMP */
+#if defined(CONFIG_SCSI_UFS_EXYNOS_SMU)
+int exynos_ufs_smu_init(struct exynos_ufs *ufs);
+int exynos_ufs_smu_resume(struct exynos_ufs *ufs);
+int exynos_ufs_smu_abort(struct exynos_ufs *ufs);
+#else
+inline int exynos_ufs_smu_init(struct exynos_ufs *ufs)
+{
+       writel(0x0, ufs->reg_ufsp + UFSPSBEGIN0);
+       writel(0xffffffff, ufs->reg_ufsp + UFSPSEND0);
+       writel(0xff, ufs->reg_ufsp + UFSPSLUN0);
+       writel(0xf1, ufs->reg_ufsp + UFSPSCTRL0);
+
+       return 0;
+}
+
+inline int exynos_ufs_smu_resume(struct exynos_ufs *ufs)
+{
+       return exynos_ufs_smu_init(ufs);
+}
+
+inline int exynos_ufs_smu_abort(struct exynos_ufs *ufs)
+{
+       return 0;
+}
+#endif
 #endif /* _UFS_EXYNOS_FMP_H_ */
diff --git a/drivers/scsi/ufs/ufs-exynos-smu.c b/drivers/scsi/ufs/ufs-exynos-smu.c
deleted file mode 100644 (file)
index 740d939..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2016 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/of.h>
-#include <crypto/smu.h>
-
-#include "ufshcd.h"
-#include "ufs-exynos.h"
-#include "ufs-exynos-smu.h"
-
-#define EXYNOS_UFS_SMU_LABEL   "ufs-exynos-smu"
-
-static struct exynos_smu_variant_ops *exynos_ufs_smu_get_vops(struct device *dev)
-{
-       struct exynos_smu_variant_ops *smu_vops = NULL;
-       struct device_node *node;
-
-       node = of_parse_phandle(dev->of_node, EXYNOS_UFS_SMU_LABEL, 0);
-       if (!node) {
-               dev_err(dev, "%s: exynos-ufs-smu property not specified\n",
-                       __func__);
-               goto err;
-       }
-
-       smu_vops = exynos_smu_get_variant_ops(node);
-       if (!smu_vops)
-               dev_err(dev, "%s: Fail to get smu_vops\n", __func__);
-
-       of_node_put(node);
-err:
-       return smu_vops;
-}
-
-static struct platform_device *exynos_ufs_smu_get_pdevice(struct device *dev)
-{
-       struct device_node *node;
-       struct platform_device *smu_pdev = NULL;
-
-       node = of_parse_phandle(dev->of_node, EXYNOS_UFS_SMU_LABEL, 0);
-       if (!node) {
-               dev_err(dev, "%s: exynos-ufs-smu property not specified\n",
-                       __func__);
-               goto err;
-       }
-
-       smu_pdev = exynos_smu_get_pdevice(node);
-err:
-       return smu_pdev;
-}
-
-int exynos_ufs_smu_get_dev(struct exynos_ufs *ufs)
-{
-       int ret;
-       struct device *dev;
-
-       if (!ufs || !ufs->dev) {
-               pr_err("%s: invalid ufs host, host->dev\n", __func__);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       dev = ufs->dev;
-       ufs->smu.vops = exynos_ufs_smu_get_vops(dev);
-       ufs->smu.pdev = exynos_ufs_smu_get_pdevice(dev);
-
-       if (ufs->smu.pdev == ERR_PTR(-EPROBE_DEFER)) {
-               dev_err(dev, "%s: SMU device not probed yet\n", __func__);
-               ret = -EPROBE_DEFER;
-               goto err;
-       }
-
-       if (!ufs->smu.pdev || !ufs->smu.vops) {
-               dev_err(dev, "%s: Host device doesn't have SMU or fail to get SMU",
-                               __func__);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       return 0;
-err:
-       ufs->smu.pdev = NULL;
-       ufs->smu.vops = NULL;
-
-       return ret;
-}
-
-int exynos_ufs_smu_init(struct exynos_ufs *ufs)
-{
-       struct smu_data_setting smu_set;
-
-       if (!ufs->smu.vops || !ufs->smu.pdev)
-               return 0;
-
-       smu_set.id = SMU_EMBEDDED;
-       smu_set.command = SMU_INIT;
-       return ufs->smu.vops->init(ufs->smu.pdev, &smu_set);
-}
-
-int exynos_ufs_smu_sec_cfg(struct exynos_ufs *ufs)
-{
-       struct smu_data_setting smu_set;
-
-       if (!ufs->smu.vops || !ufs->smu.pdev)
-               return 0;
-
-       smu_set.id = SMU_EMBEDDED;
-       smu_set.desc_type = CFG_DESCTYPE;
-
-       return ufs->smu.vops->sec_config(ufs->smu.pdev, &smu_set);
-}
-
-int exynos_ufs_smu_resume(struct exynos_ufs *ufs)
-{
-       struct smu_data_setting smu_set;
-
-       if (!ufs->smu.vops || !ufs->smu.pdev)
-               return 0;
-
-       smu_set.id = SMU_EMBEDDED;
-       return ufs->smu.vops->resume(ufs->smu.pdev, &smu_set);
-}
-
-int exynos_ufs_smu_abort(struct exynos_ufs *ufs)
-{
-       struct smu_data_setting smu_set;
-
-       if (!ufs->smu.vops || !ufs->smu.pdev)
-               return 0;
-
-       smu_set.id = SMU_EMBEDDED;
-       smu_set.command = SMU_ABORT;
-       return ufs->smu.vops->abort(ufs->smu.pdev, &smu_set);
-}
diff --git a/drivers/scsi/ufs/ufs-exynos-smu.h b/drivers/scsi/ufs/ufs-exynos-smu.h
deleted file mode 100644 (file)
index 7b4bd4b..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef _UFS_EXYNOS_SMU_H_
-#define _UFS_EXYNOS_SMU_H_
-
-#ifdef CONFIG_SCSI_UFS_EXYNOS_SMU
-int exynos_ufs_smu_get_dev(struct exynos_ufs *ufs);
-int exynos_ufs_smu_init(struct exynos_ufs *ufs);
-int exynos_ufs_smu_sec_cfg(struct exynos_ufs *ufs);
-int exynos_ufs_smu_resume(struct exynos_ufs *ufs);
-int exynos_ufs_smu_abort(struct exynos_ufs *ufs);
-#else
-inline int exynos_ufs_smu_get_dev(struct exynos_ufs *ufs)
-{
-       if (ufs) {
-               ufs->smu.pdev = NULL;
-               ufs->smu.vops = NULL;
-       }
-       return 0;
-}
-
-inline int exynos_ufs_smu_init(struct exynos_ufs *ufs)
-{
-       writel(0x0, ufs->reg_ufsp + UFSPSBEGIN0);
-       writel(0xffffffff, ufs->reg_ufsp + UFSPSEND0);
-       writel(0xff, ufs->reg_ufsp + UFSPSLUN0);
-       writel(0xf1, ufs->reg_ufsp + UFSPSCTRL0);
-
-       return 0;
-}
-
-inline int exynos_ufs_smu_sec_cfg(struct exynos_ufs *ufs)
-{
-       return 0;
-}
-
-inline int exynos_ufs_smu_resume(struct exynos_ufs *ufs)
-{
-       writel(0x0, ufs->reg_ufsp + UFSPSBEGIN0);
-       writel(0xffffffff, ufs->reg_ufsp + UFSPSEND0);
-       writel(0xff, ufs->reg_ufsp + UFSPSLUN0);
-       writel(0xf1, ufs->reg_ufsp + UFSPSCTRL0);
-
-       return 0;
-}
-
-inline int exynos_ufs_smu_abort(struct exynos_ufs *ufs)
-{
-       return 0;
-}
-
-#endif /* CONFIG_SCSI_UFS_EXYNOS_SMU */
-#endif /* _UFS_EXYNOS_SMU_H_ */
index f4b01dfecdd3006c344bd22a94e9afeff96a2ff7..b24b984c69e018403fd2abbd0e134d82726b5bb7 100644 (file)
@@ -20,7 +20,6 @@
 #include "ufshcd-pltfrm.h"
 #include "ufs-exynos.h"
 #include "ufs-exynos-fmp.h"
-#include "ufs-exynos-smu.h"
 #include <soc/samsung/exynos-fsys0-tcxo.h>
 #include <soc/samsung/exynos-cpupm.h>
 #include <linux/mfd/syscon.h>
@@ -28,9 +27,6 @@
 #include <linux/soc/samsung/exynos-soc.h>
 #include <linux/spinlock.h>
 
-
-
-
 /*
  * Unipro attribute value
  */
@@ -583,6 +579,7 @@ static int exynos_ufs_init(struct ufs_hba *hba)
 {
        struct exynos_ufs *ufs = to_exynos_ufs(hba);
        int ret;
+       int id;
 
        /* set features, such as caps or quirks */
        exynos_ufs_set_features(hba, ufs->hw_rev);
@@ -597,19 +594,21 @@ static int exynos_ufs_init(struct ufs_hba *hba)
        if (ret)
                return ret;
 
-       ret = exynos_ufs_smu_get_dev(ufs);
-       if (ret == -EPROBE_DEFER) {
-               dev_err(ufs->dev, "%s: SMU device not probed yet (%d)\n",
-                               __func__, ret);
-               return ret;
-       } else if (ret) {
-               dev_err(ufs->dev, "%s, Fail to get SMU device (%d)\n",
-                               __func__, ret);
-               return ret;
-       }
+       /* get fmp & smu id */
+       ret = of_property_read_u32(ufs->dev->of_node, "fmp-id", &id);
+       if (ret)
+               ufs->fmp = SMU_ID_MAX;
+       else
+               ufs->fmp = id;
+
+       ret = of_property_read_u32(ufs->dev->of_node, "smu-id", &id);
+       if (ret)
+               ufs->smu = SMU_ID_MAX;
+       else
+               ufs->smu = id;
 
        /* FMPSECURITY & SMU */
-       exynos_ufs_smu_sec_cfg(ufs);
+       exynos_ufs_fmp_sec_cfg(ufs);
        exynos_ufs_smu_init(ufs);
 
        /* Enable log */
@@ -952,7 +951,7 @@ static int __exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
        exynos_ufs_ctrl_auto_hci_clk(ufs, false);
 
        /* FMPSECURITY & SMU resume */
-       exynos_ufs_smu_sec_cfg(ufs);
+       exynos_ufs_fmp_sec_cfg(ufs);
        exynos_ufs_smu_resume(ufs);
 
        /* secure log */
index 800c213dfbcf35eb6f302e7017166965368a3506..abff7fd708d1aed56289d16f5db779dd2b5ec280 100644 (file)
@@ -18,6 +18,7 @@
 #else
 #include "ufs-cal-9810.h"
 #endif
+#include <crypto/smu.h>
 
 #define UFS_VER_0004   4
 #define UFS_VER_0005   5
@@ -502,16 +503,6 @@ struct exynos_ufs_debug {
        struct exynos_ufs_misc_log misc;
 };
 
-struct exynos_smu_data {
-       struct exynos_smu_variant_ops *vops;
-       struct platform_device *pdev;
-};
-
-struct exynos_fmp_data {
-       struct exynos_fmp_variant_ops *vops;
-       struct platform_device *pdev;
-};
-
 struct exynos_access_cxt {
        u32 offset;
        u32 mask;
@@ -546,7 +537,8 @@ struct exynos_ufs {
        struct uic_pwr_mode req_pmd_parm;
        struct uic_pwr_mode act_pmd_parm;
 
-       struct exynos_smu_data smu;
+       enum smu_id             fmp;
+       enum smu_id             smu;
 
        u32 rx_min_actv_time_cap;
        u32 rx_hibern8_time_cap;