xref: /openbmc/linux/include/linux/posix-clock.h (revision a33121e5)
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;
170606f422SRichard Cochran 
180606f422SRichard Cochran /**
190606f422SRichard Cochran  * struct posix_clock_operations - functional interface to the clock
200606f422SRichard Cochran  *
210606f422SRichard Cochran  * Every posix clock is represented by a character device. Drivers may
220606f422SRichard Cochran  * optionally offer extended capabilities by implementing the
230606f422SRichard Cochran  * character device methods. The character device file operations are
240606f422SRichard Cochran  * first handled by the clock device layer, then passed on to the
250606f422SRichard Cochran  * driver by calling these functions.
260606f422SRichard Cochran  *
270606f422SRichard Cochran  * @owner:          The clock driver should set to THIS_MODULE
280606f422SRichard Cochran  * @clock_adjtime:  Adjust the clock
290606f422SRichard Cochran  * @clock_gettime:  Read the current time
300606f422SRichard Cochran  * @clock_getres:   Get the clock resolution
310606f422SRichard Cochran  * @clock_settime:  Set the current time value
320606f422SRichard Cochran  * @open:           Optional character device open method
330606f422SRichard Cochran  * @release:        Optional character device release method
340606f422SRichard Cochran  * @ioctl:          Optional character device ioctl method
350606f422SRichard Cochran  * @read:           Optional character device read method
360606f422SRichard Cochran  * @poll:           Optional character device poll method
370606f422SRichard Cochran  */
380606f422SRichard Cochran struct posix_clock_operations {
390606f422SRichard Cochran 	struct module *owner;
400606f422SRichard Cochran 
41ead25417SDeepa Dinamani 	int  (*clock_adjtime)(struct posix_clock *pc, struct __kernel_timex *tx);
420606f422SRichard Cochran 
43d340266eSDeepa Dinamani 	int  (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
440606f422SRichard Cochran 
45d340266eSDeepa Dinamani 	int  (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts);
460606f422SRichard Cochran 
470606f422SRichard Cochran 	int  (*clock_settime)(struct posix_clock *pc,
48d340266eSDeepa Dinamani 			      const struct timespec64 *ts);
490606f422SRichard Cochran 
500606f422SRichard Cochran 	/*
510606f422SRichard Cochran 	 * Optional character device methods:
520606f422SRichard Cochran 	 */
530606f422SRichard Cochran 	long    (*ioctl)   (struct posix_clock *pc,
540606f422SRichard Cochran 			    unsigned int cmd, unsigned long arg);
550606f422SRichard Cochran 
560606f422SRichard Cochran 	int     (*open)    (struct posix_clock *pc, fmode_t f_mode);
570606f422SRichard Cochran 
58a3f8683bSAl Viro 	__poll_t (*poll)   (struct posix_clock *pc,
590606f422SRichard Cochran 			    struct file *file, poll_table *wait);
600606f422SRichard Cochran 
610606f422SRichard Cochran 	int     (*release) (struct posix_clock *pc);
620606f422SRichard Cochran 
630606f422SRichard Cochran 	ssize_t (*read)    (struct posix_clock *pc,
640606f422SRichard Cochran 			    uint flags, char __user *buf, size_t cnt);
650606f422SRichard Cochran };
660606f422SRichard Cochran 
670606f422SRichard Cochran /**
680606f422SRichard Cochran  * struct posix_clock - represents a dynamic posix clock
690606f422SRichard Cochran  *
700606f422SRichard Cochran  * @ops:     Functional interface to the clock
710606f422SRichard Cochran  * @cdev:    Character device instance for this clock
72a33121e5SVladis Dronov  * @dev:     Pointer to the clock's device.
731791f881SRichard Cochran  * @rwsem:   Protects the 'zombie' field from concurrent access.
740606f422SRichard Cochran  * @zombie:  If 'zombie' is true, then the hardware has disappeared.
750606f422SRichard Cochran  *
760606f422SRichard Cochran  * Drivers should embed their struct posix_clock within a private
770606f422SRichard Cochran  * structure, obtaining a reference to it during callbacks using
780606f422SRichard Cochran  * container_of().
79a33121e5SVladis Dronov  *
80a33121e5SVladis Dronov  * Drivers should supply an initialized but not exposed struct device
81a33121e5SVladis Dronov  * to posix_clock_register(). It is used to manage lifetime of the
82a33121e5SVladis Dronov  * driver's private structure. It's 'release' field should be set to
83a33121e5SVladis Dronov  * a release function for this private structure.
840606f422SRichard Cochran  */
850606f422SRichard Cochran struct posix_clock {
860606f422SRichard Cochran 	struct posix_clock_operations ops;
870606f422SRichard Cochran 	struct cdev cdev;
88a33121e5SVladis Dronov 	struct device *dev;
891791f881SRichard Cochran 	struct rw_semaphore rwsem;
900606f422SRichard Cochran 	bool zombie;
910606f422SRichard Cochran };
920606f422SRichard Cochran 
930606f422SRichard Cochran /**
940606f422SRichard Cochran  * posix_clock_register() - register a new clock
95a33121e5SVladis Dronov  * @clk:   Pointer to the clock. Caller must provide 'ops' field
96a33121e5SVladis Dronov  * @dev:   Pointer to the initialized device. Caller must provide
97a33121e5SVladis Dronov  *         'release' field
980606f422SRichard Cochran  *
990606f422SRichard Cochran  * A clock driver calls this function to register itself with the
1000606f422SRichard Cochran  * clock device subsystem. If 'clk' points to dynamically allocated
1010606f422SRichard Cochran  * memory, then the caller must provide a 'release' function to free
1020606f422SRichard Cochran  * that memory.
1030606f422SRichard Cochran  *
1040606f422SRichard Cochran  * Returns zero on success, non-zero otherwise.
1050606f422SRichard Cochran  */
106a33121e5SVladis Dronov int posix_clock_register(struct posix_clock *clk, struct device *dev);
1070606f422SRichard Cochran 
1080606f422SRichard Cochran /**
1090606f422SRichard Cochran  * posix_clock_unregister() - unregister a clock
1100606f422SRichard Cochran  * @clk: Clock instance previously registered via posix_clock_register()
1110606f422SRichard Cochran  *
1120606f422SRichard Cochran  * A clock driver calls this function to remove itself from the clock
1130606f422SRichard Cochran  * device subsystem. The posix_clock itself will remain (in an
1140606f422SRichard Cochran  * inactive state) until its reference count drops to zero, at which
1150606f422SRichard Cochran  * point it will be deallocated with its 'release' method.
1160606f422SRichard Cochran  */
1170606f422SRichard Cochran void posix_clock_unregister(struct posix_clock *clk);
1180606f422SRichard Cochran 
1190606f422SRichard Cochran #endif
120