1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * posix-clock.h - support for dynamic clock devices 4 * 5 * Copyright (C) 2010 OMICRON electronics GmbH 6 */ 7 #ifndef _LINUX_POSIX_CLOCK_H_ 8 #define _LINUX_POSIX_CLOCK_H_ 9 10 #include <linux/cdev.h> 11 #include <linux/fs.h> 12 #include <linux/poll.h> 13 #include <linux/posix-timers.h> 14 #include <linux/rwsem.h> 15 16 struct posix_clock; 17 18 /** 19 * struct posix_clock_operations - functional interface to the clock 20 * 21 * Every posix clock is represented by a character device. Drivers may 22 * optionally offer extended capabilities by implementing the 23 * character device methods. The character device file operations are 24 * first handled by the clock device layer, then passed on to the 25 * driver by calling these functions. 26 * 27 * @owner: The clock driver should set to THIS_MODULE 28 * @clock_adjtime: Adjust the clock 29 * @clock_gettime: Read the current time 30 * @clock_getres: Get the clock resolution 31 * @clock_settime: Set the current time value 32 * @open: Optional character device open method 33 * @release: Optional character device release method 34 * @ioctl: Optional character device ioctl method 35 * @read: Optional character device read method 36 * @poll: Optional character device poll method 37 */ 38 struct posix_clock_operations { 39 struct module *owner; 40 41 int (*clock_adjtime)(struct posix_clock *pc, struct __kernel_timex *tx); 42 43 int (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts); 44 45 int (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts); 46 47 int (*clock_settime)(struct posix_clock *pc, 48 const struct timespec64 *ts); 49 50 /* 51 * Optional character device methods: 52 */ 53 long (*ioctl) (struct posix_clock *pc, 54 unsigned int cmd, unsigned long arg); 55 56 int (*open) (struct posix_clock *pc, fmode_t f_mode); 57 58 __poll_t (*poll) (struct posix_clock *pc, 59 struct file *file, poll_table *wait); 60 61 int (*release) (struct posix_clock *pc); 62 63 ssize_t (*read) (struct posix_clock *pc, 64 uint flags, char __user *buf, size_t cnt); 65 }; 66 67 /** 68 * struct posix_clock - represents a dynamic posix clock 69 * 70 * @ops: Functional interface to the clock 71 * @cdev: Character device instance for this clock 72 * @kref: Reference count. 73 * @rwsem: Protects the 'zombie' field from concurrent access. 74 * @zombie: If 'zombie' is true, then the hardware has disappeared. 75 * @release: A function to free the structure when the reference count reaches 76 * zero. May be NULL if structure is statically allocated. 77 * 78 * Drivers should embed their struct posix_clock within a private 79 * structure, obtaining a reference to it during callbacks using 80 * container_of(). 81 */ 82 struct posix_clock { 83 struct posix_clock_operations ops; 84 struct cdev cdev; 85 struct kref kref; 86 struct rw_semaphore rwsem; 87 bool zombie; 88 void (*release)(struct posix_clock *clk); 89 }; 90 91 /** 92 * posix_clock_register() - register a new clock 93 * @clk: Pointer to the clock. Caller must provide 'ops' and 'release' 94 * @devid: Allocated device id 95 * 96 * A clock driver calls this function to register itself with the 97 * clock device subsystem. If 'clk' points to dynamically allocated 98 * memory, then the caller must provide a 'release' function to free 99 * that memory. 100 * 101 * Returns zero on success, non-zero otherwise. 102 */ 103 int posix_clock_register(struct posix_clock *clk, dev_t devid); 104 105 /** 106 * posix_clock_unregister() - unregister a clock 107 * @clk: Clock instance previously registered via posix_clock_register() 108 * 109 * A clock driver calls this function to remove itself from the clock 110 * device subsystem. The posix_clock itself will remain (in an 111 * inactive state) until its reference count drops to zero, at which 112 * point it will be deallocated with its 'release' method. 113 */ 114 void posix_clock_unregister(struct posix_clock *clk); 115 116 #endif 117