From: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
To: util-linux@vger.kernel.org
Cc: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Subject: [PATCH] hwclock: add support for RTC_VL_READ/RTC_VL_CLR ioctls
Date: Tue, 13 Jun 2023 12:14:28 +0200 [thread overview]
Message-ID: <20230613101428.294827-1-rasmus.villemoes@prevas.dk> (raw)
Implement a way for userspace to query the status of the backup
battery, if supported by the hardware and driver.
The RTC_VL_* bits are a somewhat recent addition (3431ca4837bf, but
really only from b0efe0281234) to the uapi header,
so provide our own definition if the build host's header doesn't.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
sys-utils/hwclock-rtc.c | 86 +++++++++++++++++++++++++++++++++++++++++
sys-utils/hwclock.c | 35 +++++++++++++++++
sys-utils/hwclock.h | 5 +++
3 files changed, 126 insertions(+)
diff --git a/sys-utils/hwclock-rtc.c b/sys-utils/hwclock-rtc.c
index 7094cd063..f918272a1 100644
--- a/sys-utils/hwclock-rtc.c
+++ b/sys-utils/hwclock-rtc.c
@@ -518,3 +518,89 @@ done:
free(opt);
return rc;
}
+
+#ifndef RTC_VL_DATA_INVALID
+#define RTC_VL_DATA_INVALID 0x1
+#endif
+#ifndef RTC_VL_BACKUP_LOW
+#define RTC_VL_BACKUP_LOW 0x2
+#endif
+#ifndef RTC_VL_BACKUP_EMPTY
+#define RTC_VL_BACKUP_EMPTY 0x4
+#endif
+#ifndef RTC_VL_ACCURACY_LOW
+#define RTC_VL_ACCURACY_LOW 0x8
+#endif
+#ifndef RTC_VL_BACKUP_SWITCH
+#define RTC_VL_BACKUP_SWITCH 0x10
+#endif
+
+int rtc_vl_read(const struct hwclock_control *ctl)
+{
+ unsigned int vl;
+ int rtc_fd;
+ size_t i;
+ static const struct vl_bit {
+ unsigned int bit;
+ const char *desc;
+ } vl_bits[] = {
+ { RTC_VL_DATA_INVALID, N_("Voltage too low, RTC data is invalid") },
+ { RTC_VL_BACKUP_LOW, N_("Backup voltage is low") },
+ { RTC_VL_BACKUP_EMPTY, N_("Backup empty or not present") },
+ { RTC_VL_ACCURACY_LOW, N_("Voltage is low, RTC accuracy is reduced") },
+ { RTC_VL_BACKUP_SWITCH, N_("Backup switchover happened") },
+ };
+
+ rtc_fd = open_rtc(ctl);
+ if (rtc_fd < 0) {
+ warnx(_("cannot open %s"), rtc_dev_name);
+ return 1;
+ }
+
+ if (ioctl(rtc_fd, RTC_VL_READ, &vl) == -1) {
+ warn(_("ioctl(%d, RTC_VL_READ) on %s failed"),
+ rtc_fd, rtc_dev_name);
+ return 1;
+ }
+
+ if (ctl->verbose) {
+ printf(_("ioctl(%d, RTC_VL_READ) on %s returned 0x%x\n"),
+ rtc_fd, rtc_dev_name, vl);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vl_bits); ++i) {
+ const struct vl_bit *vlb = &vl_bits[i];
+
+ if (vl & vlb->bit) {
+ printf("0x%02x - %s\n", vlb->bit, vlb->desc);
+ vl &= ~vlb->bit;
+ }
+ }
+ if (vl)
+ printf("0x%02x - unknown bit(s)\n", vl);
+
+ return 0;
+}
+
+int rtc_vl_clear(const struct hwclock_control *ctl)
+{
+ int rtc_fd;
+
+ rtc_fd = open_rtc(ctl);
+ if (rtc_fd < 0) {
+ warnx(_("cannot open %s"), rtc_dev_name);
+ return 1;
+ }
+
+ if (ioctl(rtc_fd, RTC_VL_CLR) == -1) {
+ warn(_("ioctl(%d, RTC_VL_CLEAR) on %s failed"),
+ rtc_fd, rtc_dev_name);
+ return 1;
+ }
+
+ if (ctl->verbose)
+ printf(_("ioctl(%d, RTC_VL_CLEAR) on %s succeeded.\n"),
+ rtc_fd, rtc_dev_name);
+
+ return 0;
+}
diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
index 2a1844309..b043646b3 100644
--- a/sys-utils/hwclock.c
+++ b/sys-utils/hwclock.c
@@ -1180,6 +1180,20 @@ manipulate_rtc_param(const struct hwclock_control *ctl)
return 1;
}
+
+static int
+manipulate_rtc_voltage_low(const struct hwclock_control *ctl)
+{
+ if (ctl->vl_read) {
+ if (rtc_vl_read(ctl))
+ return 1;
+ }
+ if (ctl->vl_clear) {
+ if (rtc_vl_clear(ctl))
+ return 1;
+ }
+ return 0;
+}
#endif
static void out_version(void)
@@ -1215,6 +1229,8 @@ usage(void)
#ifdef __linux__
puts(_(" --param-get <param> display the RTC parameter"));
puts(_(" --param-set <param>=<value> set the RTC parameter"));
+ puts(_(" --vl-read read voltage low information"));
+ puts(_(" --vl-clear clear voltage low information"));
#endif
puts(_(" --predict predict the drifted RTC time according to --date"));
fputs(USAGE_OPTIONS, stdout);
@@ -1286,6 +1302,8 @@ int main(int argc, char **argv)
OPT_NOADJFILE,
OPT_PARAM_GET,
OPT_PARAM_SET,
+ OPT_VL_READ,
+ OPT_VL_CLEAR,
OPT_PREDICT,
OPT_SET,
OPT_SETEPOCH,
@@ -1315,6 +1333,8 @@ int main(int argc, char **argv)
#ifdef __linux__
{ "param-get", required_argument, NULL, OPT_PARAM_GET },
{ "param-set", required_argument, NULL, OPT_PARAM_SET },
+ { "vl-read", no_argument, NULL, OPT_VL_READ },
+ { "vl-clear", no_argument, NULL, OPT_VL_CLEAR },
#endif
{ "noadjfile", no_argument, NULL, OPT_NOADJFILE },
{ "directisa", no_argument, NULL, OPT_DIRECTISA },
@@ -1439,6 +1459,14 @@ int main(int argc, char **argv)
ctl.show = 0;
ctl.hwaudit_on = 1;
break;
+ case OPT_VL_READ:
+ ctl.vl_read = 1;
+ ctl.show = 0;
+ break;
+ case OPT_VL_CLEAR:
+ ctl.vl_clear = 1;
+ ctl.show = 0;
+ break;
#endif
case OPT_NOADJFILE:
ctl.noadjfile = 1;
@@ -1540,6 +1568,13 @@ int main(int argc, char **argv)
hwclock_exit(&ctl, EXIT_SUCCESS);
}
+
+ if (ctl.vl_read || ctl.vl_clear) {
+ if (manipulate_rtc_voltage_low(&ctl))
+ hwclock_exit(&ctl, EXIT_FAILURE);
+
+ hwclock_exit(&ctl, EXIT_SUCCESS);
+ }
#endif
#if defined(__linux__) && defined(__alpha__)
diff --git a/sys-utils/hwclock.h b/sys-utils/hwclock.h
index b5b72d45d..a690e717b 100644
--- a/sys-utils/hwclock.h
+++ b/sys-utils/hwclock.h
@@ -53,6 +53,8 @@ struct hwclock_control {
set:1,
update:1,
universal:1, /* will store hw_clock_is_utc() return value */
+ vl_read:1,
+ vl_clear:1,
verbose:1;
};
@@ -88,6 +90,9 @@ extern int get_param_rtc(const struct hwclock_control *ctl,
const char *name, uint64_t *id, uint64_t *value);
extern int set_param_rtc(const struct hwclock_control *ctl, const char *name);
+extern int rtc_vl_read(const struct hwclock_control *ctl);
+extern int rtc_vl_clear(const struct hwclock_control *ctl);
+
extern void __attribute__((__noreturn__))
hwclock_exit(const struct hwclock_control *ctl, int status);
--
2.37.2
next reply other threads:[~2023-06-13 10:15 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-13 10:14 Rasmus Villemoes [this message]
2023-06-20 9:26 ` [PATCH] hwclock: add support for RTC_VL_READ/RTC_VL_CLR ioctls Karel Zak
2023-06-20 9:30 ` Rasmus Villemoes
2023-06-20 10:22 ` Karel Zak
2023-06-20 11:22 ` Rasmus Villemoes
2023-06-21 20:18 ` [PATCH] hwclock: add --vl-read, --vl-clear documentation and bash-completion Rasmus Villemoes
2023-06-22 8:29 ` [PATCH] hwclock: add support for RTC_VL_READ/RTC_VL_CLR ioctls Karel Zak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230613101428.294827-1-rasmus.villemoes@prevas.dk \
--to=rasmus.villemoes@prevas.dk \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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 read-only IMAP folder(s) and NNTP newsgroup(s).