aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAlexandre Belloni2021-10-18 17:19:28 +0200
committerAlexandre Belloni2021-10-18 17:20:50 +0200
commit6a8af1b6568ad9ee08a419fb12c793f7992cf8a4 (patch)
tree8f7a1b3a7ea936632a35a49dc4be6f5b02e523db /drivers/rtc
parent917425f71f36ce6f61841497040e10d0166106d8 (diff)
rtc: add parameter ioctl
Add an ioctl allowing to get and set extra parameters for an RTC. For now, only handle getting available features. Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Link: https://lore.kernel.org/r/20211018151933.76865-3-alexandre.belloni@bootlin.com
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/dev.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c
index 5b8ebe86124a..143c097eff0f 100644
--- a/drivers/rtc/dev.c
+++ b/drivers/rtc/dev.c
@@ -208,6 +208,7 @@ static long rtc_dev_ioctl(struct file *file,
const struct rtc_class_ops *ops = rtc->ops;
struct rtc_time tm;
struct rtc_wkalrm alarm;
+ struct rtc_param param;
void __user *uarg = (void __user *)arg;
err = mutex_lock_interruptible(&rtc->ops_lock);
@@ -221,6 +222,7 @@ static long rtc_dev_ioctl(struct file *file,
switch (cmd) {
case RTC_EPOCH_SET:
case RTC_SET_TIME:
+ case RTC_PARAM_SET:
if (!capable(CAP_SYS_TIME))
err = -EACCES;
break;
@@ -382,6 +384,44 @@ static long rtc_dev_ioctl(struct file *file,
err = -EFAULT;
return err;
+ case RTC_PARAM_GET:
+ if (copy_from_user(&param, uarg, sizeof(param))) {
+ mutex_unlock(&rtc->ops_lock);
+ return -EFAULT;
+ }
+
+ switch(param.param) {
+ long offset;
+ case RTC_PARAM_FEATURES:
+ if (param.index != 0)
+ err = -EINVAL;
+ param.uvalue = rtc->features[0];
+ break;
+
+ default:
+ err = -EINVAL;
+ }
+
+ if (!err)
+ if (copy_to_user(uarg, &param, sizeof(param)))
+ err = -EFAULT;
+
+ break;
+
+ case RTC_PARAM_SET:
+ if (copy_from_user(&param, uarg, sizeof(param))) {
+ mutex_unlock(&rtc->ops_lock);
+ return -EFAULT;
+ }
+
+ switch(param.param) {
+ case RTC_PARAM_FEATURES:
+ default:
+ err = -EINVAL;
+ }
+
+ break;
+
default:
/* Finally try the driver's ioctl interface */
if (ops->ioctl) {