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 struct posix_clock_context; 18 19 /** 20 * struct posix_clock_operations - functional interface to the clock 21 * 22 * Every posix clock is represented by a character device. Drivers may 23 * optionally offer extended capabilities by implementing the 24 * character device methods. The character device file operations are 25 * first handled by the clock device layer, then passed on to the 26 * driver by calling these functions. 27 * 28 * @owner: The clock driver should set to THIS_MODULE 29 * @clock_adjtime: Adjust the clock 30 * @clock_gettime: Read the current time 31 * @clock_getres: Get the clock resolution 32 * @clock_settime: Set the current time value 33 * @open: Optional character device open method 34 * @release: Optional character device release method 35 * @ioctl: Optional character device ioctl method 36 * @read: Optional character device read method 37 * @poll: Optional character device poll method 38 */ 39 struct posix_clock_operations { 40 struct module *owner; 41 42 int (*clock_adjtime)(struct posix_clock *pc, struct __kernel_timex *tx); 43 44 int (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts); 45 46 int (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts); 47 48 int (*clock_settime)(struct posix_clock *pc, 49 const struct timespec64 *ts); 50 51 /* 52 * Optional character device methods: 53 */ 54 long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd, 55 unsigned long arg); 56 57 int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode); 58 59 __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file, 60 poll_table *wait); 61 62 int (*release)(struct posix_clock_context *pccontext); 63 64 ssize_t (*read)(struct posix_clock_context *pccontext, uint flags, 65 char __user *buf, size_t cnt); 66 }; 67 68 /** 69 * struct posix_clock - represents a dynamic posix clock 70 * 71 * @ops: Functional interface to the clock 72 * @cdev: Character device instance for this clock 73 * @dev: Pointer to the clock's device. 74 * @rwsem: Protects the 'zombie' field from concurrent access. 75 * @zombie: If 'zombie' is true, then the hardware has disappeared. 76 * 77 * Drivers should embed their struct posix_clock within a private 78 * structure, obtaining a reference to it during callbacks using 79 * container_of(). 80 * 81 * Drivers should supply an initialized but not exposed struct device 82 * to posix_clock_register(). It is used to manage lifetime of the 83 * driver's private structure. It's 'release' field should be set to 84 * a release function for this private structure. 85 */ 86 struct posix_clock { 87 struct posix_clock_operations ops; 88 struct cdev cdev; 89 struct device *dev; 90 struct rw_semaphore rwsem; 91 bool zombie; 92 }; 93 94 /** 95 * struct posix_clock_context - represents clock file operations context 96 * 97 * @clk: Pointer to the clock 98 * @private_clkdata: Pointer to user data 99 * 100 * Drivers should use struct posix_clock_context during specific character 101 * device file operation methods to access the posix clock. 102 * 103 * Drivers can store a private data structure during the open operation 104 * if they have specific information that is required in other file 105 * operations. 106 */ 107 struct posix_clock_context { 108 struct posix_clock *clk; 109 void *private_clkdata; 110 }; 111 112 /** 113 * posix_clock_register() - register a new clock 114 * @clk: Pointer to the clock. Caller must provide 'ops' field 115 * @dev: Pointer to the initialized device. Caller must provide 116 * 'release' field 117 * 118 * A clock driver calls this function to register itself with the 119 * clock device subsystem. If 'clk' points to dynamically allocated 120 * memory, then the caller must provide a 'release' function to free 121 * that memory. 122 * 123 * Returns zero on success, non-zero otherwise. 124 */ 125 int posix_clock_register(struct posix_clock *clk, struct device *dev); 126 127 /** 128 * posix_clock_unregister() - unregister a clock 129 * @clk: Clock instance previously registered via posix_clock_register() 130 * 131 * A clock driver calls this function to remove itself from the clock 132 * device subsystem. The posix_clock itself will remain (in an 133 * inactive state) until its reference count drops to zero, at which 134 * point it will be deallocated with its 'release' method. 135 */ 136 void posix_clock_unregister(struct posix_clock *clk); 137 138 #endif 139