linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] scsi: ufs: wb: Add sysfs and cleanup
       [not found] <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p4>
@ 2022-07-01  7:44 ` Jinyoung CHOI
       [not found]   ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p5>
       [not found]   ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p8>
  0 siblings, 2 replies; 8+ messages in thread
From: Jinyoung CHOI @ 2022-07-01  7:44 UTC (permalink / raw)
  To: ALIM AKHTAR, avri.altman, bvanassche, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

This patch series is to clean up UFS's Write Booster code and adds sysfs
which can control the specific feature of it.

V2:
	- modify commit message
	- move & modify err messages
	- remove unnesscessary debug messages
V3:
	- split patch (functional, non-functional)

Jinyoung Choi (2):
  scsi: ufs: wb: renaming & cleanups functions
  scsi: ufs: wb: Add Manual Flush sysfs

 drivers/ufs/core/ufs-sysfs.c | 46 +++++++++++++++++++++++-
 drivers/ufs/core/ufshcd.c    | 69 +++++++++++++++++-------------------
 include/ufs/ufshcd.h         |  7 ++++
 3 files changed, 84 insertions(+), 38 deletions(-)

-- 
2.25.1

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

* [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions
       [not found]   ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p5>
@ 2022-07-01  7:46     ` Jinyoung CHOI
  2022-07-03 13:00       ` Avri Altman
                         ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Jinyoung CHOI @ 2022-07-01  7:46 UTC (permalink / raw)
  To: ALIM AKHTAR, avri.altman, bvanassche, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

The Function names were changed clearly, and the location of the
comments was modified and added properly.

In addition, the conditional test of the toggle functions was
different, so it was modified.

Unnecessary logs were removed and modified appropriately.

Signed-off-by: Jinyoung Choi <j-young.choi@samsung.com>
---
 drivers/ufs/core/ufs-sysfs.c |  2 +-
 drivers/ufs/core/ufshcd.c    | 69 +++++++++++++++++-------------------
 include/ufs/ufshcd.h         |  7 ++++
 3 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
index 0a088b47d557..6253606b93b4 100644
--- a/drivers/ufs/core/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -230,7 +230,7 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
 		 * If the platform supports UFSHCD_CAP_CLK_SCALING, turn WB
 		 * on/off will be done while clock scaling up/down.
 		 */
-		dev_warn(dev, "To control WB through wb_on is not allowed!\n");
+		dev_warn(dev, "It is not allowed to control WB!\n");
 		return -EOPNOTSUPP;
 	}
 
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 1d3214e6b364..f98d023e44ae 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -268,8 +268,7 @@ static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on);
 static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
 					 struct ufs_vreg *vreg);
 static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag);
-static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set);
-static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable);
+static void ufshcd_wb_toggle_buf_flush_during_h8(struct ufs_hba *hba, bool set);
 static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba);
 static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba);
 
@@ -289,16 +288,16 @@ static inline void ufshcd_disable_irq(struct ufs_hba *hba)
 	}
 }
 
-static inline void ufshcd_wb_config(struct ufs_hba *hba)
+static void ufshcd_wb_set_default_flags(struct ufs_hba *hba)
 {
 	if (!ufshcd_is_wb_allowed(hba))
 		return;
 
 	ufshcd_wb_toggle(hba, true);
+	ufshcd_wb_toggle_buf_flush_during_h8(hba, true);
 
-	ufshcd_wb_toggle_flush_during_h8(hba, true);
-	if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL))
-		ufshcd_wb_toggle_flush(hba, true);
+	if (ufshcd_is_wb_buf_flush_allowed(hba))
+		ufshcd_wb_toggle_buf_flush(hba, true);
 }
 
 static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba)
@@ -1289,9 +1288,10 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
 		}
 	}
 
-	/* Enable Write Booster if we have scaled up else disable it */
 	downgrade_write(&hba->clk_scaling_lock);
 	is_writelock = false;
+
+	/* Enable Write Booster if we have scaled up else disable it */
 	ufshcd_wb_toggle(hba, scale_up);
 
 out_unprepare:
@@ -5715,6 +5715,9 @@ static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn)
 	enum query_opcode opcode = set ? UPIU_QUERY_OPCODE_SET_FLAG :
 				   UPIU_QUERY_OPCODE_CLEAR_FLAG;
 
+	if (!ufshcd_is_wb_allowed(hba))
+		return -EPERM;
+
 	index = ufshcd_wb_get_query_index(hba);
 	return ufshcd_query_flag_retry(hba, opcode, idn, index, NULL);
 }
@@ -5723,60 +5726,50 @@ int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable)
 {
 	int ret;
 
-	if (!ufshcd_is_wb_allowed(hba))
-		return 0;
-
-	if (!(enable ^ hba->dev_info.wb_enabled))
+	if (hba->dev_info.wb_enabled == enable)
 		return 0;
 
 	ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_EN);
 	if (ret) {
-		dev_err(hba->dev, "%s Write Booster %s failed %d\n",
+		dev_err(hba->dev, "%s: failed to %s WB %d\n",
 			__func__, enable ? "enable" : "disable", ret);
 		return ret;
 	}
 
 	hba->dev_info.wb_enabled = enable;
-	dev_info(hba->dev, "%s Write Booster %s\n",
-			__func__, enable ? "enabled" : "disabled");
 
 	return ret;
 }
 
-static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set)
+static void ufshcd_wb_toggle_buf_flush_during_h8(struct ufs_hba *hba,
+						 bool enable)
 {
 	int ret;
 
-	ret = __ufshcd_wb_toggle(hba, set,
-			QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8);
-	if (ret) {
-		dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed: %d\n",
-			__func__, set ? "enable" : "disable", ret);
-		return;
-	}
-	dev_dbg(hba->dev, "%s WB-Buf Flush during H8 %s\n",
-			__func__, set ? "enabled" : "disabled");
+	ret = __ufshcd_wb_toggle(hba, enable,
+				 QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8);
+	if (ret)
+		dev_err(hba->dev, "%s: failed to %s WB buf flush during H8 %d\n",
+			__func__, enable ? "enable" : "disable", ret);
 }
 
-static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable)
+int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable)
 {
 	int ret;
 
-	if (!ufshcd_is_wb_allowed(hba) ||
-	    hba->dev_info.wb_buf_flush_enabled == enable)
-		return;
+	if (hba->dev_info.wb_buf_flush_enabled == enable)
+		return 0;
 
 	ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN);
 	if (ret) {
-		dev_err(hba->dev, "%s WB-Buf Flush %s failed %d\n", __func__,
-			enable ? "enable" : "disable", ret);
-		return;
+		dev_err(hba->dev, "%s: failed to %s WB buf flush %d\n",
+			__func__, enable ? "enable" : "disable", ret);
+		return ret;
 	}
 
 	hba->dev_info.wb_buf_flush_enabled = enable;
 
-	dev_dbg(hba->dev, "%s WB-Buf Flush %s\n",
-			__func__, enable ? "enabled" : "disabled");
+	return ret;
 }
 
 static bool ufshcd_wb_presrv_usrspc_keep_vcc_on(struct ufs_hba *hba,
@@ -5807,10 +5800,10 @@ static bool ufshcd_wb_presrv_usrspc_keep_vcc_on(struct ufs_hba *hba,
 
 static void ufshcd_wb_force_disable(struct ufs_hba *hba)
 {
-	if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL))
-		ufshcd_wb_toggle_flush(hba, false);
+	if (ufshcd_is_wb_buf_flush_allowed(hba))
+		ufshcd_wb_toggle_buf_flush(hba, false);
 
-	ufshcd_wb_toggle_flush_during_h8(hba, false);
+	ufshcd_wb_toggle_buf_flush_during_h8(hba, false);
 	ufshcd_wb_toggle(hba, false);
 	hba->caps &= ~UFSHCD_CAP_WB_EN;
 
@@ -8197,7 +8190,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
 	 */
 	ufshcd_set_active_icc_lvl(hba);
 
-	ufshcd_wb_config(hba);
+	/* Enable UFS Write Booster if supported */
+	ufshcd_wb_set_default_flags(hba);
+
 	if (hba->ee_usr_mask)
 		ufshcd_write_ee_control(hba);
 	/* Enable Auto-Hibernate if configured */
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 7fe1a926cd99..78adc556444a 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -1017,6 +1017,12 @@ static inline bool ufshcd_is_wb_allowed(struct ufs_hba *hba)
 	return hba->caps & UFSHCD_CAP_WB_EN;
 }
 
+static inline bool ufshcd_is_wb_buf_flush_allowed(struct ufs_hba *hba)
+{
+	return ufshcd_is_wb_allowed(hba) &&
+		!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL);
+}
+
 #define ufshcd_writel(hba, val, reg)	\
 	writel((val), (hba)->mmio_base + (reg))
 #define ufshcd_readl(hba, reg)	\
@@ -1211,6 +1217,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
 			     enum query_opcode desc_op);
 
 int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
+int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable);
 int ufshcd_suspend_prepare(struct device *dev);
 int __ufshcd_suspend_prepare(struct device *dev, bool rpm_ok_for_spm);
 void ufshcd_resume_complete(struct device *dev);
-- 
2.25.1

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

* [PATCH v3 2/2] scsi: ufs: wb: Add Manual Flush sysfs
       [not found]   ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p8>
@ 2022-07-01  7:48     ` Jinyoung CHOI
  2022-07-03 13:08       ` Avri Altman
  2022-07-07 22:45       ` Bart Van Assche
  0 siblings, 2 replies; 8+ messages in thread
