diff options
author | Alexandre Belloni | 2021-10-18 17:19:28 +0200 |
---|---|---|
committer | Alexandre Belloni | 2021-10-18 17:20:50 +0200 |
commit | 6a8af1b6568ad9ee08a419fb12c793f7992cf8a4 (patch) | |
tree | 8f7a1b3a7ea936632a35a49dc4be6f5b02e523db /drivers/rtc | |
parent | 917425f71f36ce6f61841497040e10d0166106d8 (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.c | 40 |
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(¶m, 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, ¶m, sizeof(param))) + err = -EFAULT; + + break; + + case RTC_PARAM_SET: + if (copy_from_user(¶m, 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) { |