@@ -22,11 +22,13 @@
/**
* enum scmd_cmd - system commands
* @scmd_cmd_read_rtc: read the real-time clock (RTC)
+ * @scmd_cmd_write_rtc: set the real-time clock (RTC)
* @scmd_cmd_power_off: power off the system
* @scmd_cmd_read_machine_name: read machine name
*/
enum scmd_cmd {
scmd_cmd_read_rtc = 8,
+ scmd_cmd_write_rtc = 9,
scmd_cmd_power_off = 15,
scmd_cmd_read_machine_name = 23,
};
@@ -49,4 +51,6 @@ struct scmd_machine_name scmd_read_machine_name(void);
int scmd_read_rtc(time64_t *t);
+int scmd_set_rtc(time64_t t);
+
#endif /* __ASM_MACH_PS2_SCMD_H */
@@ -321,6 +321,59 @@ int scmd_read_rtc(time64_t *t)
}
EXPORT_SYMBOL_GPL(scmd_read_rtc);
+/**
+ * scmd_set_rtc - system command to set the real-time clock (RTC)
+ * @t: the time to set
+ *
+ * The hardware clock is designed to keep Japan standard time (JST), regardless
+ * of the region of the machine. This is adjusted in the driver so that the
+ * clock to the kernel appears to be kept in coordinated universal time (UTC).
+ * Tools such as hwclock should therefore set the clock in the UTC timescale.
+
+ * Context: sleep
+ * Return: 0 on success, else a negative error number
+ */
+int scmd_set_rtc(time64_t t)
+{
+ struct __attribute__ ((packed)) {
+ u8 second;
+ u8 minute;
+ u8 hour;
+ u8 pad;
+ u8 day;
+ u8 month;
+ u8 year;
+ } rtc = { };
+ struct rtc_time tm;
+ u8 status;
+ int err;
+
+ rtc_time_to_tm(t + UTC_TO_JST, &tm);
+ rtc.second = bin2bcd(tm.tm_sec);
+ rtc.minute = bin2bcd(tm.tm_min);
+ rtc.hour = bin2bcd(tm.tm_hour);
+ rtc.day = bin2bcd(tm.tm_mday);
+ rtc.month = bin2bcd(tm.tm_mon + 1);
+ rtc.year = bin2bcd(tm.tm_year - 100);
+
+ BUILD_BUG_ON(sizeof(rtc) != 7);
+ err = scmd(scmd_cmd_write_rtc, &rtc, sizeof(rtc),
+ &status, sizeof(status));
+ if (err < 0) {
+ pr_debug("%s: Write failed with %d\n", __func__, err);
+ return err;
+ }
+
+ if (status != 0) {
+ pr_debug("%s: Invalid result with status 0x%x\n",
+ __func__, status);
+ return -EIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(scmd_set_rtc);
+
MODULE_DESCRIPTION("PlayStation 2 system commands");
MODULE_AUTHOR("Fredrik Noring");
MODULE_LICENSE("GPL");
The hardware clock is designed to keep Japan standard time (JST), regardless of the region of the machine. This is adjusted in the driver so that the clock to the kernel appears to be kept in coordinated universal time (UTC). Tools such as hwclock should therefore set the clock in the UTC timescale. Signed-off-by: Fredrik Noring <noring@nocrew.org> --- arch/mips/include/asm/mach-ps2/scmd.h | 4 ++ arch/mips/ps2/scmd.c | 53 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+)