summaryrefslogtreecommitdiff
path: root/drivers/ptp/ptp_chardev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ptp/ptp_chardev.c')
-rw-r--r--drivers/ptp/ptp_chardev.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index abe94bb80cf6..ac2f2b5ea0b7 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -110,6 +110,12 @@ int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
queue = kzalloc(sizeof(*queue), GFP_KERNEL);
if (!queue)
return -EINVAL;
+ queue->mask = bitmap_alloc(PTP_MAX_CHANNELS, GFP_KERNEL);
+ if (!queue->mask) {
+ kfree(queue);
+ return -EINVAL;
+ }
+ bitmap_set(queue->mask, 0, PTP_MAX_CHANNELS);
spin_lock_init(&queue->lock);
list_add_tail(&queue->qlist, &ptp->tsevqs);
pccontext->private_clkdata = queue;
@@ -126,6 +132,7 @@ int ptp_release(struct posix_clock_context *pccontext)
spin_lock_irqsave(&queue->lock, flags);
list_del(&queue->qlist);
spin_unlock_irqrestore(&queue->lock, flags);
+ bitmap_free(queue->mask);
kfree(queue);
}
return 0;
@@ -141,6 +148,7 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
struct system_device_crosststamp xtstamp;
struct ptp_clock_info *ops = ptp->info;
struct ptp_sys_offset *sysoff = NULL;
+ struct timestamp_event_queue *tsevq;
struct ptp_system_timestamp sts;
struct ptp_clock_request req;
struct ptp_clock_caps caps;
@@ -150,6 +158,8 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
struct timespec64 ts;
int enable, err = 0;
+ tsevq = pccontext->private_clkdata;
+
switch (cmd) {
case PTP_CLOCK_GETCAPS:
@@ -448,6 +458,22 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
mutex_unlock(&ptp->pincfg_mux);
break;
+ case PTP_MASK_CLEAR_ALL:
+ bitmap_clear(tsevq->mask, 0, PTP_MAX_CHANNELS);
+ break;
+
+ case PTP_MASK_EN_SINGLE:
+ if (copy_from_user(&i, (void __user *)arg, sizeof(i))) {
+ err = -EFAULT;
+ break;
+ }
+ if (i >= PTP_MAX_CHANNELS) {
+ err = -EFAULT;
+ break;
+ }
+ set_bit(i, tsevq->mask);
+ break;
+
default:
err = -ENOTTY;
break;