Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge patch series "Add UFS RTC support"

Bean Huo <beanhuo@iokpp.de> says:

Adding RTC support for embedded storage device UFS in its driver, it
is important for a few key reasons:

1. Helps with Regular Maintenance:
The RTC provides a basic way to keep track of time, making it useful for
scheduling routine maintenance tasks in the storage device. This includes
things like making sure data is spread
evenly across the storage to extend its life.

2. Figuring Out How Old Data Is:
The RTC helps the device estimate how long ago certain parts of the storage
were last used. This is handy for deciding when to do maintenance tasks to
keep the storage working well over time.

3. Making Devices Last Longer:
By using the RTC for regular upkeep, we can make sure the storage device lasts
longer and stays reliable. This is especially important for devices that need
to work well for a long time.

4.Fitting In with Other Devices:
The inclusion of RTC support aligns with existing UFS specifications (starting
from UFS Spec 2.0) and is consistent with the prevalent industry practice. Many
UFS devices currently on the market utilize RTC for internal timekeeping. By
ensuring compatibility with this widely adopted standard, the embedded storage
device becomes seamlessly integrable with existing hardware and software
ecosystems, reducing the risk of compatibility issues.

In short, adding RTC support to embedded storage device UFS helps with regular
upkeep, extends the device's life, ensures compatibility, and keeps everything
running smoothly with the rest of the system.

