18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * PTP 1588 clock support - private declarations for the core module. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2010 OMICRON electronics GmbH 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef _PTP_PRIVATE_H_ 88c2ecf20Sopenharmony_ci#define _PTP_PRIVATE_H_ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/cdev.h> 118c2ecf20Sopenharmony_ci#include <linux/device.h> 128c2ecf20Sopenharmony_ci#include <linux/kthread.h> 138c2ecf20Sopenharmony_ci#include <linux/mutex.h> 148c2ecf20Sopenharmony_ci#include <linux/posix-clock.h> 158c2ecf20Sopenharmony_ci#include <linux/ptp_clock.h> 168c2ecf20Sopenharmony_ci#include <linux/ptp_clock_kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/time.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define PTP_MAX_TIMESTAMPS 128 208c2ecf20Sopenharmony_ci#define PTP_BUF_TIMESTAMPS 30 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct timestamp_event_queue { 238c2ecf20Sopenharmony_ci struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS]; 248c2ecf20Sopenharmony_ci int head; 258c2ecf20Sopenharmony_ci int tail; 268c2ecf20Sopenharmony_ci spinlock_t lock; 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistruct ptp_clock { 308c2ecf20Sopenharmony_ci struct posix_clock clock; 318c2ecf20Sopenharmony_ci struct device dev; 328c2ecf20Sopenharmony_ci struct ptp_clock_info *info; 338c2ecf20Sopenharmony_ci dev_t devid; 348c2ecf20Sopenharmony_ci int index; /* index into clocks.map */ 358c2ecf20Sopenharmony_ci struct pps_device *pps_source; 368c2ecf20Sopenharmony_ci long dialed_frequency; /* remembers the frequency adjustment */ 378c2ecf20Sopenharmony_ci struct timestamp_event_queue tsevq; /* simple fifo for time stamps */ 388c2ecf20Sopenharmony_ci struct mutex tsevq_mux; /* one process at a time reading the fifo */ 398c2ecf20Sopenharmony_ci struct mutex pincfg_mux; /* protect concurrent info->pin_config access */ 408c2ecf20Sopenharmony_ci wait_queue_head_t tsev_wq; 418c2ecf20Sopenharmony_ci int defunct; /* tells readers to go away when clock is being removed */ 428c2ecf20Sopenharmony_ci struct device_attribute *pin_dev_attr; 438c2ecf20Sopenharmony_ci struct attribute **pin_attr; 448c2ecf20Sopenharmony_ci struct attribute_group pin_attr_group; 458c2ecf20Sopenharmony_ci /* 1st entry is a pointer to the real group, 2nd is NULL terminator */ 468c2ecf20Sopenharmony_ci const struct attribute_group *pin_attr_groups[2]; 478c2ecf20Sopenharmony_ci struct kthread_worker *kworker; 488c2ecf20Sopenharmony_ci struct kthread_delayed_work aux_work; 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* 528c2ecf20Sopenharmony_ci * The function queue_cnt() is safe for readers to call without 538c2ecf20Sopenharmony_ci * holding q->lock. Readers use this function to verify that the queue 548c2ecf20Sopenharmony_ci * is nonempty before proceeding with a dequeue operation. The fact 558c2ecf20Sopenharmony_ci * that a writer might concurrently increment the tail does not 568c2ecf20Sopenharmony_ci * matter, since the queue remains nonempty nonetheless. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_cistatic inline int queue_cnt(const struct timestamp_event_queue *q) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci /* 618c2ecf20Sopenharmony_ci * Paired with WRITE_ONCE() in enqueue_external_timestamp(), 628c2ecf20Sopenharmony_ci * ptp_read(), extts_fifo_show(). 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci int cnt = READ_ONCE(q->tail) - READ_ONCE(q->head); 658c2ecf20Sopenharmony_ci return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * see ptp_chardev.c 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* caller must hold pincfg_mux */ 738c2ecf20Sopenharmony_ciint ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, 748c2ecf20Sopenharmony_ci enum ptp_pin_function func, unsigned int chan); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cilong ptp_ioctl(struct posix_clock *pc, 778c2ecf20Sopenharmony_ci unsigned int cmd, unsigned long arg); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ciint ptp_open(struct posix_clock *pc, fmode_t fmode); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cissize_t ptp_read(struct posix_clock *pc, 828c2ecf20Sopenharmony_ci uint flags, char __user *buf, size_t cnt); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci__poll_t ptp_poll(struct posix_clock *pc, 858c2ecf20Sopenharmony_ci struct file *fp, poll_table *wait); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* 888c2ecf20Sopenharmony_ci * see ptp_sysfs.c 898c2ecf20Sopenharmony_ci */ 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciextern const struct attribute_group *ptp_groups[]; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ciint ptp_populate_pin_groups(struct ptp_clock *ptp); 948c2ecf20Sopenharmony_civoid ptp_cleanup_pin_groups(struct ptp_clock *ptp); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#endif 97