diff options
Diffstat (limited to 'include/linux/rtc.h')
-rw-r--r-- | include/linux/rtc.h | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 14dbc83ded20..b27ebea25660 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h | |||
@@ -92,10 +92,10 @@ struct rtc_pll_info { | |||
92 | #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ | 92 | #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ |
93 | 93 | ||
94 | /* interrupt flags */ | 94 | /* interrupt flags */ |
95 | #define RTC_IRQF 0x80 /* any of the following is active */ | 95 | #define RTC_IRQF 0x80 /* Any of the following is active */ |
96 | #define RTC_PF 0x40 | 96 | #define RTC_PF 0x40 /* Periodic interrupt */ |
97 | #define RTC_AF 0x20 | 97 | #define RTC_AF 0x20 /* Alarm interrupt */ |
98 | #define RTC_UF 0x10 | 98 | #define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ |
99 | 99 | ||
100 | #ifdef __KERNEL__ | 100 | #ifdef __KERNEL__ |
101 | 101 | ||
@@ -107,12 +107,17 @@ extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year | |||
107 | extern int rtc_valid_tm(struct rtc_time *tm); | 107 | extern int rtc_valid_tm(struct rtc_time *tm); |
108 | extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); | 108 | extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); |
109 | extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); | 109 | extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); |
110 | ktime_t rtc_tm_to_ktime(struct rtc_time tm); | ||
111 | struct rtc_time rtc_ktime_to_tm(ktime_t kt); | ||
112 | |||
110 | 113 | ||
111 | #include <linux/device.h> | 114 | #include <linux/device.h> |
112 | #include <linux/seq_file.h> | 115 | #include <linux/seq_file.h> |
113 | #include <linux/cdev.h> | 116 | #include <linux/cdev.h> |
114 | #include <linux/poll.h> | 117 | #include <linux/poll.h> |
115 | #include <linux/mutex.h> | 118 | #include <linux/mutex.h> |
119 | #include <linux/timerqueue.h> | ||
120 | #include <linux/workqueue.h> | ||
116 | 121 | ||
117 | extern struct class *rtc_class; | 122 | extern struct class *rtc_class; |
118 | 123 | ||
@@ -128,7 +133,6 @@ extern struct class *rtc_class; | |||
128 | * The (current) exceptions are mostly filesystem hooks: | 133 | * The (current) exceptions are mostly filesystem hooks: |
129 | * - the proc() hook for procfs | 134 | * - the proc() hook for procfs |
130 | * - non-ioctl() chardev hooks: open(), release(), read_callback() | 135 | * - non-ioctl() chardev hooks: open(), release(), read_callback() |
131 | * - periodic irq calls: irq_set_state(), irq_set_freq() | ||
132 | * | 136 | * |
133 | * REVISIT those periodic irq calls *do* have ops_lock when they're | 137 | * REVISIT those periodic irq calls *do* have ops_lock when they're |
134 | * issued through ioctl() ... | 138 | * issued through ioctl() ... |
@@ -143,15 +147,24 @@ struct rtc_class_ops { | |||
143 | int (*set_alarm)(struct device *, struct rtc_wkalrm *); | 147 | int (*set_alarm)(struct device *, struct rtc_wkalrm *); |
144 | int (*proc)(struct device *, struct seq_file *); | 148 | int (*proc)(struct device *, struct seq_file *); |
145 | int (*set_mmss)(struct device *, unsigned long secs); | 149 | int (*set_mmss)(struct device *, unsigned long secs); |
146 | int (*irq_set_state)(struct device *, int enabled); | ||
147 | int (*irq_set_freq)(struct device *, int freq); | ||
148 | int (*read_callback)(struct device *, int data); | 150 | int (*read_callback)(struct device *, int data); |
149 | int (*alarm_irq_enable)(struct device *, unsigned int enabled); | 151 | int (*alarm_irq_enable)(struct device *, unsigned int enabled); |
150 | int (*update_irq_enable)(struct device *, unsigned int enabled); | ||
151 | }; | 152 | }; |
152 | 153 | ||
153 | #define RTC_DEVICE_NAME_SIZE 20 | 154 | #define RTC_DEVICE_NAME_SIZE 20 |
154 | struct rtc_task; | 155 | typedef struct rtc_task { |
156 | void (*func)(void *private_data); | ||
157 | void *private_data; | ||
158 | } rtc_task_t; | ||
159 | |||
160 | |||
161 | struct rtc_timer { | ||
162 | struct rtc_task task; | ||
163 | struct timerqueue_node node; | ||
164 | ktime_t period; | ||
165 | int enabled; | ||
166 | }; | ||
167 | |||
155 | 168 | ||
156 | /* flags */ | 169 | /* flags */ |
157 | #define RTC_DEV_BUSY 0 | 170 | #define RTC_DEV_BUSY 0 |
@@ -179,6 +192,15 @@ struct rtc_device | |||
179 | spinlock_t irq_task_lock; | 192 | spinlock_t irq_task_lock; |
180 | int irq_freq; | 193 | int irq_freq; |
181 | int max_user_freq; | 194 | int max_user_freq; |
195 | |||
196 | struct timerqueue_head timerqueue; | ||
197 | struct rtc_timer aie_timer; | ||
198 | struct rtc_timer uie_rtctimer; | ||
199 | struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */ | ||
200 | int pie_enabled; | ||
201 | struct work_struct irqwork; | ||
202 | |||
203 | |||
182 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 204 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
183 | struct work_struct uie_task; | 205 | struct work_struct uie_task; |
184 | struct timer_list uie_timer; | 206 | struct timer_list uie_timer; |
@@ -201,10 +223,13 @@ extern void rtc_device_unregister(struct rtc_device *rtc); | |||
201 | extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); | 223 | extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); |
202 | extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); | 224 | extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); |
203 | extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs); | 225 | extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs); |
226 | int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); | ||
204 | extern int rtc_read_alarm(struct rtc_device *rtc, | 227 | extern int rtc_read_alarm(struct rtc_device *rtc, |
205 | struct rtc_wkalrm *alrm); | 228 | struct rtc_wkalrm *alrm); |
206 | extern int rtc_set_alarm(struct rtc_device *rtc, | 229 | extern int rtc_set_alarm(struct rtc_device *rtc, |
207 | struct rtc_wkalrm *alrm); | 230 | struct rtc_wkalrm *alrm); |
231 | extern int rtc_initialize_alarm(struct rtc_device *rtc, | ||
232 | struct rtc_wkalrm *alrm); | ||
208 | extern void rtc_update_irq(struct rtc_device *rtc, | 233 | extern void rtc_update_irq(struct rtc_device *rtc, |
209 | unsigned long num, unsigned long events); | 234 | unsigned long num, unsigned long events); |
210 | 235 | ||
@@ -224,15 +249,21 @@ extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); | |||
224 | extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, | 249 | extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, |
225 | unsigned int enabled); | 250 | unsigned int enabled); |
226 | 251 | ||
227 | typedef struct rtc_task { | 252 | void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode); |
228 | void (*func)(void *private_data); | 253 | void rtc_aie_update_irq(void *private); |
229 | void *private_data; | 254 | void rtc_uie_update_irq(void *private); |
230 | } rtc_task_t; | 255 | enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer); |
231 | 256 | ||
232 | int rtc_register(rtc_task_t *task); | 257 | int rtc_register(rtc_task_t *task); |
233 | int rtc_unregister(rtc_task_t *task); | 258 | int rtc_unregister(rtc_task_t *task); |
234 | int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); | 259 | int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); |
235 | 260 | ||
261 | void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data); | ||
262 | int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer, | ||
263 | ktime_t expires, ktime_t period); | ||
264 | int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer); | ||
265 | void rtc_timer_do_work(struct work_struct *work); | ||
266 | |||
236 | static inline bool is_leap_year(unsigned int year) | 267 | static inline bool is_leap_year(unsigned int year) |
237 | { | 268 | { |
238 | return (!(year % 4) && (year % 100)) || !(year % 400); | 269 | return (!(year % 4) && (year % 100)) || !(year % 400); |