linux/arch/arm/kernel/time.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/kernel/time.c
   3 *
   4 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
   5 *  Modifications for ARM (C) 1994-2001 Russell King
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 *  This file contains the ARM-specific time handling details:
  12 *  reading the RTC at bootup, etc...
  13 *
  14 *  1994-07-02  Alan Modra
  15 *              fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
  16 *  1998-12-20  Updated NTP code according to technical memorandum Jan '96
  17 *              "A Kernel Model for Precision Timekeeping" by Dave Mills
  18 */
  19#include <linux/module.h>
  20#include <linux/kernel.h>
  21#include <linux/interrupt.h>
  22#include <linux/time.h>
  23#include <linux/init.h>
  24#include <linux/smp.h>
  25#include <linux/timex.h>
  26#include <linux/errno.h>
  27#include <linux/profile.h>
  28#include <linux/sysdev.h>
  29#include <linux/timer.h>
  30#include <linux/irq.h>
  31
  32#include <linux/mc146818rtc.h>
  33
  34#include <asm/leds.h>
  35#include <asm/thread_info.h>
  36#include <asm/mach/time.h>
  37
  38/*
  39 * Our system timer.
  40 */
  41struct sys_timer *system_timer;
  42
  43#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
  44/* this needs a better home */
  45DEFINE_SPINLOCK(rtc_lock);
  46
  47#ifdef CONFIG_RTC_DRV_CMOS_MODULE
  48EXPORT_SYMBOL(rtc_lock);
  49#endif
  50#endif  /* pc-style 'CMOS' RTC support */
  51
  52/* change this if you have some constant time drift */
  53#define USECS_PER_JIFFY (1000000/HZ)
  54
  55#ifdef CONFIG_SMP
  56unsigned long profile_pc(struct pt_regs *regs)
  57{
  58        unsigned long fp, pc = instruction_pointer(regs);
  59
  60        if (in_lock_functions(pc)) {
  61                fp = regs->ARM_fp;
  62                pc = pc_pointer(((unsigned long *)fp)[-1]);
  63        }
  64
  65        return pc;
  66}
  67EXPORT_SYMBOL(profile_pc);
  68#endif
  69
  70/*
  71 * hook for setting the RTC's idea of the current time.
  72 */
  73int (*set_rtc)(void);
  74
  75#ifndef CONFIG_GENERIC_TIME
  76static unsigned long dummy_gettimeoffset(void)
  77{
  78        return 0;
  79}
  80#endif
  81
  82/*
  83 * An implementation of printk_clock() independent from
  84 * sched_clock().  This avoids non-bootable kernels when
  85 * printk_clock is enabled.
  86 */
  87unsigned long long printk_clock(void)
  88{
  89        return (unsigned long long)(jiffies - INITIAL_JIFFIES) *
  90                        (1000000000 / HZ);
  91}
  92
  93static unsigned long next_rtc_update;
  94
  95/*
  96 * If we have an externally synchronized linux clock, then update
  97 * CMOS clock accordingly every ~11 minutes.  set_rtc() has to be
  98 * called as close as possible to 500 ms before the new second
  99 * starts.
 100 */
 101static inline void do_set_rtc(void)
 102{
 103        if (!ntp_synced() || set_rtc == NULL)
 104                return;
 105
 106        if (next_rtc_update &&
 107            time_before((unsigned long)xtime.tv_sec, next_rtc_update))
 108                return;
 109
 110        if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
 111            xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1))
 112                return;
 113
 114        if (set_rtc())
 115                /*
 116                 * rtc update failed.  Try again in 60s
 117                 */
 118                next_rtc_update = xtime.tv_sec + 60;
 119        else
 120                next_rtc_update = xtime.tv_sec + 660;
 121}
 122
 123#ifdef CONFIG_LEDS
 124
 125static void dummy_leds_event(led_event_t evt)
 126{
 127}
 128
 129void (*leds_event)(led_event_t) = dummy_leds_event;
 130
 131struct leds_evt_name {
 132        const char      name[8];
 133        int             on;
 134        int             off;
 135};
 136
 137static const struct leds_evt_name evt_names[] = {
 138        { "amber", led_amber_on, led_amber_off },
 139        { "blue",  led_blue_on,  led_blue_off  },
 140        { "green", led_green_on, led_green_off },
 141        { "red",   led_red_on,   led_red_off   },
 142};
 143
 144static ssize_t leds_store(struct sys_device *dev, const char *buf, size_t size)
 145{
 146        int ret = -EINVAL, len = strcspn(buf, " ");
 147
 148        if (len > 0 && buf[len] == '\0')
 149                len--;
 150
 151        if (strncmp(buf, "claim", len) == 0) {
 152                leds_event(led_claim);
 153                ret = size;
 154        } else if (strncmp(buf, "release", len) == 0) {
 155                leds_event(led_release);
 156                ret = size;
 157        } else {
 158                int i;
 159
 160                for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
 161                        if (strlen(evt_names[i].name) != len ||
 162                            strncmp(buf, evt_names[i].name, len) != 0)
 163                                continue;
 164                        if (strncmp(buf+len, " on", 3) == 0) {
 165                                leds_event(evt_names[i].on);
 166                                ret = size;
 167                        } else if (strncmp(buf+len, " off", 4) == 0) {
 168                                leds_event(evt_names[i].off);
 169                                ret = size;
 170                        }
 171                        break;
 172                }
 173        }
 174        return ret;
 175}
 176
 177static SYSDEV_ATTR(event, 0200, NULL, leds_store);
 178
 179static int leds_suspend(struct sys_device *dev, pm_message_t state)
 180{
 181        leds_event(led_stop);
 182        return 0;
 183}
 184
 185static int leds_resume(struct sys_device *dev)
 186{
 187        leds_event(led_start);
 188        return 0;
 189}
 190
 191static int leds_shutdown(struct sys_device *dev)
 192{
 193        leds_event(led_halted);
 194        return 0;
 195}
 196
 197static struct sysdev_class leds_sysclass = {
 198        set_kset_name("leds"),
 199        .shutdown       = leds_shutdown,
 200        .suspend        = leds_suspend,
 201        .resume         = leds_resume,
 202};
 203
 204static struct sys_device leds_device = {
 205        .id             = 0,
 206        .cls            = &leds_sysclass,
 207};
 208
 209static int __init leds_init(void)
 210{
 211        int ret;
 212        ret = sysdev_class_register(&leds_sysclass);
 213        if (ret == 0)
 214                ret = sysdev_register(&leds_device);
 215        if (ret == 0)
 216                ret = sysdev_create_file(&leds_device, &attr_event);
 217        return ret;
 218}
 219
 220device_initcall(leds_init);
 221
 222EXPORT_SYMBOL(leds_event);
 223#endif
 224
 225#ifdef CONFIG_LEDS_TIMER
 226static inline void do_leds(void)
 227{
 228        static unsigned int count = HZ/2;
 229
 230        if (--count == 0) {
 231                count = HZ/2;
 232                leds_event(led_timer);
 233        }
 234}
 235#else
 236#define do_leds()
 237#endif
 238
 239#ifndef CONFIG_GENERIC_TIME
 240void do_gettimeofday(struct timeval *tv)
 241{
 242        unsigned long flags;
 243        unsigned long seq;
 244        unsigned long usec, sec;
 245
 246        do {
 247                seq = read_seqbegin_irqsave(&xtime_lock, flags);
 248                usec = system_timer->offset();
 249                sec = xtime.tv_sec;
 250                usec += xtime.tv_nsec / 1000;
 251        } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 252
 253        /* usec may have gone up a lot: be safe */
 254        while (usec >= 1000000) {
 255                usec -= 1000000;
 256                sec++;
 257        }
 258
 259        tv->tv_sec = sec;
 260        tv->tv_usec = usec;
 261}
 262
 263EXPORT_SYMBOL(do_gettimeofday);
 264
 265int do_settimeofday(struct timespec *tv)
 266{
 267        time_t wtm_sec, sec = tv->tv_sec;
 268        long wtm_nsec, nsec = tv->tv_nsec;
 269
 270        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
 271                return -EINVAL;
 272
 273        write_seqlock_irq(&xtime_lock);
 274        /*
 275         * This is revolting. We need to set "xtime" correctly. However, the
 276         * value in this location is the value at the most recent update of
 277         * wall time.  Discover what correction gettimeofday() would have
 278         * done, and then undo it!
 279         */
 280        nsec -= system_timer->offset() * NSEC_PER_USEC;
 281
 282        wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
 283        wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
 284
 285        set_normalized_timespec(&xtime, sec, nsec);
 286        set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
 287
 288        ntp_clear();
 289        write_sequnlock_irq(&xtime_lock);
 290        clock_was_set();
 291        return 0;
 292}
 293
 294EXPORT_SYMBOL(do_settimeofday);
 295#endif /* !CONFIG_GENERIC_TIME */
 296
 297/**
 298 * save_time_delta - Save the offset between system time and RTC time
 299 * @delta: pointer to timespec to store delta
 300 * @rtc: pointer to timespec for current RTC time
 301 *
 302 * Return a delta between the system time and the RTC time, such
 303 * that system time can be restored later with restore_time_delta()
 304 */
 305void save_time_delta(struct timespec *delta, struct timespec *rtc)
 306{
 307        set_normalized_timespec(delta,
 308                                xtime.tv_sec - rtc->tv_sec,
 309                                xtime.tv_nsec - rtc->tv_nsec);
 310}
 311EXPORT_SYMBOL(save_time_delta);
 312
 313/**
 314 * restore_time_delta - Restore the current system time
 315 * @delta: delta returned by save_time_delta()
 316 * @rtc: pointer to timespec for current RTC time
 317 */
 318void restore_time_delta(struct timespec *delta, struct timespec *rtc)
 319{
 320        struct timespec ts;
 321
 322        set_normalized_timespec(&ts,
 323                                delta->tv_sec + rtc->tv_sec,
 324                                delta->tv_nsec + rtc->tv_nsec);
 325
 326        do_settimeofday(&ts);
 327}
 328EXPORT_SYMBOL(restore_time_delta);
 329
 330#ifndef CONFIG_GENERIC_CLOCKEVENTS
 331/*
 332 * Kernel system timer support.
 333 */
 334void timer_tick(void)
 335{
 336        profile_tick(CPU_PROFILING);
 337        do_leds();
 338        do_set_rtc();
 339        do_timer(1);
 340#ifndef CONFIG_SMP
 341        update_process_times(user_mode(get_irq_regs()));
 342#endif
 343}
 344#endif
 345
 346#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
 347static int timer_suspend(struct sys_device *dev, pm_message_t state)
 348{
 349        struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
 350
 351        if (timer->suspend != NULL)
 352                timer->suspend();
 353
 354        return 0;
 355}
 356
 357static int timer_resume(struct sys_device *dev)
 358{
 359        struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
 360
 361        if (timer->resume != NULL)
 362                timer->resume();
 363
 364        return 0;
 365}
 366#else
 367#define timer_suspend NULL
 368#define timer_resume NULL
 369#endif
 370
 371static struct sysdev_class timer_sysclass = {
 372        set_kset_name("timer"),
 373        .suspend        = timer_suspend,
 374        .resume         = timer_resume,
 375};
 376
 377#ifdef CONFIG_NO_IDLE_HZ
 378static int timer_dyn_tick_enable(void)
 379{
 380        struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
 381        unsigned long flags;
 382        int ret = -ENODEV;
 383
 384        if (dyn_tick) {
 385                spin_lock_irqsave(&dyn_tick->lock, flags);
 386                ret = 0;
 387                if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
 388                        ret = dyn_tick->enable();
 389
 390                        if (ret == 0)
 391                                dyn_tick->state |= DYN_TICK_ENABLED;
 392                }
 393                spin_unlock_irqrestore(&dyn_tick->lock, flags);
 394        }
 395
 396        return ret;
 397}
 398
 399static int timer_dyn_tick_disable(void)
 400{
 401        struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
 402        unsigned long flags;
 403        int ret = -ENODEV;
 404
 405        if (dyn_tick) {
 406                spin_lock_irqsave(&dyn_tick->lock, flags);
 407                ret = 0;
 408                if (dyn_tick->state & DYN_TICK_ENABLED) {
 409                        ret = dyn_tick->disable();
 410
 411                        if (ret == 0)
 412                                dyn_tick->state &= ~DYN_TICK_ENABLED;
 413                }
 414                spin_unlock_irqrestore(&dyn_tick->lock, flags);
 415        }
 416
 417        return ret;
 418}
 419
 420/*
 421 * Reprogram the system timer for at least the calculated time interval.
 422 * This function should be called from the idle thread with IRQs disabled,
 423 * immediately before sleeping.
 424 */
 425void timer_dyn_reprogram(void)
 426{
 427        struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
 428        unsigned long next, seq, flags;
 429
 430        if (!dyn_tick)
 431                return;
 432
 433        spin_lock_irqsave(&dyn_tick->lock, flags);
 434        if (dyn_tick->state & DYN_TICK_ENABLED) {
 435                next = next_timer_interrupt();
 436                do {
 437                        seq = read_seqbegin(&xtime_lock);
 438                        dyn_tick->reprogram(next - jiffies);
 439                } while (read_seqretry(&xtime_lock, seq));
 440        }
 441        spin_unlock_irqrestore(&dyn_tick->lock, flags);
 442}
 443
 444static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
 445{
 446        return sprintf(buf, "%i\n",
 447                       (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1);
 448}
 449
 450static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf,
 451                                  size_t count)
 452{
 453        unsigned int enable = simple_strtoul(buf, NULL, 2);
 454
 455        if (enable)
 456                timer_dyn_tick_enable();
 457        else
 458                timer_dyn_tick_disable();
 459
 460        return count;
 461}
 462static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick);
 463
 464/*
 465 * dyntick=enable|disable
 466 */
 467static char dyntick_str[4] __initdata = "";
 468
 469static int __init dyntick_setup(char *str)
 470{
 471        if (str)
 472                strlcpy(dyntick_str, str, sizeof(dyntick_str));
 473        return 1;
 474}
 475
 476__setup("dyntick=", dyntick_setup);
 477#endif
 478
 479static int __init timer_init_sysfs(void)
 480{
 481        int ret = sysdev_class_register(&timer_sysclass);
 482        if (ret == 0) {
 483                system_timer->dev.cls = &timer_sysclass;
 484                ret = sysdev_register(&system_timer->dev);
 485        }
 486
 487#ifdef CONFIG_NO_IDLE_HZ
 488        if (ret == 0 && system_timer->dyn_tick) {
 489                ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick);
 490
 491                /*
 492                 * Turn on dynamic tick after calibrate delay
 493                 * for correct bogomips
 494                 */
 495                if (ret == 0 && dyntick_str[0] == 'e')
 496                        ret = timer_dyn_tick_enable();
 497        }
 498#endif
 499
 500        return ret;
 501}
 502
 503device_initcall(timer_init_sysfs);
 504
 505void __init time_init(void)
 506{
 507#ifndef CONFIG_GENERIC_TIME
 508        if (system_timer->offset == NULL)
 509                system_timer->offset = dummy_gettimeoffset;
 510#endif
 511        system_timer->init();
 512
 513#ifdef CONFIG_NO_IDLE_HZ
 514        if (system_timer->dyn_tick)
 515                spin_lock_init(&system_timer->dyn_tick->lock);
 516#endif
 517}
 518
 519