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 * @dev: Pointer to the clock's device. 73 * @rwsem: Protects the 'zombie' field from concurrent access. 74 * @zombie: If 'zombie' is true, then the hardware has disappeared. 75 * 76 * Drivers should embed their struct posix_clock within a private 77 * structure, obtaining a reference to it during callbacks using 78 * container_of(). 79 * 80 * Drivers should supply an initialized but not exposed struct device 81 * to posix_clock_register(). It is used to manage lifetime of the 82 * driver's private structure. It's 'release' field should be set to 83 * a release function for this private structure. 84 */ 85 struct posix_clock { 86 struct posix_clock_operations ops; 87 struct cdev cdev; 88 struct device *dev; 89 struct rw_semaphore rwsem; 90 bool zombie; 91 }; 92 93 /** 94 * posix_clock_register() - register a new clock 95 * @clk: Pointer to the clock. Caller must provide 'ops' field 96 * @dev: Pointer to the initialized device. Caller must provide 97 * 'release' field 98 * 99 * A clock driver calls this function to register itself with the 100 * clock device subsystem. If 'clk' points to dynamically allocated 101 * memory, then the caller must provide a 'release' function to free 102 * that memory. 103 * 104 * Returns zero on success, non-zero otherwise. 105 */ 106 int posix_clock_register(struct posix_clock *clk, struct device *dev); 107 108 /** 109 * posix_clock_unregister() - unregister a clock 110 * @clk: Clock instance previously registered via posix_clock_register() 111 * 112 * A clock driver calls this function to remove itself from the clock 113 * device subsystem. The posix_clock itself will remain (in an 114 * inactive state) until its reference count drops to zero, at which 115 * point it will be deallocated with its 'release' method. 116 */ 117 void posix_clock_unregister(struct posix_clock *clk); 118 119 #endif 120