aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2011-02-01 08:52:35 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-02 09:28:20 -0500
commit0606f422b453f76c31ab2b1bd52943ff06a2dcf2 (patch)
tree14f4859e8492f01e97140248a28ab98355c415cf /include
parent527087374faa488776a789375a7d6ea74fda6f71 (diff)
posix clocks: Introduce dynamic clocks
This patch adds support for adding and removing posix clocks. The clock lifetime cycle is patterned after usb devices. Each clock is represented by a standard character device. In addition, the driver may optionally implement custom character device operations. The posix clock and timer system calls listed below now work with dynamic posix clocks, as well as the traditional static clocks. The following system calls are affected: - clock_adjtime (brand new syscall) - clock_gettime - clock_getres - clock_settime - timer_create - timer_delete - timer_gettime - timer_settime [ tglx: Adapted to the posix-timer cleanup. Moved clock_posix_dynamic to posix-clock.c and made all referenced functions static ] Signed-off-by: Richard Cochran <richard.cochran@omicron.at> Acked-by: John Stultz <johnstul@us.ibm.com> LKML-Reference: <20110201134420.164172635@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/posix-clock.h150
-rw-r--r--include/linux/posix-timers.h6
2 files changed, 155 insertions, 1 deletions
diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
new file mode 100644
index 000000000000..369e19d3750b
--- /dev/null
+++ b/include/linux/posix-clock.h
@@ -0,0 +1,150 @@
1/*
2 * posix-clock.h - support for dynamic clock devices
3 *
4 * Copyright (C) 2010 OMICRON electronics GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#ifndef _LINUX_POSIX_CLOCK_H_
21#define _LINUX_POSIX_CLOCK_H_
22
23#include <linux/cdev.h>
24#include <linux/fs.h>
25#include <linux/poll.h>
26#include <linux/posix-timers.h>
27
28struct posix_clock;
29
30/**
31 * struct posix_clock_operations - functional interface to the clock
32 *
33 * Every posix clock is represented by a character device. Drivers may
34 * optionally offer extended capabilities by implementing the
35 * character device methods. The character device file operations are
36 * first handled by the clock device layer, then passed on to the
37 * driver by calling these functions.
38 *
39 * @owner: The clock driver should set to THIS_MODULE
40 * @clock_adjtime: Adjust the clock
41 * @clock_gettime: Read the current time
42 * @clock_getres: Get the clock resolution
43 * @clock_settime: Set the current time value
44 * @timer_create: Create a new timer
45 * @timer_delete: Remove a previously created timer
46 * @timer_gettime: Get remaining time and interval of a timer
47 * @timer_setttime: Set a timer's initial expiration and interval
48 * @fasync: Optional character device fasync method
49 * @mmap: Optional character device mmap method
50 * @open: Optional character device open method
51 * @release: Optional character device release method
52 * @ioctl: Optional character device ioctl method
53 * @read: Optional character device read method
54 * @poll: Optional character device poll method
55 */
56struct posix_clock_operations {
57 struct module *owner;
58
59 int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx);
60
61 int (*clock_gettime)(struct posix_clock *pc, struct timespec *ts);
62
63 int (*clock_getres) (struct posix_clock *pc, struct timespec *ts);
64
65 int (*clock_settime)(struct posix_clock *pc,
66 const struct timespec *ts);
67
68 int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
69
70 int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
71
72 void (*timer_gettime)(struct posix_clock *pc,
73 struct k_itimer *kit, struct itimerspec *tsp);
74
75 int (*timer_settime)(struct posix_clock *pc,
76 struct k_itimer *kit, int flags,
77 struct itimerspec *tsp, struct itimerspec *old);
78 /*
79 * Optional character device methods:
80 */
81 int (*fasync) (struct posix_clock *pc,
82 int fd, struct file *file, int on);
83
84 long (*ioctl) (struct posix_clock *pc,
85 unsigned int cmd, unsigned long arg);
86
87 int (*mmap) (struct posix_clock *pc,
88 struct vm_area_struct *vma);
89
90 int (*open) (struct posix_clock *pc, fmode_t f_mode);
91
92 uint (*poll) (struct posix_clock *pc,
93 struct file *file, poll_table *wait);
94
95 int (*release) (struct posix_clock *pc);
96
97 ssize_t (*read) (struct posix_clock *pc,
98 uint flags, char __user *buf, size_t cnt);
99};
100
101/**
102 * struct posix_clock - represents a dynamic posix clock
103 *
104 * @ops: Functional interface to the clock
105 * @cdev: Character device instance for this clock
106 * @kref: Reference count.
107 * @mutex: Protects the 'zombie' field from concurrent access.
108 * @zombie: If 'zombie' is true, then the hardware has disappeared.
109 * @release: A function to free the structure when the reference count reaches
110 * zero. May be NULL if structure is statically allocated.
111 *
112 * Drivers should embed their struct posix_clock within a private
113 * structure, obtaining a reference to it during callbacks using
114 * container_of().
115 */
116struct posix_clock {
117 struct posix_clock_operations ops;
118 struct cdev cdev;
119 struct kref kref;
120 struct mutex mutex;
121 bool zombie;
122 void (*release)(struct posix_clock *clk);
123};
124
125/**
126 * posix_clock_register() - register a new clock
127 * @clk: Pointer to the clock. Caller must provide 'ops' and 'release'
128 * @devid: Allocated device id
129 *
130 * A clock driver calls this function to register itself with the
131 * clock device subsystem. If 'clk' points to dynamically allocated
132 * memory, then the caller must provide a 'release' function to free
133 * that memory.
134 *
135 * Returns zero on success, non-zero otherwise.
136 */
137int posix_clock_register(struct posix_clock *clk, dev_t devid);
138
139/**
140 * posix_clock_unregister() - unregister a clock
141 * @clk: Clock instance previously registered via posix_clock_register()
142 *
143 * A clock driver calls this function to remove itself from the clock
144 * device subsystem. The posix_clock itself will remain (in an
145 * inactive state) until its reference count drops to zero, at which
146 * point it will be deallocated with its 'release' method.
147 */
148void posix_clock_unregister(struct posix_clock *clk);
149
150#endif
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 9d6ffe2c92e5..d51243ae0726 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -32,7 +32,7 @@ struct cpu_timer_list {
32#define CPUCLOCK_PID(clock) ((pid_t) ~((clock) >> 3)) 32#define CPUCLOCK_PID(clock) ((pid_t) ~((clock) >> 3))
33#define CPUCLOCK_PERTHREAD(clock) \ 33#define CPUCLOCK_PERTHREAD(clock) \
34 (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0) 34 (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
35#define CPUCLOCK_PID_MASK 7 35
36#define CPUCLOCK_PERTHREAD_MASK 4 36#define CPUCLOCK_PERTHREAD_MASK 4
37#define CPUCLOCK_WHICH(clock) ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK) 37#define CPUCLOCK_WHICH(clock) ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
38#define CPUCLOCK_CLOCK_MASK 3 38#define CPUCLOCK_CLOCK_MASK 3
@@ -48,6 +48,9 @@ struct cpu_timer_list {
48#define MAKE_THREAD_CPUCLOCK(tid, clock) \ 48#define MAKE_THREAD_CPUCLOCK(tid, clock) \
49 MAKE_PROCESS_CPUCLOCK((tid), (clock) | CPUCLOCK_PERTHREAD_MASK) 49 MAKE_PROCESS_CPUCLOCK((tid), (clock) | CPUCLOCK_PERTHREAD_MASK)
50 50
51#define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD)
52#define CLOCKID_TO_FD(clk) ((unsigned int) ~((clk) >> 3))
53
51/* POSIX.1b interval timer structure. */ 54/* POSIX.1b interval timer structure. */
52struct k_itimer { 55struct k_itimer {
53 struct list_head list; /* free/ allocate list */ 56 struct list_head list; /* free/ allocate list */
@@ -100,6 +103,7 @@ struct k_clock {
100}; 103};
101 104
102extern struct k_clock clock_posix_cpu; 105extern struct k_clock clock_posix_cpu;
106extern struct k_clock clock_posix_dynamic;
103 107
104void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock); 108void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock);
105 109