diff options
Diffstat (limited to 'drivers/ptp/ptp_private.h')
| -rw-r--r-- | drivers/ptp/ptp_private.h | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 75f58fc468a7..db4039d642b4 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -15,16 +15,30 @@ #include <linux/ptp_clock.h> #include <linux/ptp_clock_kernel.h> #include <linux/time.h> +#include <linux/list.h> +#include <linux/bitmap.h> +#include <linux/debugfs.h> #define PTP_MAX_TIMESTAMPS 128 #define PTP_BUF_TIMESTAMPS 30 #define PTP_DEFAULT_MAX_VCLOCKS 20 +#define PTP_MAX_VCLOCKS_LIMIT (KMALLOC_MAX_SIZE/(sizeof(int))) +#define PTP_MAX_CHANNELS 2048 + +enum { + PTP_LOCK_PHYSICAL = 0, + PTP_LOCK_VIRTUAL, +}; struct timestamp_event_queue { struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS]; int head; int tail; spinlock_t lock; + struct list_head qlist; + unsigned long *mask; + struct dentry *debugfs_instance; + struct debugfs_u32_array dfs_bitmap; }; struct ptp_clock { @@ -35,8 +49,8 @@ struct ptp_clock { int index; /* index into clocks.map */ struct pps_device *pps_source; long dialed_frequency; /* remembers the frequency adjustment */ - struct timestamp_event_queue tsevq; /* simple fifo for time stamps */ - struct mutex tsevq_mux; /* one process at a time reading the fifo */ + struct list_head tsevqs; /* timestamp fifo list */ + spinlock_t tsevqs_lock; /* protects tsevqs from concurrent access */ struct mutex pincfg_mux; /* protect concurrent info->pin_config access */ wait_queue_head_t tsev_wq; int defunct; /* tells readers to go away when clock is being removed */ @@ -53,6 +67,7 @@ struct ptp_clock { struct mutex n_vclocks_mux; /* protect concurrent n_vclocks access */ bool is_virtual_clock; bool has_cycles; + struct dentry *debugfs_root; }; #define info_to_vclock(d) container_of((d), struct ptp_vclock, info) @@ -76,9 +91,13 @@ struct ptp_vclock { * that a writer might concurrently increment the tail does not * matter, since the queue remains nonempty nonetheless. */ -static inline int queue_cnt(struct timestamp_event_queue *q) +static inline int queue_cnt(const struct timestamp_event_queue *q) { - int cnt = q->tail - q->head; + /* + * Paired with WRITE_ONCE() in enqueue_external_timestamp(), + * ptp_read(), extts_fifo_show(). + */ + int cnt = READ_ONCE(q->tail) - READ_ONCE(q->head); return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; } @@ -87,10 +106,20 @@ static inline bool ptp_vclock_in_use(struct ptp_clock *ptp) { bool in_use = false; + /* Virtual clocks can't be stacked on top of virtual clocks. + * Avoid acquiring the n_vclocks_mux on virtual clocks, to allow this + * function to be called from code paths where the n_vclocks_mux of the + * parent physical clock is already held. Functionally that's not an + * issue, but lockdep would complain, because they have the same lock + * class. + */ + if (ptp->is_virtual_clock) + return false; + if (mutex_lock_interruptible(&ptp->n_vclocks_mux)) return true; - if (!ptp->is_virtual_clock && ptp->n_vclocks) + if (ptp->n_vclocks) in_use = true; mutex_unlock(&ptp->n_vclocks_mux); @@ -107,26 +136,30 @@ static inline bool ptp_clock_freerun(struct ptp_clock *ptp) return ptp_vclock_in_use(ptp); } -extern struct class *ptp_class; +extern const struct class ptp_class; /* * see ptp_chardev.c */ +void ptp_disable_all_events(struct ptp_clock *ptp); + /* caller must hold pincfg_mux */ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan); -long ptp_ioctl(struct posix_clock *pc, - unsigned int cmd, unsigned long arg); +long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, + unsigned long arg); + +int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode); -int ptp_open(struct posix_clock *pc, fmode_t fmode); +int ptp_release(struct posix_clock_context *pccontext); -ssize_t ptp_read(struct posix_clock *pc, - uint flags, char __user *buf, size_t cnt); +ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf, + size_t cnt); -__poll_t ptp_poll(struct posix_clock *pc, - struct file *fp, poll_table *wait); +__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp, + poll_table *wait); /* * see ptp_sysfs.c |
