[v2] scsi: ufs: ufs-sysfs: Expose UFS power info
Commit Message
Having UFS power info available in sysfs makes it easier to tell the state
of the link during runtime considering we have a bunch of power saving
features and various combinations for backward compatibility.
Signed-off-by: Can Guo <quic_cang@quicinc.com>
---
v1 -> v2:
1. Incorporated comments from Bart, Nitin and Mani.
2. Added explanations for gear/lane/rate/dev_pm/link_status in Documentation/ABI/testing/sysfs-driver-ufs
---
Documentation/ABI/testing/sysfs-driver-ufs | 88 ++++++++++++++++++++++++++++++
drivers/ufs/core/ufs-sysfs.c | 71 ++++++++++++++++++++++++
2 files changed, 159 insertions(+)
Comments
On 10/31/23 02:53, Can Guo wrote:
> +What: /sys/bus/platform/drivers/ufshcd/*/power_info/mode
> +What: /sys/bus/platform/devices/*.ufs/power_info/mode
> +Date: September 2023
> +Contact: Can Guo <quic_cang@quicinc.com>
> +Description: This file shows the UniPro power mode of UFS link:
> + == ====================================================
> + 1 FAST_MODE
> + 2 SLOW_MODE
> + 4 FASTAUTO_MODE
> + 5 SLOWAUTO_MODE
> + == ====================================================
> +
> + The file is read only.
For this attribute and the attributes below, shouldn't these be exported
as text instead of as numbers? Shell scripts that read and use these
attributes will be much easier to read if these attributes are changed
from numeric into a textual.
Thanks,
Bart.
Hi Bart,
On 11/1/2023 12:23 AM, Bart Van Assche wrote:
> On 10/31/23 02:53, Can Guo wrote:
>> +What: /sys/bus/platform/drivers/ufshcd/*/power_info/mode
>> +What: /sys/bus/platform/devices/*.ufs/power_info/mode
>> +Date: September 2023
>> +Contact: Can Guo <quic_cang@quicinc.com>
>> +Description: This file shows the UniPro power mode of UFS link:
>> + == ====================================================
>> + 1 FAST_MODE
>> + 2 SLOW_MODE
>> + 4 FASTAUTO_MODE
>> + 5 SLOWAUTO_MODE
>> + == ====================================================
>> +
>> + The file is read only.
>
> For this attribute and the attributes below, shouldn't these be exported
> as text instead of as numbers? Shell scripts that read and use these
> attributes will be much easier to read if these attributes are changed
> from numeric into a textual.
Done.
Thanks,
Can Guo.
>
> Thanks,
>
> Bart.
@@ -1223,6 +1223,94 @@ Description: This file shows the total latency (in micro seconds) of write
The file is read only.
+What: /sys/bus/platform/drivers/ufshcd/*/power_info/lane
+What: /sys/bus/platform/devices/*.ufs/power_info/lane
+Date: September 2023
+Contact: Can Guo <quic_cang@quicinc.com>
+Description: This file shows how many lanes are enabled on the UFS link,
+ i.e., an output 2 means UFS link is operating with 2 lanes.
+
+ The file is read only.
+
+What: /sys/bus/platform/drivers/ufshcd/*/power_info/mode
+What: /sys/bus/platform/devices/*.ufs/power_info/mode
+Date: September 2023
+Contact: Can Guo <quic_cang@quicinc.com>
+Description: This file shows the UniPro power mode of UFS link:
+ == ====================================================
+ 1 FAST_MODE
+ 2 SLOW_MODE
+ 4 FASTAUTO_MODE
+ 5 SLOWAUTO_MODE
+ == ====================================================
+
+ The file is read only.
+
+What: /sys/bus/platform/drivers/ufshcd/*/power_info/rate
+What: /sys/bus/platform/devices/*.ufs/power_info/rate
+Date: September 2023
+Contact: Can Guo <quic_cang@quicinc.com>
+Description: This file shows the speed rate of UFS link:
+ == ====================================================
+ 0 Indicates that the gear is in PWM mode
+ 1 HS_MODE_A - High Speed Rate A
+ 2 HS_MODE_B - High Speed Rate B
+ == ====================================================
+
+ The file is read only.
+
+What: /sys/bus/platform/drivers/ufshcd/*/power_info/gear
+What: /sys/bus/platform/devices/*.ufs/power_info/gear
+Date: September 2023
+Contact: Can Guo <quic_cang@quicinc.com>
+Description: This file shows the gear of UFS link. 'rate' indicates whether
+ the gear is in PWM mode or High-Speed mode.
+ == ====================================================
+ 1 PWM_GEAR1
+ 2 PWM_GEAR2
+ 3 PWM_GEAR3
+ 4 PWM_GEAR4
+ 5 PWM_GEAR5
+ 6 PWM_GEAR6
+ 7 PWM_GEAR7
+ == ====================================================
+ 1 HS_GEAR1
+ 2 HS_GEAR2
+ 3 HS_GEAR3
+ 4 HS_GEAR4
+ 5 HS_GEAR5
+ == ====================================================
+
+ The file is read only.
+
+What: /sys/bus/platform/drivers/ufshcd/*/power_info/dev_pm
+What: /sys/bus/platform/devices/*.ufs/power_info/dev_pm
+Date: September 2023
+Contact: Can Guo <quic_cang@quicinc.com>
+Description: This file shows the UFS device power mode:
+ == ====================================================
+ 1 ACTIVE_PWR_MODE
+ 2 SLEEP_PWR_MODE
+ 3 POWERDOWN_PWR_MODE
+ 4 DEEPSLEEP_PWR_MODE
+ == ====================================================
+
+ The file is read only.
+
+What: /sys/bus/platform/drivers/ufshcd/*/power_info/link_state
+What: /sys/bus/platform/devices/*.ufs/power_info/link_state
+Date: September 2023
+Contact: Can Guo <quic_cang@quicinc.com>
+Description: This file shows the state of UFS link:
+ == ====================================================
+ 0 UIC_LINK_OFF_STATE
+ 1 UIC_LINK_ACTIVE_STATE
+ 2 UIC_LINK_HIBERN8_STATE
+ 3 UIC_LINK_BROKEN_STATE
+ == ====================================================
+
+ The file is read only.
+
What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_presv_us_en
What: /sys/bus/platform/devices/*.ufs/device_descriptor/wb_presv_us_en
Date: June 2020
@@ -628,6 +628,76 @@ static const struct attribute_group ufs_sysfs_monitor_group = {
.attrs = ufs_sysfs_monitor_attrs,
};
+static ssize_t gear_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%u\n", hba->pwr_info.gear_rx);
+}
+
+static ssize_t lane_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%u\n", hba->pwr_info.lane_rx);
+}
+
+static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%u\n", hba->pwr_info.pwr_rx);
+}
+
+static ssize_t rate_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%u\n", hba->pwr_info.hs_rate);
+}
+
+static ssize_t dev_pm_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->curr_dev_pwr_mode);
+}
+
+static ssize_t link_state_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->uic_link_state);
+}
+
+static DEVICE_ATTR_RO(gear);
+static DEVICE_ATTR_RO(lane);
+static DEVICE_ATTR_RO(mode);
+static DEVICE_ATTR_RO(rate);
+static DEVICE_ATTR_RO(dev_pm);
+static DEVICE_ATTR_RO(link_state);
+
+static struct attribute *ufs_power_info_attrs[] = {
+ &dev_attr_gear.attr,
+ &dev_attr_lane.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_rate.attr,
+ &dev_attr_dev_pm.attr,
+ &dev_attr_link_state.attr,
+ NULL
+};
+
+static const struct attribute_group ufs_sysfs_power_info_group = {
+ .name = "power_info",
+ .attrs = ufs_power_info_attrs,
+};
+
static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
enum desc_idn desc_id,
u8 desc_index,
@@ -1233,6 +1303,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
&ufs_sysfs_default_group,
&ufs_sysfs_capabilities_group,
&ufs_sysfs_monitor_group,
+ &ufs_sysfs_power_info_group,
&ufs_sysfs_device_descriptor_group,
&ufs_sysfs_interconnect_descriptor_group,
&ufs_sysfs_geometry_descriptor_group,