From: Jinyoung CHOI @ 2022-07-01  7:48 UTC (permalink / raw)
  To: ALIM AKHTAR, avri.altman, bvanassche, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

There is the following quirk to bypass "WB Manual Flush" in Write Booster.

	- UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL

If this quirk is not set, there is no knob that can control "WB Manual Flush".

There are three flags that control Write Booster Feature.
	1. WB ON/OFF
	2. WB Hibern Flush ON/OFF
	3. WB Flush ON/OFF

The sysfs that controls the WB was implemented. (1)

In the case of "Hibern Flush", it is always good to turn on.
Control may not be required. (2)

Finally, "Manual flush" may be necessary because the Auto-Hibern8 is not
supported in a specific environment.
So the sysfs that controls this is necessary. (3)

Signed-off-by: Jinyoung Choi <j-young.choi@samsung.com>
---
 drivers/ufs/core/ufs-sysfs.c | 44 ++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
index 6253606b93b4..b1c51d8df9f4 100644
--- a/drivers/ufs/core/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -254,6 +254,48 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
 	return res < 0 ? res : count;
 }
 
+static ssize_t wb_buf_flush_en_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sysfs_emit(buf, "%d\n", hba->dev_info.wb_buf_flush_enabled);
+}
+
+static ssize_t wb_buf_flush_en_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	unsigned int wb_buf_flush_en;
+	ssize_t res;
+
+	if (!ufshcd_is_wb_buf_flush_allowed(hba)) {
+		dev_warn(dev, "It is not allowed to control WB buf flush!\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (kstrtouint(buf, 0, &wb_buf_flush_en))
+		return -EINVAL;
+
+	if (wb_buf_flush_en != 0 && wb_buf_flush_en != 1)
+		return -EINVAL;
+
+	down(&hba->host_sem);
+	if (!ufshcd_is_user_access_allowed(hba)) {
+		res = -EBUSY;
+		goto out;
+	}
+
+	ufshcd_rpm_get_sync(hba);
+	res = ufshcd_wb_toggle_buf_flush(hba, wb_buf_flush_en);
+	ufshcd_rpm_put_sync(hba);
+out:
+	up(&hba->host_sem);
+	return res < 0 ? res : count;
+}
+
 static DEVICE_ATTR_RW(rpm_lvl);
 static DEVICE_ATTR_RO(rpm_target_dev_state);
 static DEVICE_ATTR_RO(rpm_target_link_state);
@@ -262,6 +304,7 @@ static DEVICE_ATTR_RO(spm_target_dev_state);
 static DEVICE_ATTR_RO(spm_target_link_state);
 static DEVICE_ATTR_RW(auto_hibern8);
 static DEVICE_ATTR_RW(wb_on);
+static DEVICE_ATTR_RW(wb_buf_flush_en);
 
 static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
 	&dev_attr_rpm_lvl.attr,
@@ -272,6 +315,7 @@ static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
 	&dev_attr_spm_target_link_state.attr,
 	&dev_attr_auto_hibern8.attr,
 	&dev_attr_wb_on.attr,
+	&dev_attr_wb_buf_flush_en.attr,
 	NULL
 };
 