Link: https://lore.kernel.org/r/20231212220825.85255-1-beanhuo@iokpp.de
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+151 -6
+7
Documentation/ABI/testing/sysfs-driver-ufs
··· 1523 1523 1524 1524 The file is read only. 1525 1525 1526 + What: /sys/bus/platform/drivers/ufshcd/*/rtc_update_ms 1527 + What: /sys/bus/platform/devices/*.ufs/rtc_update_ms 1528 + Date: November 2023 1529 + Contact: Bean Huo <beanhuo@micron.com> 1530 + Description: 1531 + rtc_update_ms indicates how often the host should synchronize or update the 1532 + UFS RTC. If set to 0, this will disable UFS RTC periodic update.
+31
drivers/ufs/core/ufs-sysfs.c
··· 302 302 return res < 0 ? res : count; 303 303 } 304 304 305 + static ssize_t rtc_update_ms_show(struct device *dev, struct device_attribute *attr, 306 + char *buf) 307 + { 308 + struct ufs_hba *hba = dev_get_drvdata(dev); 309 + 310 + return sysfs_emit(buf, "%d\n", hba->dev_info.rtc_update_period); 311 + } 312 + 313 + static ssize_t rtc_update_ms_store(struct device *dev, struct device_attribute *attr, 314 + const char *buf, size_t count) 315 + { 316 + struct ufs_hba *hba = dev_get_drvdata(dev); 317 + unsigned int ms; 318 + bool resume_period_update = false; 319 + 320 + if (kstrtouint(buf, 0, &ms)) 321 + return -EINVAL; 322 + 323 + if (!hba->dev_info.rtc_update_period && ms > 0) 324 + resume_period_update = true; 325 + /* Minimum and maximum update frequency should be synchronized with all UFS vendors */ 326 + hba->dev_info.rtc_update_period = ms; 327 + 328 + if (resume_period_update) 329 + schedule_delayed_work(&hba->ufs_rtc_update_work, 330 + msecs_to_jiffies(hba->dev_info.rtc_update_period)); 331 + return count; 332 + } 333 + 305 334 static ssize_t enable_wb_buf_flush_show(struct device *dev, 306 335 struct device_attribute *attr, 307 336 char *buf) ··· 415 386 static DEVICE_ATTR_RW(wb_on); 416 387 static DEVICE_ATTR_RW(enable_wb_buf_flush); 417 388 static DEVICE_ATTR_RW(wb_flush_threshold); 389 + static DEVICE_ATTR_RW(rtc_update_ms); 418 390 419 391 static struct attribute *ufs_sysfs_ufshcd_attrs[] = { 420 392 &dev_attr_rpm_lvl.attr, ··· 428 398 &dev_attr_wb_on.attr, 429 399 &dev_attr_enable_wb_buf_flush.attr, 430 400 &dev_attr_wb_flush_threshold.attr, 401 + &dev_attr_rtc_update_ms.attr, 431 402 NULL 432 403 }; 433 404
+95 -6
drivers/ufs/core/ufshcd.c
··· 99 99 /* Polling time to wait for fDeviceInit */ 100 100 #define FDEVICEINIT_COMPL_TIMEOUT 1500 /* millisecs */ 101 101 102 + /* Default RTC update every 10 seconds */ 103 + #define UFS_RTC_UPDATE_INTERVAL_MS (10 * MSEC_PER_SEC) 104 + 102 105 /* UFSHC 4.0 compliant HC support this mode. */ 103 106 static bool use_mcq_mode = true; 104 107 ··· 236 233 237 234 /* if no match found, return the level 0 */ 238 235 return UFS_PM_LVL_0; 236 + } 237 + 238 + static bool ufshcd_is_ufs_dev_busy(struct ufs_hba *hba) 239 + { 240 + return (hba->clk_gating.active_reqs || hba->outstanding_reqs || hba->outstanding_tasks || 241 + hba->active_uic_cmd || hba->uic_async_done); 239 242 } 240 243 241 244 static const struct ufs_dev_quirk ufs_fixups[] = { ··· 688 679 hba->dev_info.wb_enabled = false; 689 680 hba->dev_info.wb_buf_flush_enabled = false; 690 681 } 682 + if (hba->dev_info.rtc_type == UFS_RTC_RELATIVE) 683 + hba->dev_info.rtc_time_baseline = 0; 691 684 } 692 685 if (err != -EOPNOTSUPP) 693 686 ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err); ··· 1930 1919 goto rel_lock; 1931 1920 } 1932 1921 1933 - if (hba->clk_gating.active_reqs 1934 - || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL 1935 - || hba->outstanding_reqs || hba->outstanding_tasks 1936 - || hba->active_uic_cmd || hba->uic_async_done) 1922 + if (ufshcd_is_ufs_dev_busy(hba) || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL) 1937 1923 goto rel_lock; 1938 1924 1939 1925 spin_unlock_irqrestore(hba->host->host_lock, flags); ··· 8197 8189 ufshcd_vops_fixup_dev_quirks(hba); 8198 8190 } 8199 8191 8192 + static void ufshcd_update_rtc(struct ufs_hba *hba) 8193 + { 8194 + struct timespec64 ts64; 8195 + int err; 8196 + u32 val; 8197 + 8198 + ktime_get_real_ts64(&ts64); 8199 + 8200 + if (ts64.tv_sec < hba->dev_info.rtc_time_baseline) { 8201 + dev_warn_once(hba->dev, "%s: Current time precedes previous setting!\n", __func__); 8202 + return; 8203 + } 8204 + 8205 + /* 8206 + * The Absolute RTC mode has a 136-year limit, spanning from 2010 to 2146. If a time beyond 8207 + * 2146 is required, it is recommended to choose the relative RTC mode. 8208 + */ 8209 + val = ts64.tv_sec - hba->dev_info.rtc_time_baseline; 8210 + 8211 + ufshcd_rpm_get_sync(hba); 8212 + err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED, 8213 + 0, 0, &val); 8214 + ufshcd_rpm_put_sync(hba); 8215 + 8216 + if (err) 8217 + dev_err(hba->dev, "%s: Failed to update rtc %d\n", __func__, err); 8218 + else if (hba->dev_info.rtc_type == UFS_RTC_RELATIVE) 8219 + hba->dev_info.rtc_time_baseline = ts64.tv_sec; 8220 + } 8221 + 8222 + static void ufshcd_rtc_work(struct work_struct *work) 8223 + { 8224 + struct ufs_hba *hba; 8225 + 8226 + hba = container_of(to_delayed_work(work), struct ufs_hba, ufs_rtc_update_work); 8227 + 8228 + /* Update RTC only when there are no requests in progress and UFSHCI is operational */ 8229 + if (!ufshcd_is_ufs_dev_busy(hba) && hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL) 8230 + ufshcd_update_rtc(hba); 8231 + 8232 + if (ufshcd_is_ufs_dev_active(hba) && hba->dev_info.rtc_update_period) 8233 + schedule_delayed_work(&hba->ufs_rtc_update_work, 8234 + msecs_to_jiffies(hba->dev_info.rtc_update_period)); 8235 + } 8236 + 8237 + static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf) 8238 + { 8239 + u16 periodic_rtc_update = get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_FRQ_RTC]); 8240 + struct ufs_dev_info *dev_info = &hba->dev_info; 8241 + 8242 + if (periodic_rtc_update & UFS_RTC_TIME_BASELINE) { 8243 + dev_info->rtc_type = UFS_RTC_ABSOLUTE; 8244 + 8245 + /* 8246 + * The concept of measuring time in Linux as the number of seconds elapsed since 8247 + * 00:00:00 UTC on January 1, 1970, and UFS ABS RTC is elapsed from January 1st 8248 + * 2010 00:00, here we need to adjust ABS baseline. 8249 + */ 8250 + dev_info->rtc_time_baseline = mktime64(2010, 1, 1, 0, 0, 0) - 8251 + mktime64(1970, 1, 1, 0, 0, 0); 8252 + } else { 8253 + dev_info->rtc_type = UFS_RTC_RELATIVE; 8254 + dev_info->rtc_time_baseline = 0; 8255 + } 8256 + 8257 + /* 8258 + * We ignore TIME_PERIOD defined in wPeriodicRTCUpdate because Spec does not clearly state 8259 + * how to calculate the specific update period for each time unit. And we disable periodic 8260 + * RTC update work, let user configure by sysfs node according to specific circumstance. 8261 + */ 8262 + dev_info->rtc_update_period = 0; 8263 + } 8264 + 8200 8265 static int ufs_get_device_desc(struct ufs_hba *hba) 8201 8266 { 8202 8267 int err; ··· 8321 8240 ufshcd_wb_probe(hba, desc_buf); 8322 8241 8323 8242 ufshcd_temp_notif_probe(hba, desc_buf); 8243 + 8244 + ufs_init_rtc(hba, desc_buf); 8324 8245 8325 8246 if (hba->ext_iid_sup) 8326 8247 ufshcd_ext_iid_probe(hba, desc_buf); ··· 8877 8794 ufshcd_force_reset_auto_bkops(hba); 8878 8795 8879 8796 ufshcd_set_timestamp_attr(hba); 8797 + schedule_delayed_work(&hba->ufs_rtc_update_work, 8798 + msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS)); 8880 8799 8881 8800 /* Gear up to HS gear if supported */ 8882 8801 if (hba->max_pwr_info.is_valid) { ··· 9836 9751 ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE); 9837 9752 if (ret) 9838 9753 goto set_link_active; 9754 + 9755 + cancel_delayed_work_sync(&hba->ufs_rtc_update_work); 9839 9756 goto out; 9840 9757 9841 9758 set_link_active: ··· 9932 9845 if (ret) 9933 9846 goto set_old_link_state; 9934 9847 ufshcd_set_timestamp_attr(hba); 9848 + schedule_delayed_work(&hba->ufs_rtc_update_work, 9849 + msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS)); 9935 9850 } 9936 9851 9937 9852 if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) ··· 10630 10541 UFS_SLEEP_PWR_MODE, 10631 10542 UIC_LINK_HIBERN8_STATE); 10632 10543 10633 - INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, 10634 - ufshcd_rpm_dev_flush_recheck_work); 10544 + INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work); 10545 + INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work); 10635 10546 10636 10547 /* Set the default auto-hiberate idle timer value to 150 ms */ 10637 10548 if (ufshcd_is_auto_hibern8_supported(hba) && !hba->ahit) {
+14
include/ufs/ufs.h
··· 14 14 #include <linux/bitops.h> 15 15 #include <linux/types.h> 16 16 #include <uapi/scsi/scsi_bsg_ufs.h> 17 + #include <linux/time64.h> 17 18 18 19 /* 19 20 * Using static_assert() is not allowed in UAPI header files. Hence the check ··· 552 551 struct ufs_vreg *vdd_hba; 553 552 }; 554 553 554 + /* UFS device descriptor wPeriodicRTCUpdate bit9 defines RTC time baseline */ 555 + #define UFS_RTC_TIME_BASELINE BIT(9) 556 + 557 + enum ufs_rtc_time { 558 + UFS_RTC_RELATIVE, 559 + UFS_RTC_ABSOLUTE 560 + }; 561 + 555 562 struct ufs_dev_info { 556 563 bool f_power_on_wp_en; 557 564 /* Keeps information if any of the LU is power on write protected */ ··· 587 578 588 579 /* UFS EXT_IID Enable */ 589 580 bool b_ext_iid_en; 581 + 582 + /* UFS RTC */ 583 + enum ufs_rtc_time rtc_type; 584 + time64_t rtc_time_baseline; 585 + u32 rtc_update_period; 590 586 }; 591 587 592 588 /*
+4
include/ufs/ufshcd.h
··· 912 912 * @mcq_base: Multi circular queue registers base address 913 913 * @uhq: array of supported hardware queues 914 914 * @dev_cmd_queue: Queue for issuing device management commands 915 + * @mcq_opr: MCQ operation and runtime registers 916 + * @ufs_rtc_update_work: A work for UFS RTC periodic update 915 917 */ 916 918 struct ufs_hba { 917 919 void __iomem *mmio_base; ··· 1078 1076 struct ufs_hw_queue *uhq; 1079 1077 struct ufs_hw_queue *dev_cmd_queue; 1080 1078 struct ufshcd_mcq_opr_info_t mcq_opr[OPR_MAX]; 1079 + 1080 + struct delayed_work ufs_rtc_update_work; 1081 1081 }; 1082 1082 1083 1083 /**