diff mbox series

[v2] ufs: core: Add WB buffer resize support

Message ID 20241026004423.135-1-tanghuan@vivo.com (mailing list archive)
State New
Headers show
Series [v2] ufs: core: Add WB buffer resize support | expand

Commit Message

Huan Tang Oct. 26, 2024, 12:44 a.m. UTC
Support WB buffer resize function through sysfs, the host can obtain
resize hint and resize status and enable the resize operation. To
achieve this goals, three sysfs nodes have been added:
	1. wb_toggle_buf_resize
	2. wb_buf_resize_hint
	3. wb_buf_resize_status

The detailed definition of the three nodes can be found in the sysfs
documentation.

Changelog
===
	v1 - > v2:
	remove unused variable "u8 index",
	drivers/ufs/core/ufs-sysfs.c:419:12: warning: variable 'index'
	set but not used.

v1
	https://lore.kernel.org/all/20241025085924.4855-1-tanghuan@vivo.com/

Signed-off-by: Huan Tang <tanghuan@vivo.com>
Signed-off-by: Lu Hongfei <luhongfei@vivo.com>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 52 ++++++++++++++++++++++
 drivers/ufs/core/ufs-sysfs.c               | 43 ++++++++++++++++++
 drivers/ufs/core/ufshcd.c                  | 15 +++++++
 include/ufs/ufs.h                          |  5 ++-
 include/ufs/ufshcd.h                       |  1 +
 5 files changed, 115 insertions(+), 1 deletion(-)

Comments

kernel test robot Oct. 26, 2024, 5:03 p.m. UTC | #1
Hi Huan,

kernel test robot noticed the following build errors:

