aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-dev.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
commit7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch)
treee730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/rtc/rtc-dev.c
parent41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff)
parent0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff)
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'drivers/rtc/rtc-dev.c')
-rw-r--r--drivers/rtc/rtc-dev.c100
1 files changed, 63 insertions, 37 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 0114a78b7cbb..079e9ed907e0 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
16#include <linux/smp_lock.h>
17#include "rtc-core.h" 16#include "rtc-core.h"
18 17
19static dev_t rtc_devt; 18static dev_t rtc_devt;
@@ -27,11 +26,8 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
27 struct rtc_device, char_dev); 26 struct rtc_device, char_dev);
28 const struct rtc_class_ops *ops = rtc->ops; 27 const struct rtc_class_ops *ops = rtc->ops;
29 28
30 lock_kernel(); 29 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
31 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) { 30 return -EBUSY;
32 err = -EBUSY;
33 goto out;
34 }
35 31
36 file->private_data = rtc; 32 file->private_data = rtc;
37 33
@@ -41,13 +37,11 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
41 rtc->irq_data = 0; 37 rtc->irq_data = 0;
42 spin_unlock_irq(&rtc->irq_lock); 38 spin_unlock_irq(&rtc->irq_lock);
43 39
44 goto out; 40 return 0;
45 } 41 }
46 42
47 /* something has gone wrong */ 43 /* something has gone wrong */
48 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); 44 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
49out:
50 unlock_kernel();
51 return err; 45 return err;
52} 46}
53 47
@@ -209,7 +203,7 @@ static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
209 return (data != 0) ? (POLLIN | POLLRDNORM) : 0; 203 return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
210} 204}
211 205
212static int rtc_dev_ioctl(struct inode *inode, struct file *file, 206static long rtc_dev_ioctl(struct file *file,
213 unsigned int cmd, unsigned long arg) 207 unsigned int cmd, unsigned long arg)
214{ 208{
215 int err = 0; 209 int err = 0;
@@ -219,6 +213,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
219 struct rtc_wkalrm alarm; 213 struct rtc_wkalrm alarm;
220 void __user *uarg = (void __user *) arg; 214 void __user *uarg = (void __user *) arg;
221 215
216 err = mutex_lock_interruptible(&rtc->ops_lock);
217 if (err)
218 return err;
219
222 /* check that the calling task has appropriate permissions 220 /* check that the calling task has appropriate permissions
223 * for certain ioctls. doing this check here is useful 221 * for certain ioctls. doing this check here is useful
224 * to avoid duplicate code in each driver. 222 * to avoid duplicate code in each driver.
@@ -227,26 +225,31 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
227 case RTC_EPOCH_SET: 225 case RTC_EPOCH_SET:
228 case RTC_SET_TIME: 226 case RTC_SET_TIME:
229 if (!capable(CAP_SYS_TIME)) 227 if (!capable(CAP_SYS_TIME))
230 return -EACCES; 228 err = -EACCES;
231 break; 229 break;
232 230
233 case RTC_IRQP_SET: 231 case RTC_IRQP_SET:
234 if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) 232 if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE))
235 return -EACCES; 233 err = -EACCES;
236 break; 234 break;
237 235
238 case RTC_PIE_ON: 236 case RTC_PIE_ON:
239 if (rtc->irq_freq > rtc->max_user_freq && 237 if (rtc->irq_freq > rtc->max_user_freq &&
240 !capable(CAP_SYS_RESOURCE)) 238 !capable(CAP_SYS_RESOURCE))
241 return -EACCES; 239 err = -EACCES;
242 break; 240 break;
243 } 241 }
244 242
243 if (err)
244 goto done;
245
245 /* try the driver's ioctl interface */ 246 /* try the driver's ioctl interface */
246 if (ops->ioctl) { 247 if (ops->ioctl) {
247 err = ops->ioctl(rtc->dev.parent, cmd, arg); 248 err = ops->ioctl(rtc->dev.parent, cmd, arg);
248 if (err != -ENOIOCTLCMD) 249 if (err != -ENOIOCTLCMD) {
250 mutex_unlock(&rtc->ops_lock);
249 return err; 251 return err;
252 }
250 } 253 }
251 254
252 /* if the driver does not provide the ioctl interface 255 /* if the driver does not provide the ioctl interface
@@ -265,15 +268,19 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
265 268
266 switch (cmd) { 269 switch (cmd) {
267 case RTC_ALM_READ: 270 case RTC_ALM_READ:
271 mutex_unlock(&rtc->ops_lock);
272
268 err = rtc_read_alarm(rtc, &alarm); 273 err = rtc_read_alarm(rtc, &alarm);
269 if (err < 0) 274 if (err < 0)
270 return err; 275 return err;
271 276
272 if (copy_to_user(uarg, &alarm.time, sizeof(tm))) 277 if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
273 return -EFAULT; 278 err = -EFAULT;
274 break; 279 return err;
275 280
276 case RTC_ALM_SET: 281 case RTC_ALM_SET:
282 mutex_unlock(&rtc->ops_lock);
283
277 if (copy_from_user(&alarm.time, uarg, sizeof(tm))) 284 if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
278 return -EFAULT; 285 return -EFAULT;
279 286
@@ -321,24 +328,26 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
321 } 328 }
322 } 329 }
323 330
324 err = rtc_set_alarm(rtc, &alarm); 331 return rtc_set_alarm(rtc, &alarm);
325 break;
326 332
327 case RTC_RD_TIME: 333 case RTC_RD_TIME:
334 mutex_unlock(&rtc->ops_lock);
335
328 err = rtc_read_time(rtc, &tm); 336 err = rtc_read_time(rtc, &tm);
329 if (err < 0) 337 if (err < 0)
330 return err; 338 return err;
331 339
332 if (copy_to_user(uarg, &tm, sizeof(tm))) 340 if (copy_to_user(uarg, &tm, sizeof(tm)))
333 return -EFAULT; 341 err = -EFAULT;
334 break; 342 return err;
335 343
336 case RTC_SET_TIME: 344 case RTC_SET_TIME:
345 mutex_unlock(&rtc->ops_lock);
346
337 if (copy_from_user(&tm, uarg, sizeof(tm))) 347 if (copy_from_user(&tm, uarg, sizeof(tm)))
338 return -EFAULT; 348 return -EFAULT;
339 349
340 err = rtc_set_time(rtc, &tm); 350 return rtc_set_time(rtc, &tm);
341 break;
342 351
343 case RTC_PIE_ON: 352 case RTC_PIE_ON:
344 err = rtc_irq_set_state(rtc, NULL, 1); 353 err = rtc_irq_set_state(rtc, NULL, 1);
@@ -376,63 +385,80 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
376 break; 385 break;
377#endif 386#endif
378 case RTC_WKALM_SET: 387 case RTC_WKALM_SET:
388 mutex_unlock(&rtc->ops_lock);
379 if (copy_from_user(&alarm, uarg, sizeof(alarm))) 389 if (copy_from_user(&alarm, uarg, sizeof(alarm)))
380 return -EFAULT; 390 return -EFAULT;
381 391
382 err = rtc_set_alarm(rtc, &alarm); 392 return rtc_set_alarm(rtc, &alarm);
383 break;
384 393
385 case RTC_WKALM_RD: 394 case RTC_WKALM_RD:
395 mutex_unlock(&rtc->ops_lock);
386 err = rtc_read_alarm(rtc, &alarm); 396 err = rtc_read_alarm(rtc, &alarm);
387 if (err < 0) 397 if (err < 0)
388 return err; 398 return err;
389 399
390 if (copy_to_user(uarg, &alarm, sizeof(alarm))) 400 if (copy_to_user(uarg, &alarm, sizeof(alarm)))
391 return -EFAULT; 401 err = -EFAULT;
392 break; 402 return err;
393 403
394#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 404#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
395 case RTC_UIE_OFF: 405 case RTC_UIE_OFF:
406 mutex_unlock(&rtc->ops_lock);
396 clear_uie(rtc); 407 clear_uie(rtc);
397 return 0; 408 return 0;
398 409
399 case RTC_UIE_ON: 410 case RTC_UIE_ON:
400 return set_uie(rtc); 411 mutex_unlock(&rtc->ops_lock);
412 err = set_uie(rtc);
413 return err;
401#endif 414#endif
402 default: 415 default:
403 err = -ENOTTY; 416 err = -ENOTTY;
404 break; 417 break;
405 } 418 }
406 419
420done:
421 mutex_unlock(&rtc->ops_lock);
407 return err; 422 return err;
408} 423}
409 424
425static int rtc_dev_fasync(int fd, struct file *file, int on)
426{
427 struct rtc_device *rtc = file->private_data;
428 return fasync_helper(fd, file, on, &rtc->async_queue);
429}
430
410static int rtc_dev_release(struct inode *inode, struct file *file) 431static int rtc_dev_release(struct inode *inode, struct file *file)
411{ 432{
412 struct rtc_device *rtc = file->private_data; 433 struct rtc_device *rtc = file->private_data;
413 434
414#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 435 /* We shut down the repeating IRQs that userspace enabled,
415 clear_uie(rtc); 436 * since nothing is listening to them.
416#endif 437 * - Update (UIE) ... currently only managed through ioctls
438 * - Periodic (PIE) ... also used through rtc_*() interface calls
439 *
440 * Leave the alarm alone; it may be set to trigger a system wakeup
441 * later, or be used by kernel code, and is a one-shot event anyway.
442 */
443 rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
444 rtc_irq_set_state(rtc, NULL, 0);
445
417 if (rtc->ops->release) 446 if (rtc->ops->release)
418 rtc->ops->release(rtc->dev.parent); 447 rtc->ops->release(rtc->dev.parent);
419 448
449 if (file->f_flags & FASYNC)
450 rtc_dev_fasync(-1, file, 0);
451
420 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); 452 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
421 return 0; 453 return 0;
422} 454}
423 455
424static int rtc_dev_fasync(int fd, struct file *file, int on)
425{
426 struct rtc_device *rtc = file->private_data;
427 return fasync_helper(fd, file, on, &rtc->async_queue);
428}
429
430static const struct file_operations rtc_dev_fops = { 456static const struct file_operations rtc_dev_fops = {
431 .owner = THIS_MODULE, 457 .owner = THIS_MODULE,
432 .llseek = no_llseek, 458 .llseek = no_llseek,
433 .read = rtc_dev_read, 459 .read = rtc_dev_read,
434 .poll = rtc_dev_poll, 460 .poll = rtc_dev_poll,
435 .ioctl = rtc_dev_ioctl, 461 .unlocked_ioctl = rtc_dev_ioctl,
436 .open = rtc_dev_open, 462 .open = rtc_dev_open,
437 .release = rtc_dev_release, 463 .release = rtc_dev_release,
438 .fasync = rtc_dev_fasync, 464 .fasync = rtc_dev_fasync,