xref: /linux-6.15/include/linux/posix-clock.h (revision e859d375)
174ba9207SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
20606f422SRichard Cochran /*
30606f422SRichard Cochran  * posix-clock.h - support for dynamic clock devices
40606f422SRichard Cochran  *
50606f422SRichard Cochran  * Copyright (C) 2010 OMICRON electronics GmbH
60606f422SRichard Cochran  */
70606f422SRichard Cochran #ifndef _LINUX_POSIX_CLOCK_H_
80606f422SRichard Cochran #define _LINUX_POSIX_CLOCK_H_
90606f422SRichard Cochran 
100606f422SRichard Cochran #include <linux/cdev.h>
110606f422SRichard Cochran #include <linux/fs.h>
120606f422SRichard Cochran #include <linux/poll.h>
130606f422SRichard Cochran #include <linux/posix-timers.h>
141791f881SRichard Cochran #include <linux/rwsem.h>
150606f422SRichard Cochran 
160606f422SRichard Cochran struct posix_clock;
1760c69466SXabier Marquiegui struct posix_clock_context;
180606f422SRichard Cochran 
190606f422SRichard Cochran /**
200606f422SRichard Cochran  * struct posix_clock_operations - functional interface to the clock
210606f422SRichard Cochran  *
220606f422SRichard Cochran  * Every posix clock is represented by a character device. Drivers may
230606f422SRichard Cochran  * optionally offer extended capabilities by implementing the
240606f422SRichard Cochran  * character device methods. The character device file operations are
250606f422SRichard Cochran  * first handled by the clock device layer, then passed on to the
260606f422SRichard Cochran  * driver by calling these functions.
270606f422SRichard Cochran  *
280606f422SRichard Cochran  * @owner:          The clock driver should set to THIS_MODULE
290606f422SRichard Cochran  * @clock_adjtime:  Adjust the clock
300606f422SRichard Cochran  * @clock_gettime:  Read the current time
310606f422SRichard Cochran  * @clock_getres:   Get the clock resolution
320606f422SRichard Cochran  * @clock_settime:  Set the current time value
330606f422SRichard Cochran  * @open:           Optional character device open method
340606f422SRichard Cochran  * @release:        Optional character device release method
350606f422SRichard Cochran  * @ioctl:          Optional character device ioctl method
360606f422SRichard Cochran  * @read:           Optional character device read method
370606f422SRichard Cochran  * @poll:           Optional character device poll method
380606f422SRichard Cochran  */
390606f422SRichard Cochran struct posix_clock_operations {
400606f422SRichard Cochran 	struct module *owner;
410606f422SRichard Cochran 
42ead25417SDeepa Dinamani 	int  (*clock_adjtime)(struct posix_clock *pc, struct __kernel_timex *tx);
430606f422SRichard Cochran 
44d340266eSDeepa Dinamani 	int  (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
450606f422SRichard Cochran 
46d340266eSDeepa Dinamani 	int  (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts);
470606f422SRichard Cochran 
480606f422SRichard Cochran 	int  (*clock_settime)(struct posix_clock *pc,
49d340266eSDeepa Dinamani 			      const struct timespec64 *ts);
500606f422SRichard Cochran 
510606f422SRichard Cochran 	/*
520606f422SRichard Cochran 	 * Optional character device methods:
530606f422SRichard Cochran 	 */
5460c69466SXabier Marquiegui 	long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
5560c69466SXabier Marquiegui 		      unsigned long arg);
560606f422SRichard Cochran 
5760c69466SXabier Marquiegui 	int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
580606f422SRichard Cochran 
5960c69466SXabier Marquiegui 	__poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
6060c69466SXabier Marquiegui 			 poll_table *wait);
610606f422SRichard Cochran 
6260c69466SXabier Marquiegui 	int (*release)(struct posix_clock_context *pccontext);
630606f422SRichard Cochran 
6460c69466SXabier Marquiegui 	ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
6560c69466SXabier Marquiegui 			char __user *buf, size_t cnt);
660606f422SRichard Cochran };
670606f422SRichard Cochran 
680606f422SRichard Cochran /**
690606f422SRichard Cochran  * struct posix_clock - represents a dynamic posix clock
700606f422SRichard Cochran  *
710606f422SRichard Cochran  * @ops:     Functional interface to the clock
720606f422SRichard Cochran  * @cdev:    Character device instance for this clock
73a33121e5SVladis Dronov  * @dev:     Pointer to the clock's device.
741791f881SRichard Cochran  * @rwsem:   Protects the 'zombie' field from concurrent access.
750606f422SRichard Cochran  * @zombie:  If 'zombie' is true, then the hardware has disappeared.
760606f422SRichard Cochran  *
770606f422SRichard Cochran  * Drivers should embed their struct posix_clock within a private
780606f422SRichard Cochran  * structure, obtaining a reference to it during callbacks using
790606f422SRichard Cochran  * container_of().
80a33121e5SVladis Dronov  *
81a33121e5SVladis Dronov  * Drivers should supply an initialized but not exposed struct device
82a33121e5SVladis Dronov  * to posix_clock_register(). It is used to manage lifetime of the
83a33121e5SVladis Dronov  * driver's private structure. It's 'release' field should be set to
84a33121e5SVladis Dronov  * a release function for this private structure.
850606f422SRichard Cochran  */
860606f422SRichard Cochran struct posix_clock {
870606f422SRichard Cochran 	struct posix_clock_operations ops;
880606f422SRichard Cochran 	struct cdev cdev;
89a33121e5SVladis Dronov 	struct device *dev;
901791f881SRichard Cochran 	struct rw_semaphore rwsem;
910606f422SRichard Cochran 	bool zombie;
920606f422SRichard Cochran };
930606f422SRichard Cochran 
940606f422SRichard Cochran /**
9560c69466SXabier Marquiegui  * struct posix_clock_context - represents clock file operations context
9660c69466SXabier Marquiegui  *
9760c69466SXabier Marquiegui  * @clk:              Pointer to the clock
98*e859d375SWojtek Wasko  * @fp:               Pointer to the file used to open the clock
9960c69466SXabier Marquiegui  * @private_clkdata:  Pointer to user data
10060c69466SXabier Marquiegui  *
10160c69466SXabier Marquiegui  * Drivers should use struct posix_clock_context during specific character
102*e859d375SWojtek Wasko  * device file operation methods to access the posix clock. In particular,
103*e859d375SWojtek Wasko  * the file pointer can be used to verify correct access mode for ioctl()
104*e859d375SWojtek Wasko  * calls.
10560c69466SXabier Marquiegui  *
10660c69466SXabier Marquiegui  * Drivers can store a private data structure during the open operation
10760c69466SXabier Marquiegui  * if they have specific information that is required in other file
10860c69466SXabier Marquiegui  * operations.
10960c69466SXabier Marquiegui  */
11060c69466SXabier Marquiegui struct posix_clock_context {
11160c69466SXabier Marquiegui 	struct posix_clock *clk;
112*e859d375SWojtek Wasko 	struct file *fp;
11360c69466SXabier Marquiegui 	void *private_clkdata;
11460c69466SXabier Marquiegui };
11560c69466SXabier Marquiegui 
11660c69466SXabier Marquiegui /**
1170606f422SRichard Cochran  * posix_clock_register() - register a new clock
118a33121e5SVladis Dronov  * @clk:   Pointer to the clock. Caller must provide 'ops' field
119a33121e5SVladis Dronov  * @dev:   Pointer to the initialized device. Caller must provide
120a33121e5SVladis Dronov  *         'release' field
1210606f422SRichard Cochran  *
1220606f422SRichard Cochran  * A clock driver calls this function to register itself with the
1230606f422SRichard Cochran  * clock device subsystem. If 'clk' points to dynamically allocated
1240606f422SRichard Cochran  * memory, then the caller must provide a 'release' function to free
1250606f422SRichard Cochran  * that memory.
1260606f422SRichard Cochran  *
1270606f422SRichard Cochran  * Returns zero on success, non-zero otherwise.
1280606f422SRichard Cochran  */
129a33121e5SVladis Dronov int posix_clock_register(struct posix_clock *clk, struct device *dev);
1300606f422SRichard Cochran 
1310606f422SRichard Cochran /**
1320606f422SRichard Cochran  * posix_clock_unregister() - unregister a clock
1330606f422SRichard Cochran  * @clk: Clock instance previously registered via posix_clock_register()
1340606f422SRichard Cochran  *
1350606f422SRichard Cochran  * A clock driver calls this function to remove itself from the clock
1360606f422SRichard Cochran  * device subsystem. The posix_clock itself will remain (in an
1370606f422SRichard Cochran  * inactive state) until its reference count drops to zero, at which
1380606f422SRichard Cochran  * point it will be deallocated with its 'release' method.
1390606f422SRichard Cochran  */
1400606f422SRichard Cochran void posix_clock_unregister(struct posix_clock *clk);
1410606f422SRichard Cochran 
1420606f422SRichard Cochran #endif
143