[auto build test ERROR on jejb-scsi/for-next]
[also build test ERROR on mkp-scsi/for-next linus/master v6.12-rc4 next-20241025]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Huan-Tang/ufs-core-Add-WB-buffer-resize-support/20241026-084545
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link:    https://lore.kernel.org/r/20241026004423.135-1-tanghuan%40vivo.com
patch subject: [PATCH v2] ufs: core: Add WB buffer resize support
config: i386-randconfig-141-20241026 (https://download.01.org/0day-ci/archive/20241027/202410270024.rwb7xAgC-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241027/202410270024.rwb7xAgC-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410270024.rwb7xAgC-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/ufs/core/ufs-sysfs.c: In function 'wb_toggle_buf_resize_store':
>> drivers/ufs/core/ufs-sysfs.c:441:9: error: 'index' undeclared (first use in this function)
     441 |         index = ufshcd_wb_get_query_index(hba);
         |         ^~~~~
   drivers/ufs/core/ufs-sysfs.c:441:9: note: each undeclared identifier is reported only once for each function it appears in

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for GET_FREE_REGION
   Depends on [n]: SPARSEMEM [=n]
   Selected by [m]:
   - RESOURCE_KUNIT_TEST [=m] && RUNTIME_TESTING_MENU [=y] && KUNIT [=y]


vim +/index +441 drivers/ufs/core/ufs-sysfs.c

   413	
   414	static ssize_t wb_toggle_buf_resize_store(struct device *dev,
   415			struct device_attribute *attr, const char *buf, size_t count)
   416	{
   417		struct ufs_hba *hba = dev_get_drvdata(dev);
   418		unsigned int wb_buf_resize_op;
   419		ssize_t res;
   420	
   421		if (!ufshcd_is_wb_allowed(hba) || !hba->dev_info.wb_enabled ||
   422			!hba->dev_info.b_presrv_uspc_en) {
   423			dev_err(dev, "The WB buf resize is not allowed!\n");
   424			return -EOPNOTSUPP;
   425		}
   426	
   427		if (kstrtouint(buf, 0, &wb_buf_resize_op))
   428			return -EINVAL;
   429	
   430		if (wb_buf_resize_op != 0x01 && wb_buf_resize_op != 0x02) {
   431			dev_err(dev, "The operation %u is invalid!\n", wb_buf_resize_op);
   432			return -EINVAL;
   433		}
   434	
   435		down(&hba->host_sem);
   436		if (!ufshcd_is_user_access_allowed(hba)) {
   437			res = -EBUSY;
   438			goto out;
   439		}
   440	
 > 441		index = ufshcd_wb_get_query_index(hba);
   442		ufshcd_rpm_get_sync(hba);
   443		res = ufshcd_wb_toggle_buf_resize(hba, wb_buf_resize_op);
   444		ufshcd_rpm_put_sync(hba);
   445	
   446	out:
   447		up(&hba->host_sem);
   448		return res < 0 ? res : count;
   449	}
   450
kernel test robot Oct. 26, 2024, 5:44 p.m. UTC | #2
Hi Huan,

kernel test robot noticed the following build errors:

[auto build test ERROR on jejb-scsi/for-next]
[also build test ERROR on mkp-scsi/for-next linus/master v6.12-rc4 next-20241025]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Huan-Tang/ufs-core-Add-WB-buffer-resize-support/20241026-084545
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link:    https://lore.kernel.org/r/20241026004423.135-1-tanghuan%40vivo.com
patch subject: [PATCH v2] ufs: core: Add WB buffer resize support
config: i386-buildonly-randconfig-001-20241026 (https://download.01.org/0day-ci/archive/20241027/202410270108.zrM5GjRx-lkp@intel.com/config)
compiler: clang version 19.1.2 (https://github.com/llvm/llvm-project 7ba7d8e2f7b6445b60679da826210cdde29eaf8b)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241027/202410270108.zrM5GjRx-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410270108.zrM5GjRx-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/ufs/core/ufs-sysfs.c:12:
   In file included from drivers/ufs/core/ufshcd-priv.h:7:
   In file included from include/ufs/ufshcd.h:16:
   In file included from include/linux/blk-crypto-profile.h:9:
   In file included from include/linux/bio.h:10:
   In file included from include/linux/blk_types.h:10:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:8:
   In file included from include/linux/cacheflush.h:5:
   In file included from arch/x86/include/asm/cacheflush.h:5:
   In file included from include/linux/mm.h:2213:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/ufs/core/ufs-sysfs.c:441:2: error: use of undeclared identifier 'index'
     441 |         index = ufshcd_wb_get_query_index(hba);
         |         ^
   1 warning and 1 error generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for GET_FREE_REGION
   Depends on [n]: SPARSEMEM [=n]
   Selected by [y]:
   - RESOURCE_KUNIT_TEST [=y] && RUNTIME_TESTING_MENU [=y] && KUNIT [=y]


vim +/index +441 drivers/ufs/core/ufs-sysfs.c

   413	
   414	static ssize_t wb_toggle_buf_resize_store(struct device *dev,
   415			struct device_attribute *attr, const char *buf, size_t count)
   416	{
   417		struct ufs_hba *hba = dev_get_drvdata(dev);
   418		unsigned int wb_buf_resize_op;
   419		ssize_t res;
   420	
   421		if (!ufshcd_is_wb_allowed(hba) || !hba->dev_info.wb_enabled ||
   422			!hba->dev_info.b_presrv_uspc_en) {
   423			dev_err(dev, "The WB buf resize is not allowed!\n");
   424			return -EOPNOTSUPP;
   425		}
   426	
   427		if (kstrtouint(buf, 0, &wb_buf_resize_op))
   428			return -EINVAL;
   429	
   430		if (wb_buf_resize_op != 0x01 && wb_buf_resize_op != 0x02) {
   431			dev_err(dev, "The operation %u is invalid!\n", wb_buf_resize_op);
   432			return -EINVAL;
   433		}
   434	
   435		down(&hba->host_sem);
   436		if (!ufshcd_is_user_access_allowed(hba)) {
   437			res = -EBUSY;
   438			goto out;
   439		}
   440	
 > 441		index = ufshcd_wb_get_query_index(hba);
   442		ufshcd_rpm_get_sync(hba);
   443		res = ufshcd_wb_toggle_buf_resize(hba, wb_buf_resize_op);
   444		ufshcd_rpm_put_sync(hba);
   445	
   446	out:
   447		up(&hba->host_sem);
   448		return res < 0 ? res : count;
   449	}
   450
Bean Huo Oct. 26, 2024, 7:40 p.m. UTC | #3
Hi Tang,

I saw that "Both UFS 4.1 and UFS 5.0 are currently in development" have
not been officially published yet. Are you keen to incorporate features
based on an unpublished standard?


Kind regards,
Bean

On Sat, 2024-10-26 at 08:44 +0800, Huan Tang wrote:
> Support WB buffer resize function through sysfs, the host can obtain
> resize hint and resize status and enable the resize operation. To
> achieve this goals, three sysfs nodes have been added:
>         1. wb_toggle_buf_resize
>         2. wb_buf_resize_hint
>         3. wb_buf_resize_status
> 
> The detailed definition of the three nodes can be found in the sysfs
> documentation.
> 
> Changelog
> ===
>         v1 - > v2:
>         remove unused variable "u8 index",
>         drivers/ufs/core/ufs-sysfs.c:419:12: warning: variable
> 'index'
>         set but not used.
> 
> v1
>         
> https://lore.kernel.org/all/20241025085924.4855-1-tanghuan@vivo.com/
> 
> Signed-off-by: Huan Tang <tanghuan@vivo.com>
> Signed-off-by: Lu Hongfei <luhongfei@vivo.com>
> ---
>  Documentation/ABI/testing/sysfs-driver-ufs | 52
> ++++++++++++++++++++++
>  drivers/ufs/core/ufs-sysfs.c               | 43 ++++++++++++++++++
>  drivers/ufs/core/ufshcd.c                  | 15 +++++++
>  include/ufs/ufs.h                          |  5 ++-
>  include/ufs/ufshcd.h                       |  1 +
>  5 files changed, 115 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
> b/Documentation/ABI/testing/sysfs-driver-ufs
> index 5fa6655aee84..dbaa84277801 100644
> --- a/Documentation/ABI/testing/sysfs-driver-ufs
> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
> @@ -1559,3 +1559,55 @@ Description:
>                 Symbol - HCMID. This file shows the UFSHCD
> manufacturer id.
>                 The Manufacturer ID is defined by JEDEC in JEDEC-
> JEP106.
>                 The file is read only.
> +
> +What:          /sys/bus/platform/drivers/ufshcd/*/wb_toggle_buf_resi
> ze
> +What:          /sys/bus/platform/devices/*.ufs/wb_toggle_buf_resize
> +Date:          Qct 2024
> +Contact:       Huan Tang <tanghuan@vivo.com>
> +Description:
> +               The host can decrease or increase the WriteBooster
> Buffer size by setting
> +               this file.
> +
> +               ======  ======================================
> +               00h  Idle (There is no resize operation)
> +               01h  Decrease WriteBooster Buffer Size
> +               02h  Increase WriteBooster Buffer Size
> +               Others  Reserved
> +               ======  ======================================
> +
> +               The file is write only.
> +
> +What:          /sys/bus/platform/drivers/ufshcd/*/attributes/wb_buf_
> resize_hint
> +What:          /sys/bus/platform/devices/*.ufs/attributes/wb_buf_res
> ize_hint
> +Date:          Qct 2024
> +Contact:       Huan Tang <tanghuan@vivo.com>
> +Description:
> +               wb_buf_resize_hint indicates hint information about
> which type of resize for
> +               WriteBooster Buffer is recommended by the device.
> +
> +               ======  ======================================
> +               00h  Recommend keep the buffer size
> +               01h  Recommend to decrease the buffer size
> +               02h  Recommend to increase the buffer size
> +               Others: Reserved
> +               ======  ======================================
> +
> +               The file is read only.
> +
> +What:          /sys/bus/platform/drivers/ufshcd/*/attributes/wb_buf_
> resize_status
> +What:          /sys/bus/platform/devices/*.ufs/attributes/wb_buf_res
> ize_status
> +Date:          Qct 2024
> +Contact:       Huan Tang <tanghuan@vivo.com>
> +Description:
> +               The host can check the Resize operation status of the
> WriteBooster Buffer
> +               by reading this file.
> +
> +               ======  ========================================
> +               00h  Idle (resize operation is not issued)
> +               01h  Resize operation in progress
> +               02h  Resize operation completed successfully
> +               03h  Resize operation general failure
> +               Others  Reserved
> +               ======  ========================================
> +
> +               The file is read only.
> diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-
> sysfs.c
> index 265f21133b63..bb21982394c8 100644
> --- a/drivers/ufs/core/ufs-sysfs.c
> +++ b/drivers/ufs/core/ufs-sysfs.c
> @@ -411,6 +411,43 @@ static ssize_t wb_flush_threshold_store(struct
> device *dev,
>         return count;
>  }
>  
> +static ssize_t wb_toggle_buf_resize_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_resize_op;
> +       ssize_t res;
> +
> +       if (!ufshcd_is_wb_allowed(hba) || !hba->dev_info.wb_enabled
> ||
> +               !hba->dev_info.b_presrv_uspc_en) {
> +               dev_err(dev, "The WB buf resize is not allowed!\n");
> +               return -EOPNOTSUPP;
> +       }
> +
> +       if (kstrtouint(buf, 0, &wb_buf_resize_op))
> +               return -EINVAL;
> +
> +       if (wb_buf_resize_op != 0x01 && wb_buf_resize_op != 0x02) {
> +               dev_err(dev, "The operation %u is invalid!\n",
> wb_buf_resize_op);
> +               return -EINVAL;
> +       }
> +
> +       down(&hba->host_sem);
> +       if (!ufshcd_is_user_access_allowed(hba)) {
> +               res = -EBUSY;
> +               goto out;
> +       }
> +
> +       index = ufshcd_wb_get_query_index(hba);
> +       ufshcd_rpm_get_sync(hba);
> +       res = ufshcd_wb_toggle_buf_resize(hba, wb_buf_resize_op);
> +       ufshcd_rpm_put_sync(hba);
> +
> +out:
> +       up(&hba->host_sem);
> +       return res < 0 ? res : count;
> +}
> +
>  /**
>   * pm_qos_enable_show - sysfs handler to show pm qos enable value
>   * @dev: device associated with the UFS controller
> @@ -468,6 +505,7 @@ static DEVICE_ATTR_RW(auto_hibern8);
>  static DEVICE_ATTR_RW(wb_on);
>  static DEVICE_ATTR_RW(enable_wb_buf_flush);
>  static DEVICE_ATTR_RW(wb_flush_threshold);
> +static DEVICE_ATTR_WO(wb_toggle_buf_resize);
>  static DEVICE_ATTR_RW(rtc_update_ms);
>  static DEVICE_ATTR_RW(pm_qos_enable);
>  
> @@ -482,6 +520,7 @@ static struct attribute *ufs_sysfs_ufshcd_attrs[]
> = {
>         &dev_attr_wb_on.attr,
>         &dev_attr_enable_wb_buf_flush.attr,
>         &dev_attr_wb_flush_threshold.attr,
> +       &dev_attr_wb_toggle_buf_resize.attr,
>         &dev_attr_rtc_update_ms.attr,
>         &dev_attr_pm_qos_enable.attr,
>         NULL
> @@ -1526,6 +1565,8 @@ UFS_ATTRIBUTE(wb_flush_status,
> _WB_FLUSH_STATUS);
>  UFS_ATTRIBUTE(wb_avail_buf, _AVAIL_WB_BUFF_SIZE);
>  UFS_ATTRIBUTE(wb_life_time_est, _WB_BUFF_LIFE_TIME_EST);
>  UFS_ATTRIBUTE(wb_cur_buf, _CURR_WB_BUFF_SIZE);
> +UFS_ATTRIBUTE(wb_buf_resize_hint, _WB_BUF_RESIZE_HINT);
> +UFS_ATTRIBUTE(wb_buf_resize_status, _WB_BUF_RESIZE_STATUS);
>  
>  
>  static struct attribute *ufs_sysfs_attributes[] = {
> @@ -1549,6 +1590,8 @@ static struct attribute *ufs_sysfs_attributes[]
> = {
>         &dev_attr_wb_avail_buf.attr,
>         &dev_attr_wb_life_time_est.attr,
>         &dev_attr_wb_cur_buf.attr,
> +       &dev_attr_wb_buf_resize_hint.attr,
> +       &dev_attr_wb_buf_resize_status.attr,
>         NULL,
>  };
>  
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 630409187c10..c28915debab6 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -6167,6 +6167,21 @@ static bool ufshcd_wb_need_flush(struct
> ufs_hba *hba)
>         return ufshcd_wb_presrv_usrspc_keep_vcc_on(hba, avail_buf);
>  }
>  
> +int ufshcd_wb_toggle_buf_resize(struct ufs_hba *hba, u32 op)
> +{
> +       int ret;
> +       u8 index;
> +
> +       index = ufshcd_wb_get_query_index(hba);
> +       ret = ufshcd_query_attr_retry(hba,
> UPIU_QUERY_OPCODE_WRITE_ATTR,
> +                                  QUERY_ATTR_IDN_WB_BUF_RESIZE_EN,
> index, 0, &op);
> +       if (ret)
> +               dev_err(hba->dev, "%s: Enable WB buf resize operation
> failed %d\n",
> +                       __func__, ret);
> +
> +       return ret;
> +}
> +
>  static void ufshcd_rpm_dev_flush_recheck_work(struct work_struct
> *work)
>  {
>         struct ufs_hba *hba = container_of(to_delayed_work(work),
> diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
> index e594abe5d05f..f737d98044ac 100644
> --- a/include/ufs/ufs.h
> +++ b/include/ufs/ufs.h
> @@ -181,7 +181,10 @@ enum attr_idn {
>         QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST    = 0x1E,
>         QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE        = 0x1F,
>         QUERY_ATTR_IDN_EXT_IID_EN               = 0x2A,
> -       QUERY_ATTR_IDN_TIMESTAMP                = 0x30
> +       QUERY_ATTR_IDN_TIMESTAMP                = 0x30,
> +       QUERY_ATTR_IDN_WB_BUF_RESIZE_HINT       = 0x3C,
> +       QUERY_ATTR_IDN_WB_BUF_RESIZE_EN         = 0x3D,
> +       QUERY_ATTR_IDN_WB_BUF_RESIZE_STATUS     = 0x3E,
>  };
>  
>  /* Descriptor idn for Query requests */
> diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
> index a95282b9f743..cbe208ce9293 100644
> --- a/include/ufs/ufshcd.h
> +++ b/include/ufs/ufshcd.h
> @@ -1454,6 +1454,7 @@ int ufshcd_advanced_rpmb_req_handler(struct
> ufs_hba *hba, struct utp_upiu_req *r
>                                      struct scatterlist *sg_list,
> enum dma_data_direction dir);
>  int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
>  int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable);
> +int ufshcd_wb_toggle_buf_resize(struct ufs_hba *hba, u32 op);
>  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);
diff mbox series

Patch

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 5fa6655aee84..dbaa84277801 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1559,3 +1559,55 @@  Description:
 		Symbol - HCMID. This file shows the UFSHCD manufacturer id.
 		The Manufacturer ID is defined by JEDEC in JEDEC-JEP106.
 		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/wb_toggle_buf_resize
+What:		/sys/bus/platform/devices/*.ufs/wb_toggle_buf_resize
+Date:		Qct 2024
+Contact:	Huan Tang <tanghuan@vivo.com>
+Description:
+		The host can decrease or increase the WriteBooster Buffer size by setting
+		this file.
+
+		======  ======================================
+		00h  Idle (There is no resize operation)
+		01h  Decrease WriteBooster Buffer Size
+		02h  Increase WriteBooster Buffer Size
+		Others  Reserved
+		======  ======================================
+
+		The file is write only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/wb_buf_resize_hint
+What:		/sys/bus/platform/devices/*.ufs/attributes/wb_buf_resize_hint
+Date:		Qct 2024
+Contact:	Huan Tang <tanghuan@vivo.com>
+Description:
+		wb_buf_resize_hint indicates hint information about which type of resize for
+		WriteBooster Buffer is recommended by the device.
+
+		======  ======================================
+		00h  Recommend keep the buffer size
+		01h  Recommend to decrease the buffer size
+		02h  Recommend to increase the buffer size
+		Others: Reserved
+		======  ======================================
+
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/wb_buf_resize_status
+What:		/sys/bus/platform/devices/*.ufs/attributes/wb_buf_resize_status
+Date:		Qct 2024
+Contact:	Huan Tang <tanghuan@vivo.com>
+Description:
+		The host can check the Resize operation status of the WriteBooster Buffer
+		by reading this file.
+
+		======  ========================================
+		00h  Idle (resize operation is not issued)
+		01h  Resize operation in progress
+		02h  Resize operation completed successfully
+		03h  Resize operation general failure
+		Others  Reserved
+		======  ========================================
+
+		The file is read only.
diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
index 265f21133b63..bb21982394c8 100644
--- a/drivers/ufs/core/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -411,6 +411,43 @@  static ssize_t wb_flush_threshold_store(struct device *dev,
 	return count;
 }
 
+static ssize_t wb_toggle_buf_resize_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_resize_op;
+	ssize_t res;
+
+	if (!ufshcd_is_wb_allowed(hba) || !hba->dev_info.wb_enabled ||
+		!hba->dev_info.b_presrv_uspc_en) {
+		dev_err(dev, "The WB buf resize is not allowed!\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (kstrtouint(buf, 0, &wb_buf_resize_op))
+		return -EINVAL;
+
+	if (wb_buf_resize_op != 0x01 && wb_buf_resize_op != 0x02) {
+		dev_err(dev, "The operation %u is invalid!\n", wb_buf_resize_op);
+		return -EINVAL;
+	}
+
+	down(&hba->host_sem);
+	if (!ufshcd_is_user_access_allowed(hba)) {
+		res = -EBUSY;
+		goto out;
+	}
+
+	index = ufshcd_wb_get_query_index(hba);
+	ufshcd_rpm_get_sync(hba);
+	res = ufshcd_wb_toggle_buf_resize(hba, wb_buf_resize_op);
+	ufshcd_rpm_put_sync(hba);
+
+out:
+	up(&hba->host_sem);
+	return res < 0 ? res : count;
+}
+
 /**
  * pm_qos_enable_show - sysfs handler to show pm qos enable value
  * @dev: device associated with the UFS controller
@@ -468,6 +505,7 @@  static DEVICE_ATTR_RW(auto_hibern8);
 static DEVICE_ATTR_RW(wb_on);
 static DEVICE_ATTR_RW(enable_wb_buf_flush);
 static DEVICE_ATTR_RW(wb_flush_threshold);
+static DEVICE_ATTR_WO(wb_toggle_buf_resize);
 static DEVICE_ATTR_RW(rtc_update_ms);
 static DEVICE_ATTR_RW(pm_qos_enable);
 
@@ -482,6 +520,7 @@  static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
 	&dev_attr_wb_on.attr,
 	&dev_attr_enable_wb_buf_flush.attr,
 	&dev_attr_wb_flush_threshold.attr,
+	&dev_attr_wb_toggle_buf_resize.attr,
 	&dev_attr_rtc_update_ms.attr,
 	&dev_attr_pm_qos_enable.attr,
 	NULL
@@ -1526,6 +1565,8 @@  UFS_ATTRIBUTE(wb_flush_status, _WB_FLUSH_STATUS);
 UFS_ATTRIBUTE(wb_avail_buf, _AVAIL_WB_BUFF_SIZE);
 UFS_ATTRIBUTE(wb_life_time_est, _WB_BUFF_LIFE_TIME_EST);
 UFS_ATTRIBUTE(wb_cur_buf, _CURR_WB_BUFF_SIZE);
+UFS_ATTRIBUTE(wb_buf_resize_hint, _WB_BUF_RESIZE_HINT);
+UFS_ATTRIBUTE(wb_buf_resize_status, _WB_BUF_RESIZE_STATUS);
 
 
 static struct attribute *ufs_sysfs_attributes[] = {
@@ -1549,6 +1590,8 @@  static struct attribute *ufs_sysfs_attributes[] = {
 	&dev_attr_wb_avail_buf.attr,
 	&dev_attr_wb_life_time_est.attr,
 	&dev_attr_wb_cur_buf.attr,
+	&dev_attr_wb_buf_resize_hint.attr,
+	&dev_attr_wb_buf_resize_status.attr,
 	NULL,
 };
 
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 630409187c10..c28915debab6 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -6167,6 +6167,21 @@  static bool ufshcd_wb_need_flush(struct ufs_hba *hba)
 	return ufshcd_wb_presrv_usrspc_keep_vcc_on(hba, avail_buf);
 }
 
+int ufshcd_wb_toggle_buf_resize(struct ufs_hba *hba, u32 op)
+{
+	int ret;
+	u8 index;
+
+	index = ufshcd_wb_get_query_index(hba);
+	ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
+				   QUERY_ATTR_IDN_WB_BUF_RESIZE_EN, index, 0, &op);
+	if (ret)
+		dev_err(hba->dev, "%s: Enable WB buf resize operation failed %d\n",
+			__func__, ret);
+
+	return ret;
+}
+
 static void ufshcd_rpm_dev_flush_recheck_work(struct work_struct *work)
 {
 	struct ufs_hba *hba = container_of(to_delayed_work(work),
diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
index e594abe5d05f..f737d98044ac 100644
--- a/include/ufs/ufs.h
+++ b/include/ufs/ufs.h
@@ -181,7 +181,10 @@  enum attr_idn {
 	QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST    = 0x1E,
 	QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE        = 0x1F,
 	QUERY_ATTR_IDN_EXT_IID_EN		= 0x2A,
-	QUERY_ATTR_IDN_TIMESTAMP		= 0x30
+	QUERY_ATTR_IDN_TIMESTAMP		= 0x30,
+	QUERY_ATTR_IDN_WB_BUF_RESIZE_HINT	= 0x3C,
+	QUERY_ATTR_IDN_WB_BUF_RESIZE_EN		= 0x3D,
+	QUERY_ATTR_IDN_WB_BUF_RESIZE_STATUS	= 0x3E,
 };
 
 /* Descriptor idn for Query requests */
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index a95282b9f743..cbe208ce9293 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -1454,6 +1454,7 @@  int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r
 				     struct scatterlist *sg_list, enum dma_data_direction dir);
 int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
 int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable);
+int ufshcd_wb_toggle_buf_resize(struct ufs_hba *hba, u32 op);
 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);