-- 
2.25.1

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

* RE: [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions
  2022-07-01  7:46     ` [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions Jinyoung CHOI
@ 2022-07-03 13:00       ` Avri Altman
       [not found]       ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p2>
  2022-07-07 22:28       ` Bart Van Assche
  2 siblings, 0 replies; 8+ messages in thread
From: Avri Altman @ 2022-07-03 13:00 UTC (permalink / raw)
  To: j-young.choi, ALIM AKHTAR, bvanassche, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

> The Function names were changed clearly, and the location of the comments
> was modified and added properly.
> 
> In addition, the conditional test of the toggle functions was different, so it
> was modified.
> 
> Unnecessary logs were removed and modified appropriately.
> 
> Signed-off-by: Jinyoung Choi <j-young.choi@samsung.com>
> ---
>  drivers/ufs/core/ufs-sysfs.c |  2 +-
>  drivers/ufs/core/ufshcd.c    | 69 +++++++++++++++++-------------------
>  include/ufs/ufshcd.h         |  7 ++++
>  3 files changed, 40 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index
> 0a088b47d557..6253606b93b4 100644
> --- a/drivers/ufs/core/ufs-sysfs.c
> +++ b/drivers/ufs/core/ufs-sysfs.c
> @@ -230,7 +230,7 @@ static ssize_t wb_on_store(struct device *dev, struct
> device_attribute *attr,
>                  * If the platform supports UFSHCD_CAP_CLK_SCALING, turn WB
>                  * on/off will be done while clock scaling up/down.
>                  */
> -               dev_warn(dev, "To control WB through wb_on is not allowed!\n");
> +               dev_warn(dev, "It is not allowed to control WB!\n");
>                 return -EOPNOTSUPP;
>         }
> 
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index
> 1d3214e6b364..f98d023e44ae 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -268,8 +268,7 @@ static int ufshcd_setup_vreg(struct ufs_hba *hba,
> bool on);  static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
>                                          struct ufs_vreg *vreg);  static int
> ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag); -static void
> ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set); -static
> inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable);
> +static void ufshcd_wb_toggle_buf_flush_during_h8(struct ufs_hba *hba,
> +bool set);
>  static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba);  static void
> ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba);
> 
> @@ -289,16 +288,16 @@ static inline void ufshcd_disable_irq(struct ufs_hba
> *hba)
>         }
>  }
> 
> -static inline void ufshcd_wb_config(struct ufs_hba *hba)
> +static void ufshcd_wb_set_default_flags(struct ufs_hba *hba)
>  {
>         if (!ufshcd_is_wb_allowed(hba))
>                 return;
> 
>         ufshcd_wb_toggle(hba, true);
> +       ufshcd_wb_toggle_buf_flush_during_h8(hba, true);
> 
> -       ufshcd_wb_toggle_flush_during_h8(hba, true);
> -       if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL))
> -               ufshcd_wb_toggle_flush(hba, true);
> +       if (ufshcd_is_wb_buf_flush_allowed(hba))
> +               ufshcd_wb_toggle_buf_flush(hba, true);
>  }
> 
>  static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba) @@ -1289,9
> +1288,10 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool
> scale_up)
>                 }
>         }
> 
> -       /* Enable Write Booster if we have scaled up else disable it */
>         downgrade_write(&hba->clk_scaling_lock);
>         is_writelock = false;
> +
> +       /* Enable Write Booster if we have scaled up else disable it */
>         ufshcd_wb_toggle(hba, scale_up);
> 
>  out_unprepare:
> @@ -5715,6 +5715,9 @@ static int __ufshcd_wb_toggle(struct ufs_hba *hba,
> bool set, enum flag_idn idn)
>         enum query_opcode opcode = set ? UPIU_QUERY_OPCODE_SET_FLAG :
>                                    UPIU_QUERY_OPCODE_CLEAR_FLAG;
> 
> +       if (!ufshcd_is_wb_allowed(hba))
> +               return -EPERM;
> +
>         index = ufshcd_wb_get_query_index(hba);
>         return ufshcd_query_flag_retry(hba, opcode, idn, index, NULL);  } @@ -
> 5723,60 +5726,50 @@ int ufshcd_wb_toggle(struct ufs_hba *hba, bool
> enable)  {
Nobody is checking the return value of ufshcd_wb_toggle(), maybe make it void instead?

Other than that - looks good to me.

Reviewed-by: Avri Altman <avri.altman@wdc.com>

>         int ret;
> 
> -       if (!ufshcd_is_wb_allowed(hba))
> -               return 0;
> -
> -       if (!(enable ^ hba->dev_info.wb_enabled))
> +       if (hba->dev_info.wb_enabled == enable)
>                 return 0;
> 
>         ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_EN);
>         if (ret) {
> -               dev_err(hba->dev, "%s Write Booster %s failed %d\n",
> +               dev_err(hba->dev, "%s: failed to %s WB %d\n",
>                         __func__, enable ? "enable" : "disable", ret);
>                 return ret;
>         }
> 
>         hba->dev_info.wb_enabled = enable;
> -       dev_info(hba->dev, "%s Write Booster %s\n",
> -                       __func__, enable ? "enabled" : "disabled");
> 
>         return ret;
>  }
> 
> -static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool
> set)
> +static void ufshcd_wb_toggle_buf_flush_during_h8(struct ufs_hba *hba,
> +                                                bool enable)
>  {
>         int ret;
> 
> -       ret = __ufshcd_wb_toggle(hba, set,
> -                       QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8);
> -       if (ret) {
> -               dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed: %d\n",
> -                       __func__, set ? "enable" : "disable", ret);
> -               return;
> -       }
> -       dev_dbg(hba->dev, "%s WB-Buf Flush during H8 %s\n",
> -                       __func__, set ? "enabled" : "disabled");
> +       ret = __ufshcd_wb_toggle(hba, enable,
> +                                QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8);
> +       if (ret)
> +               dev_err(hba->dev, "%s: failed to %s WB buf flush during H8 %d\n",
> +                       __func__, enable ? "enable" : "disable", ret);
>  }
> 
> -static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable)
> +int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable)
>  {
>         int ret;
> 
> -       if (!ufshcd_is_wb_allowed(hba) ||
> -           hba->dev_info.wb_buf_flush_enabled == enable)
> -               return;
> +       if (hba->dev_info.wb_buf_flush_enabled == enable)
> +               return 0;
> 
>         ret = __ufshcd_wb_toggle(hba, enable,
> QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN);
>         if (ret) {
> -               dev_err(hba->dev, "%s WB-Buf Flush %s failed %d\n", __func__,
> -                       enable ? "enable" : "disable", ret);
> -               return;
> +               dev_err(hba->dev, "%s: failed to %s WB buf flush %d\n",
> +                       __func__, enable ? "enable" : "disable", ret);
> +               return ret;
>         }
> 
>         hba->dev_info.wb_buf_flush_enabled = enable;
> 
> -       dev_dbg(hba->dev, "%s WB-Buf Flush %s\n",
> -                       __func__, enable ? "enabled" : "disabled");
> +       return ret;
>  }
> 
>  static bool ufshcd_wb_presrv_usrspc_keep_vcc_on(struct ufs_hba *hba,
> @@ -5807,10 +5800,10 @@ static bool
> ufshcd_wb_presrv_usrspc_keep_vcc_on(struct ufs_hba *hba,
> 
>  static void ufshcd_wb_force_disable(struct ufs_hba *hba)  {
> -       if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL))
> -               ufshcd_wb_toggle_flush(hba, false);
> +       if (ufshcd_is_wb_buf_flush_allowed(hba))
> +               ufshcd_wb_toggle_buf_flush(hba, false);
> 
> -       ufshcd_wb_toggle_flush_during_h8(hba, false);
> +       ufshcd_wb_toggle_buf_flush_during_h8(hba, false);
>         ufshcd_wb_toggle(hba, false);
>         hba->caps &= ~UFSHCD_CAP_WB_EN;
> 
> @@ -8197,7 +8190,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba,
> bool init_dev_params)
>          */
>         ufshcd_set_active_icc_lvl(hba);
> 
> -       ufshcd_wb_config(hba);
> +       /* Enable UFS Write Booster if supported */
> +       ufshcd_wb_set_default_flags(hba);
> +
>         if (hba->ee_usr_mask)
>                 ufshcd_write_ee_control(hba);
>         /* Enable Auto-Hibernate if configured */ diff --git
> a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index
> 7fe1a926cd99..78adc556444a 100644
> --- a/include/ufs/ufshcd.h
> +++ b/include/ufs/ufshcd.h
> @@ -1017,6 +1017,12 @@ static inline bool ufshcd_is_wb_allowed(struct
> ufs_hba *hba)
>         return hba->caps & UFSHCD_CAP_WB_EN;  }
> 
> +static inline bool ufshcd_is_wb_buf_flush_allowed(struct ufs_hba *hba)
> +{
> +       return ufshcd_is_wb_allowed(hba) &&
> +               !(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL);
> +}
> +
>  #define ufshcd_writel(hba, val, reg)   \
>         writel((val), (hba)->mmio_base + (reg))  #define ufshcd_readl(hba, reg)
> \ @@ -1211,6 +1217,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba
> *hba,
>                              enum query_opcode desc_op);
> 
>  int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
> +int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable);
>  int ufshcd_suspend_prepare(struct device *dev);  int
> __ufshcd_suspend_prepare(struct device *dev, bool rpm_ok_for_spm);
> void ufshcd_resume_complete(struct device *dev);
> --
> 2.25.1

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

* RE: [PATCH v3 2/2] scsi: ufs: wb: Add Manual Flush sysfs
  2022-07-01  7:48     ` [PATCH v3 2/2] scsi: ufs: wb: Add Manual Flush sysfs Jinyoung CHOI
@ 2022-07-03 13:08       ` Avri Altman
  2022-07-07 22:45       ` Bart Van Assche
  1 sibling, 0 replies; 8+ messages in thread
From: Avri Altman @ 2022-07-03 13:08 UTC (permalink / raw)
  To: j-young.choi, ALIM AKHTAR, bvanassche, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

> There is the following quirk to bypass "WB Manual Flush" in Write Booster.
> 
>         - UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL
> 
> If this quirk is not set, there is no knob that can control "WB Manual Flush".
> 
> There are three flags that control Write Booster Feature.
>         1. WB ON/OFF
>         2. WB Hibern Flush ON/OFF
>         3. WB Flush ON/OFF
> 
> The sysfs that controls the WB was implemented. (1)
> 
> In the case of "Hibern Flush", it is always good to turn on.
> Control may not be required. (2)
> 
> Finally, "Manual flush" may be necessary because the Auto-Hibern8 is not
> supported in a specific environment.
> So the sysfs that controls this is necessary. (3)
> 
> Signed-off-by: Jinyoung Choi <j-young.choi@samsung.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>


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

* RE:(2) [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions
       [not found]       ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p2>
@ 2022-07-04  2:44         ` Jinyoung CHOI
  0 siblings, 0 replies; 8+ messages in thread
From: Jinyoung CHOI @ 2022-07-04  2:44 UTC (permalink / raw)
  To: Avri Altman, ALIM AKHTAR, bvanassche, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

>> @@ -5715,6 +5715,9 @@ static int __ufshcd_wb_toggle(struct ufs_hba *hba,
>> bool set, enum flag_idn idn)
>>         enum query_opcode opcode = set ? UPIU_QUERY_OPCODE_SET_FLAG :
>>                                    UPIU_QUERY_OPCODE_CLEAR_FLAG;
>> 
>> +       if (!ufshcd_is_wb_allowed(hba))
>> +               return -EPERM;
>> +
>>         index = ufshcd_wb_get_query_index(hba);
>>         return ufshcd_query_flag_retry(hba, opcode, idn, index, NULL);  } @@ -
>> 5723,60 +5726,50 @@ int ufshcd_wb_toggle(struct ufs_hba *hba, bool
>> enable)  {
> Nobody is checking the return value of ufshcd_wb_toggle(), maybe make it void instead?
>
> Other than that - looks good to me.
>
> Reviewed-by: Avri Altman <avri.altman@wdc.com>

It is used in "wb_on_store()" that turns WB on/off.

Thank you for your review. :)

Jinyoung.

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

* Re: [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions
  2022-07-01  7:46     ` [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions Jinyoung CHOI
  2022-07-03 13:00       ` Avri Altman
       [not found]       ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p2>
@ 2022-07-07 22:28       ` Bart Van Assche
  2 siblings, 0 replies; 8+ messages in thread
From: Bart Van Assche @ 2022-07-07 22:28 UTC (permalink / raw)
  To: j-young.choi, ALIM AKHTAR, avri.altman, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

On 7/1/22 00:46, Jinyoung CHOI wrote:
> The Function names were changed clearly, and the location of the
> comments was modified and added properly.
> 
> In addition, the conditional test of the toggle functions was
> different, so it was modified.
> 
> Unnecessary logs were removed and modified appropriately.

There are too many changes in this patch. Please split this patch, e.g. 
one patch that introduces ufshcd_is_wb_buf_flush_allowed(), one patch 
that renames ufshcd_wb_toggle_flush_during_h8() and its arguments and 
another patch that renames ufshcd_wb_config().

> diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
> index 0a088b47d557..6253606b93b4 100644
> --- a/drivers/ufs/core/ufs-sysfs.c
> +++ b/drivers/ufs/core/ufs-sysfs.c
> @@ -230,7 +230,7 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
>   		 * If the platform supports UFSHCD_CAP_CLK_SCALING, turn WB
>   		 * on/off will be done while clock scaling up/down.
>   		 */
> -		dev_warn(dev, "To control WB through wb_on is not allowed!\n");
> +		dev_warn(dev, "It is not allowed to control WB!\n");

I suggest to change "control" into "configure".

>   static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba)
> @@ -1289,9 +1288,10 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
>   		}
>   	}
>   
> -	/* Enable Write Booster if we have scaled up else disable it */
>   	downgrade_write(&hba->clk_scaling_lock);
>   	is_writelock = false;
> +
> +	/* Enable Write Booster if we have scaled up else disable it */
>   	ufshcd_wb_toggle(hba, scale_up);

