linux/drivers/rtc/rtc-dev.c
<<
>>
Prefs
   1/*
   2 * RTC subsystem, dev interface
   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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15
  16#include <linux/module.h>
  17#include <linux/rtc.h>
  18#include <linux/sched.h>
  19#include "rtc-core.h"
  20
  21static dev_t rtc_devt;
  22
  23#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
  24
  25static int rtc_dev_open(struct inode *inode, struct file *file)
  26{
  27        int err;
  28        struct rtc_device *rtc = container_of(inode->i_cdev,
  29                                        struct rtc_device, char_dev);
  30        const struct rtc_class_ops *ops = rtc->ops;
  31
  32        if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
  33                return -EBUSY;
  34
  35        file->private_data = rtc;
  36
  37        err = ops->open ? ops->open(rtc->dev.parent) : 0;
  38        if (err == 0) {
  39                spin_lock_irq(&rtc->irq_lock);
  40                rtc->irq_data = 0;
  41                spin_unlock_irq(&rtc->irq_lock);
  42
  43                return 0;
  44        }
  45
  46        /* something has gone wrong */
  47        clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
  48        return err;
  49}
  50
  51#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
  52/*
  53 * Routine to poll RTC seconds field for change as often as possible,
  54 * after first RTC_UIE use timer to reduce polling
  55 */
  56static void rtc_uie_task(struct work_struct *work)
  57{
  58        struct rtc_device *rtc =
  59                container_of(work, struct rtc_device, uie_task);
  60        struct rtc_time tm;
  61        int num = 0;
  62        int err;
  63
  64        err = rtc_read_time(rtc, &tm);
  65
  66        spin_lock_irq(&rtc->irq_lock);
  67        if (rtc->stop_uie_polling || err) {
  68                rtc->uie_task_active = 0;
  69        } else if (rtc->oldsecs != tm.tm_sec) {
  70                num = (tm.tm_sec + 60 - rtc->oldsecs) % 60;
  71                rtc->oldsecs = tm.tm_sec;
  72                rtc->uie_timer.expires = jiffies + HZ - (HZ/10);
  73                rtc->uie_timer_active = 1;
  74                rtc->uie_task_active = 0;
  75                add_timer(&rtc->uie_timer);
  76        } else if (schedule_work(&rtc->uie_task) == 0) {
  77                rtc->uie_task_active = 0;
  78        }
  79        spin_unlock_irq(&rtc->irq_lock);
  80        if (num)
  81                rtc_handle_legacy_irq(rtc, num, RTC_UF);
  82}
  83static void rtc_uie_timer(unsigned long data)
  84{
  85        struct rtc_device *rtc = (struct rtc_device *)data;
  86        unsigned long flags;
  87
  88        spin_lock_irqsave(&rtc->irq_lock, flags);
  89        rtc->uie_timer_active = 0;
  90        rtc->uie_task_active = 1;
  91        if ((schedule_work(&rtc->uie_task) == 0))
  92                rtc->uie_task_active = 0;
  93        spin_unlock_irqrestore(&rtc->irq_lock, flags);
  94}
  95
  96static int clear_uie(struct rtc_device *rtc)
  97{
  98        spin_lock_irq(&rtc->irq_lock);
  99        if (rtc->uie_irq_active) {
 100                rtc->stop_uie_polling = 1;
 101                if (rtc->uie_timer_active) {
 102                        spin_unlock_irq(&rtc->irq_lock);
 103                        del_timer_sync(&rtc->uie_timer);
 104                        spin_lock_irq(&rtc->irq_lock);
 105                        rtc->uie_timer_active = 0;
 106                }
 107                if (rtc->uie_task_active) {
 108                        spin_unlock_irq(&rtc->irq_lock);
 109                        flush_scheduled_work();
 110                        spin_lock_irq(&rtc->irq_lock);
 111                }
 112                rtc->uie_irq_active = 0;
 113        }
 114        spin_unlock_irq(&rtc->irq_lock);
 115        return 0;
 116}
 117
 118static int set_uie(struct rtc_device *rtc)
 119{
 120        struct rtc_time tm;
 121        int err;
 122
 123        err = rtc_read_time(rtc, &tm);
 124        if (err)
 125                return err;
 126        spin_lock_irq(&rtc->irq_lock);
 127        if (!rtc->uie_irq_active) {
 128                rtc->uie_irq_active = 1;
 129                rtc->stop_uie_polling = 0;
 130                rtc->oldsecs = tm.tm_sec;
 131                rtc->uie_task_active = 1;
 132                if (schedule_work(&rtc->uie_task) == 0)
 133                        rtc->uie_task_active = 0;
 134        }
 135        rtc->irq_data = 0;
 136        spin_unlock_irq(&rtc->irq_lock);
 137        return 0;
 138}
 139
 140int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled)
 141{
 142        if (enabled)
 143                return set_uie(rtc);
 144        else
 145                return clear_uie(rtc);
 146}
 147EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul);
 148
 149#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */
 150
 151static ssize_t
 152rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 153{
 154        struct rtc_device *rtc = file->private_data;
 155
 156        DECLARE_WAITQUEUE(wait, current);
 157        unsigned long data;
 158        ssize_t ret;
 159
 160        if (count != sizeof(unsigned int) && count < sizeof(unsigned long))
 161                return -EINVAL;
 162
 163        add_wait_queue(&rtc->irq_queue, &wait);
 164        do {
 165                __set_current_state(TASK_INTERRUPTIBLE);
 166
 167                spin_lock_irq(&rtc->irq_lock);
 168                data = rtc->irq_data;
 169                rtc->irq_data = 0;
 170                spin_unlock_irq(&rtc->irq_lock);
 171
 172                if (data != 0) {
 173                        ret = 0;
 174                        break;
 175                }
 176                if (file->f_flags & O_NONBLOCK) {
 177                        ret = -EAGAIN;
 178                        break;
 179                }
 180                if (signal_pending(current)) {
 181                        ret = -ERESTARTSYS;
 182                        break;
 183                }
 184                schedule();
 185        } while (1);
 186        set_current_state(TASK_RUNNING);
 187        remove_wait_queue(&rtc->irq_queue, &wait);
 188
 189        if (ret == 0) {
 190                /* Check for any data updates */
 191                if (rtc->ops->read_callback)
 192                        data = rtc->ops->read_callback(rtc->dev.parent,
 193                                                       data);
 194
 195                if (sizeof(int) != sizeof(long) &&
 196                    count == sizeof(unsigned int))
 197                        ret = put_user(data, (unsigned int __user *)buf) ?:
 198                                sizeof(unsigned int);
 199                else
 200                        ret = put_user(data, (unsigned long __user *)buf) ?:
 201                                sizeof(unsigned long);
 202        }
 203        return ret;
 204}
 205
 206static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
 207{
 208        struct rtc_device *rtc = file->private_data;
 209        unsigned long data;
 210
 211        poll_wait(file, &rtc->irq_queue, wait);
 212
 213        data = rtc->irq_data;
 214
 215        return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
 216}
 217
 218static long rtc_dev_ioctl(struct file *file,
 219                unsigned int cmd, unsigned long arg)
 220{
 221        int err = 0;
 222        struct rtc_device *rtc = file->private_data;
 223        const struct rtc_class_ops *ops = rtc->ops;
 224        struct rtc_time tm;
 225        struct rtc_wkalrm alarm;
 226        void __user *uarg = (void __user *) arg;
 227
 228        err = mutex_lock_interruptible(&rtc->ops_lock);
 229        if (err)
 230                return err;
 231
 232        /* check that the calling task has appropriate permissions
 233         * for certain ioctls. doing this check here is useful
 234         * to avoid duplicate code in each driver.
 235         */
 236        switch (cmd) {
 237        case RTC_EPOCH_SET:
 238        case RTC_SET_TIME:
 239                if (!capable(CAP_SYS_TIME))
 240                        err = -EACCES;
 241                break;
 242
 243        case RTC_IRQP_SET:
 244                if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE))
 245                        err = -EACCES;
 246                break;
 247
 248        case RTC_PIE_ON:
 249                if (rtc->irq_freq > rtc->max_user_freq &&
 250                                !capable(CAP_SYS_RESOURCE))
 251                        err = -EACCES;
 252                break;
 253        }
 254
 255        if (err)
 256                goto done;
 257
 258        /*
 259         * Drivers *SHOULD NOT* provide ioctl implementations
 260         * for these requests.  Instead, provide methods to
 261         * support the following code, so that the RTC's main
 262         * features are accessible without using ioctls.
 263         *
 264         * RTC and alarm times will be in UTC, by preference,
 265         * but dual-booting with MS-Windows implies RTCs must
 266         * use the local wall clock time.
 267         */
 268
 269        switch (cmd) {
 270        case RTC_ALM_READ:
 271                mutex_unlock(&rtc->ops_lock);
 272
 273                err = rtc_read_alarm(rtc, &alarm);
 274                if (err < 0)
 275                        return err;
 276
 277                if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
 278                        err = -EFAULT;
 279                return err;
 280
 281        case RTC_ALM_SET:
 282                mutex_unlock(&rtc->ops_lock);
 283
 284                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
 285                        return -EFAULT;
 286
 287                alarm.enabled = 0;
 288                alarm.pending = 0;
 289                alarm.time.tm_wday = -1;
 290                alarm.time.tm_yday = -1;
 291                alarm.time.tm_isdst = -1;
 292
 293                /* RTC_ALM_SET alarms may be up to 24 hours in the future.
 294                 * Rather than expecting every RTC to implement "don't care"
 295                 * for day/month/year fields, just force the alarm to have
 296                 * the right values for those fields.
 297                 *
 298                 * RTC_WKALM_SET should be used instead.  Not only does it
 299                 * eliminate the need for a separate RTC_AIE_ON call, it
 300                 * doesn't have the "alarm 23:59:59 in the future" race.
 301                 *
 302                 * NOTE:  some legacy code may have used invalid fields as
 303                 * wildcards, exposing hardware "periodic alarm" capabilities.
 304                 * Not supported here.
 305                 */
 306                {
 307                        unsigned long now, then;
 308
 309                        err = rtc_read_time(rtc, &tm);
 310                        if (err < 0)
 311                                return err;
 312                        rtc_tm_to_time(&tm, &now);
 313
 314                        alarm.time.tm_mday = tm.tm_mday;
 315                        alarm.time.tm_mon = tm.tm_mon;
 316                        alarm.time.tm_year = tm.tm_year;
 317                        err  = rtc_valid_tm(&alarm.time);
 318                        if (err < 0)
 319                                return err;
 320                        rtc_tm_to_time(&alarm.time, &then);
 321
 322                        /* alarm may need to wrap into tomorrow */
 323                        if (then < now) {
 324                                rtc_time_to_tm(now + 24 * 60 * 60, &tm);
 325                                alarm.time.tm_mday = tm.tm_mday;
 326                                alarm.time.tm_mon = tm.tm_mon;
 327                                alarm.time.tm_year = tm.tm_year;
 328                        }
 329                }
 330
 331                return rtc_set_alarm(rtc, &alarm);
 332
 333        case RTC_RD_TIME:
 334                mutex_unlock(&rtc->ops_lock);
 335
 336                err = rtc_read_time(rtc, &tm);
 337                if (err < 0)
 338                        return err;
 339
 340                if (copy_to_user(uarg, &tm, sizeof(tm)))
 341                        err = -EFAULT;
 342                return err;
 343
 344        case RTC_SET_TIME:
 345                mutex_unlock(&rtc->ops_lock);
 346
 347                if (copy_from_user(&tm, uarg, sizeof(tm)))
 348                        return -EFAULT;
 349
 350                return rtc_set_time(rtc, &tm);
 351
 352        case RTC_PIE_ON:
 353                err = rtc_irq_set_state(rtc, NULL, 1);
 354                break;
 355
 356        case RTC_PIE_OFF:
 357                err = rtc_irq_set_state(rtc, NULL, 0);
 358                break;
 359
 360        case RTC_AIE_ON:
 361                mutex_unlock(&rtc->ops_lock);
 362                return rtc_alarm_irq_enable(rtc, 1);
 363
 364        case RTC_AIE_OFF:
 365                mutex_unlock(&rtc->ops_lock);
 366                return rtc_alarm_irq_enable(rtc, 0);
 367
 368        case RTC_UIE_ON:
 369                mutex_unlock(&rtc->ops_lock);
 370                return rtc_update_irq_enable(rtc, 1);
 371
 372        case RTC_UIE_OFF:
 373                mutex_unlock(&rtc->ops_lock);
 374                return rtc_update_irq_enable(rtc, 0);
 375
 376        case RTC_IRQP_SET:
 377                err = rtc_irq_set_freq(rtc, NULL, arg);
 378                break;
 379
 380        case RTC_IRQP_READ:
 381                err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
 382                break;
 383
 384        case RTC_WKALM_SET:
 385                mutex_unlock(&rtc->ops_lock);
 386                if (copy_from_user(&alarm, uarg, sizeof(alarm)))
 387                        return -EFAULT;
 388
 389                return rtc_set_alarm(rtc, &alarm);
 390
 391        case RTC_WKALM_RD:
 392                mutex_unlock(&rtc->ops_lock);
 393                err = rtc_read_alarm(rtc, &alarm);
 394                if (err < 0)
 395                        return err;
 396
 397                if (copy_to_user(uarg, &alarm, sizeof(alarm)))
 398                        err = -EFAULT;
 399                return err;
 400
 401        default:
 402                /* Finally try the driver's ioctl interface */
 403                if (ops->ioctl) {
 404                        err = ops->ioctl(rtc->dev.parent, cmd, arg);
 405                        if (err == -ENOIOCTLCMD)
 406                                err = -ENOTTY;
 407                } else
 408                        err = -ENOTTY;
 409                break;
 410        }
 411
 412done:
 413        mutex_unlock(&rtc->ops_lock);
 414        return err;
 415}
 416
 417static int rtc_dev_fasync(int fd, struct file *file, int on)
 418{
 419        struct rtc_device *rtc = file->private_data;
 420        return fasync_helper(fd, file, on, &rtc->async_queue);
 421}
 422
 423static int rtc_dev_release(struct inode *inode, struct file *file)
 424{
 425        struct rtc_device *rtc = file->private_data;
 426
 427        /* We shut down the repeating IRQs that userspace enabled,
 428         * since nothing is listening to them.
 429         *  - Update (UIE) ... currently only managed through ioctls
 430         *  - Periodic (PIE) ... also used through rtc_*() interface calls
 431         *
 432         * Leave the alarm alone; it may be set to trigger a system wakeup
 433         * later, or be used by kernel code, and is a one-shot event anyway.
 434         */
 435
 436        /* Keep ioctl until all drivers are converted */
 437        rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
 438        rtc_update_irq_enable(rtc, 0);
 439        rtc_irq_set_state(rtc, NULL, 0);
 440
 441        if (rtc->ops->release)
 442                rtc->ops->release(rtc->dev.parent);
 443
 444        clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
 445        return 0;
 446}
 447
 448static const struct file_operations rtc_dev_fops = {
 449        .owner          = THIS_MODULE,
 450        .llseek         = no_llseek,
 451        .read           = rtc_dev_read,
 452        .poll           = rtc_dev_poll,
 453        .unlocked_ioctl = rtc_dev_ioctl,
 454        .open           = rtc_dev_open,
 455        .release        = rtc_dev_release,
 456        .fasync         = rtc_dev_fasync,
 457};
 458
 459/* insertion/removal hooks */
 460
 461void rtc_dev_prepare(struct rtc_device *rtc)
 462{
 463        if (!rtc_devt)
 464                return;
 465
 466        if (rtc->id >= RTC_DEV_MAX) {
 467                dev_dbg(&rtc->dev, "%s: too many RTC devices\n", rtc->name);
 468                return;
 469        }
 470
 471        rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
 472
 473#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
 474        INIT_WORK(&rtc->uie_task, rtc_uie_task);
 475        setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
 476#endif
 477
 478        cdev_init(&rtc->char_dev, &rtc_dev_fops);
 479        rtc->char_dev.owner = rtc->owner;
 480}
 481
 482void rtc_dev_add_device(struct rtc_device *rtc)
 483{
 484        if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1))
 485                dev_warn(&rtc->dev, "%s: failed to add char device %d:%d\n",
 486                        rtc->name, MAJOR(rtc_devt), rtc->id);
 487        else
 488                dev_dbg(&rtc->dev, "%s: dev (%d:%d)\n", rtc->name,
 489                        MAJOR(rtc_devt), rtc->id);
 490}
 491
 492void rtc_dev_del_device(struct rtc_device *rtc)
 493{
 494        if (rtc->dev.devt)
 495                cdev_del(&rtc->char_dev);
 496}
 497
 498void __init rtc_dev_init(void)
 499{
 500        int err;
 501
 502        err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");
 503        if (err < 0)
 504                pr_err("failed to allocate char dev region\n");
 505}
 506
 507void __exit rtc_dev_exit(void)
 508{
 509        if (rtc_devt)
 510                unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
 511}
 512
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.