rtc_irq_set_freq() requires power-of-two and associated kerneldoc
[safe/jmp/linux-2.6] / drivers / rtc / interface.c
1 /*
2  * RTC subsystem, interface functions
3  *
4  * Copyright (C) 2005 Tower Technologies
5  * Author: Alessandro Zummo <a.zummo@towertech.it>
6  *
7  * based on arch/arm/common/rtctime.c
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12 */
13
14 #include <linux/rtc.h>
15 #include <linux/log2.h>
16
17 int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
18 {
19         int err;
20
21         err = mutex_lock_interruptible(&rtc->ops_lock);
22         if (err)
23                 return -EBUSY;
24
25         if (!rtc->ops)
26                 err = -ENODEV;
27         else if (!rtc->ops->read_time)
28                 err = -EINVAL;
29         else {
30                 memset(tm, 0, sizeof(struct rtc_time));
31                 err = rtc->ops->read_time(rtc->dev.parent, tm);
32         }
33
34         mutex_unlock(&rtc->ops_lock);
35         return err;
36 }
37 EXPORT_SYMBOL_GPL(rtc_read_time);
38
39 int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
40 {
41         int err;
42
43         err = rtc_valid_tm(tm);
44         if (err != 0)
45                 return err;
46
47         err = mutex_lock_interruptible(&rtc->ops_lock);
48         if (err)
49                 return -EBUSY;
50
51         if (!rtc->ops)
52                 err = -ENODEV;
53         else if (!rtc->ops->set_time)
54                 err = -EINVAL;
55         else
56                 err = rtc->ops->set_time(rtc->dev.parent, tm);
57
58         mutex_unlock(&rtc->ops_lock);
59         return err;
60 }
61 EXPORT_SYMBOL_GPL(rtc_set_time);
62
63 int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
64 {
65         int err;
66
67         err = mutex_lock_interruptible(&rtc->ops_lock);
68         if (err)
69                 return -EBUSY;
70
71         if (!rtc->ops)
72                 err = -ENODEV;
73         else if (rtc->ops->set_mmss)
74                 err = rtc->ops->set_mmss(rtc->dev.parent, secs);
75         else if (rtc->ops->read_time && rtc->ops->set_time) {
76                 struct rtc_time new, old;
77
78                 err = rtc->ops->read_time(rtc->dev.parent, &old);
79                 if (err == 0) {
80                         rtc_time_to_tm(secs, &new);
81
82                         /*
83                          * avoid writing when we're going to change the day of
84                          * the month. We will retry in the next minute. This
85                          * basically means that if the RTC must not drift
86                          * by more than 1 minute in 11 minutes.
87                          */
88                         if (!((old.tm_hour == 23 && old.tm_min == 59) ||
89                                 (new.tm_hour == 23 && new.tm_min == 59)))
90                                 err = rtc->ops->set_time(rtc->dev.parent,
91                                                 &new);
92                 }
93         }
94         else
95                 err = -EINVAL;
96
97         mutex_unlock(&rtc->ops_lock);
98
99         return err;
100 }
101 EXPORT_SYMBOL_GPL(rtc_set_mmss);
102
103 int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
104 {
105         int err;
106
107         err = mutex_lock_interruptible(&rtc->ops_lock);
108         if (err)
109                 return -EBUSY;
110
111         if (rtc->ops == NULL)
112                 err = -ENODEV;
113         else if (!rtc->ops->read_alarm)
114                 err = -EINVAL;
115         else {
116                 memset(alarm, 0, sizeof(struct rtc_wkalrm));
117                 err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
118         }
119
120         mutex_unlock(&rtc->ops_lock);
121         return err;
122 }
123 EXPORT_SYMBOL_GPL(rtc_read_alarm);
124
125 int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
126 {
127         int err;
128
129         err = rtc_valid_tm(&alarm->time);
130         if (err != 0)
131                 return err;
132
133         err = mutex_lock_interruptible(&rtc->ops_lock);
134         if (err)
135                 return -EBUSY;
136
137         if (!rtc->ops)
138                 err = -ENODEV;
139         else if (!rtc->ops->set_alarm)
140                 err = -EINVAL;
141         else
142                 err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
143
144         mutex_unlock(&rtc->ops_lock);
145         return err;
146 }
147 EXPORT_SYMBOL_GPL(rtc_set_alarm);
148
149 /**
150  * rtc_update_irq - report RTC periodic, alarm, and/or update irqs
151  * @rtc: the rtc device
152  * @num: how many irqs are being reported (usually one)
153  * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
154  * Context: in_interrupt(), irqs blocked
155  */
156 void rtc_update_irq(struct rtc_device *rtc,
157                 unsigned long num, unsigned long events)
158 {
159         spin_lock(&rtc->irq_lock);
160         rtc->irq_data = (rtc->irq_data + (num << 8)) | events;
161         spin_unlock(&rtc->irq_lock);
162
163         spin_lock(&rtc->irq_task_lock);
164         if (rtc->irq_task)
165                 rtc->irq_task->func(rtc->irq_task->private_data);
166         spin_unlock(&rtc->irq_task_lock);
167
168         wake_up_interruptible(&rtc->irq_queue);
169         kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
170 }
171 EXPORT_SYMBOL_GPL(rtc_update_irq);
172
173 struct rtc_device *rtc_class_open(char *name)
174 {
175         struct device *dev;
176         struct rtc_device *rtc = NULL;
177
178         down(&rtc_class->sem);
179         list_for_each_entry(dev, &rtc_class->devices, node) {
180                 if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) {
181                         dev = get_device(dev);
182                         if (dev)
183                                 rtc = to_rtc_device(dev);
184                         break;
185                 }
186         }
187
188         if (rtc) {
189                 if (!try_module_get(rtc->owner)) {
190                         put_device(dev);
191                         rtc = NULL;
192                 }
193         }
194         up(&rtc_class->sem);
195
196         return rtc;
197 }
198 EXPORT_SYMBOL_GPL(rtc_class_open);
199
200 void rtc_class_close(struct rtc_device *rtc)
201 {
202         module_put(rtc->owner);
203         put_device(&rtc->dev);
204 }
205 EXPORT_SYMBOL_GPL(rtc_class_close);
206
207 int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
208 {
209         int retval = -EBUSY;
210
211         if (task == NULL || task->func == NULL)
212                 return -EINVAL;
213
214         /* Cannot register while the char dev is in use */
215         if (!(mutex_trylock(&rtc->char_lock)))
216                 return -EBUSY;
217
218         spin_lock_irq(&rtc->irq_task_lock);
219         if (rtc->irq_task == NULL) {
220                 rtc->irq_task = task;
221                 retval = 0;
222         }
223         spin_unlock_irq(&rtc->irq_task_lock);
224
225         mutex_unlock(&rtc->char_lock);
226
227         return retval;
228 }
229 EXPORT_SYMBOL_GPL(rtc_irq_register);
230
231 void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
232 {
233         spin_lock_irq(&rtc->irq_task_lock);
234         if (rtc->irq_task == task)
235                 rtc->irq_task = NULL;
236         spin_unlock_irq(&rtc->irq_task_lock);
237 }
238 EXPORT_SYMBOL_GPL(rtc_irq_unregister);
239
240 /**
241  * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
242  * @rtc: the rtc device
243  * @task: currently registered with rtc_irq_register()
244  * @enabled: true to enable periodic IRQs
245  * Context: any
246  *
247  * Note that rtc_irq_set_freq() should previously have been used to
248  * specify the desired frequency of periodic IRQ task->func() callbacks.
249  */
250 int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
251 {
252         int err = 0;
253         unsigned long flags;
254
255         if (rtc->ops->irq_set_state == NULL)
256                 return -ENXIO;
257
258         spin_lock_irqsave(&rtc->irq_task_lock, flags);
259         if (rtc->irq_task != NULL && task == NULL)
260                 err = -EBUSY;
261         if (rtc->irq_task != task)
262                 err = -EACCES;
263         spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
264
265         if (err == 0)
266                 err = rtc->ops->irq_set_state(rtc->dev.parent, enabled);
267
268         return err;
269 }
270 EXPORT_SYMBOL_GPL(rtc_irq_set_state);
271
272 /**
273  * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
274  * @rtc: the rtc device
275  * @task: currently registered with rtc_irq_register()
276  * @freq: positive frequency with which task->func() will be called
277  * Context: any
278  *
279  * Note that rtc_irq_set_state() is used to enable or disable the
280  * periodic IRQs.
281  */
282 int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
283 {
284         int err = 0;
285         unsigned long flags;
286
287         if (rtc->ops->irq_set_freq == NULL)
288                 return -ENXIO;
289
290         if (!is_power_of_2(freq))
291                 return -EINVAL;
292
293         spin_lock_irqsave(&rtc->irq_task_lock, flags);
294         if (rtc->irq_task != NULL && task == NULL)
295                 err = -EBUSY;
296         if (rtc->irq_task != task)
297                 err = -EACCES;
298         spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
299
300         if (err == 0) {
301                 err = rtc->ops->irq_set_freq(rtc->dev.parent, freq);
302                 if (err == 0)
303                         rtc->irq_freq = freq;
304         }
305         return err;
306 }
307 EXPORT_SYMBOL_GPL(rtc_irq_set_freq);