The above change could be yet another patch.

>   out_unprepare:
> @@ -5715,6 +5715,9 @@ static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn)
>   	enum query_opcode opcode = set ? UPIU_QUERY_OPCODE_SET_FLAG :
>   				   UPIU_QUERY_OPCODE_CLEAR_FLAG;
>   
> +	if (!ufshcd_is_wb_allowed(hba))
> +		return -EPERM;
> +

Moving the ufshcd_is_wb_allowed() call from ufshcd_wb_toggle() into 
__ufshcd_wb_toggle() should be yet another patch.

> -	if (!(enable ^ hba->dev_info.wb_enabled))
> +	if (hba->dev_info.wb_enabled == enable)
>   		return 0;

This change is independent of the rest of this patch and hence could be 
yet another patch.

> -	dev_info(hba->dev, "%s Write Booster %s\n",
> -			__func__, enable ? "enabled" : "disabled");

Why has this code been left out?

> -	ret = __ufshcd_wb_toggle(hba, set,
> -			QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8);
> -	if (ret) {
> -		dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed: %d\n",
> -			__func__, set ? "enable" : "disable", ret);
> -		return;
> -	}
> -	dev_dbg(hba->dev, "%s WB-Buf Flush during H8 %s\n",
> -			__func__, set ? "enabled" : "disabled");
> +	ret = __ufshcd_wb_toggle(hba, enable,
> +				 QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8);
> +	if (ret)
> +		dev_err(hba->dev, "%s: failed to %s WB buf flush during H8 %d\n",
> +			__func__, enable ? "enable" : "disable", ret);

The above error message is worse than the original error message. Please 
either keep the original message or change it into something better than 
the original, e.g. "Failed to %s WB buffer flushing during H8".

Thanks,

Bart.

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

* Re: [PATCH v3 2/2] scsi: ufs: wb: Add Manual Flush sysfs
  2022-07-01  7:48     ` [PATCH v3 2/2] scsi: ufs: wb: Add Manual Flush sysfs Jinyoung CHOI
  2022-07-03 13:08       ` Avri Altman
@ 2022-07-07 22:45       ` Bart Van Assche
  1 sibling, 0 replies; 8+ messages in thread
From: Bart Van Assche @ 2022-07-07 22:45 UTC (permalink / raw)
  To: j-young.choi, ALIM AKHTAR, avri.altman, jejb, martin.petersen,
	beanhuo, adrian.hunter, linux-scsi, linux-kernel

On 7/1/22 00:48, Jinyoung CHOI wrote:
>

The subject of this email is incomplete. "sysfs" should be changed into 
"sysfs attribute".

Additional, the use of the word "manual" in the subject seems weird to 
me. I think the term "explicit" from the UFS specification describes the 
purpose of the new sysfs attribute better.

Thanks,

Bart.

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

end of thread, other threads:[~2022-07-07 22:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p4>
2022-07-01  7:44 ` [PATCH v3 0/2] scsi: ufs: wb: Add sysfs and cleanup Jinyoung CHOI
     [not found]   ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p5>
2022-07-01  7:46     ` [PATCH v3 1/2] scsi: ufs: wb: renaming & cleanups functions Jinyoung CHOI
2022-07-03 13:00       ` Avri Altman
     [not found]       ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p2>
2022-07-04  2:44         ` Jinyoung CHOI
2022-07-07 22:28       ` Bart Van Assche
     [not found]   ` <CGME20220701074420epcms2p4c4a6a016c7070d5dfa279fc4607caa95@epcms2p8>
2022-07-01  7:48     ` [PATCH v3 2/2] scsi: ufs: wb: Add Manual Flush sysfs Jinyoung CHOI
2022-07-03 13:08       ` Avri Altman
2022-07-07 22:45       ` Bart Van Assche

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).