]> err.no Git - linux-2.6/blobdiff - arch/sparc64/kernel/time.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / arch / sparc64 / kernel / time.c
index e340eb401fb956642028b4eb8f912989487e2378..69cad1b653c14f55a57a2ec5ad0a5e2abf5ad801 100644 (file)
@@ -403,58 +403,9 @@ static struct sparc64_tick_ops hbtick_operations __read_mostly = {
 
 static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
 
-#define TICK_SIZE (tick_nsec / 1000)
-
-#define USEC_AFTER     500000
-#define USEC_BEFORE    500000
-
-static void sync_cmos_clock(unsigned long dummy);
-
-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
-
-static void sync_cmos_clock(unsigned long dummy)
+int update_persistent_clock(struct timespec now)
 {
-       struct timeval now, next;
-       int fail = 1;
-
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        * This code is run on a timer.  If the clock is set, that timer
-        * may not expire at the correct time.  Thus, we adjust...
-        */
-       if (!ntp_synced())
-               /*
-                * Not synced, exit, do not restart a timer (if one is
-                * running, let it run out).
-                */
-               return;
-
-       do_gettimeofday(&now);
-       if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
-           now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2)
-               fail = set_rtc_mmss(now.tv_sec);
-
-       next.tv_usec = USEC_AFTER - now.tv_usec;
-       if (next.tv_usec <= 0)
-               next.tv_usec += USEC_PER_SEC;
-
-       if (!fail)
-               next.tv_sec = 659;
-       else
-               next.tv_sec = 0;
-
-       if (next.tv_usec >= USEC_PER_SEC) {
-               next.tv_sec++;
-               next.tv_usec -= USEC_PER_SEC;
-       }
-       mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next));
-}
-
-void notify_arch_cmos_timer(void)
-{
-       mod_timer(&sync_cmos_timer, jiffies + 1);
+       return set_rtc_mmss(now.tv_sec);
 }
 
 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
@@ -931,6 +882,7 @@ static void sparc64_timer_setup(enum clock_event_mode mode,
 {
        switch (mode) {
        case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_RESUME:
                break;
 
        case CLOCK_EVT_MODE_SHUTDOWN:
@@ -1508,6 +1460,74 @@ static int cmos_set_rtc_time(struct rtc_time *rtc_tm)
 }
 #endif /* CONFIG_PCI */
 
+static void mostek_get_rtc_time(struct rtc_time *rtc_tm)
+{
+       void __iomem *regs = mstk48t02_regs;
+       u8 tmp;
+
+       spin_lock_irq(&mostek_lock);
+
+       tmp = mostek_read(regs + MOSTEK_CREG);
+       tmp |= MSTK_CREG_READ;
+       mostek_write(regs + MOSTEK_CREG, tmp);
+
+       rtc_tm->tm_sec = MSTK_REG_SEC(regs);
+       rtc_tm->tm_min = MSTK_REG_MIN(regs);
+       rtc_tm->tm_hour = MSTK_REG_HOUR(regs);
+       rtc_tm->tm_mday = MSTK_REG_DOM(regs);
+       rtc_tm->tm_mon = MSTK_REG_MONTH(regs);
+       rtc_tm->tm_year = MSTK_CVT_YEAR( MSTK_REG_YEAR(regs) );
+       rtc_tm->tm_wday = MSTK_REG_DOW(regs);
+
+       tmp = mostek_read(regs + MOSTEK_CREG);
+       tmp &= ~MSTK_CREG_READ;
+       mostek_write(regs + MOSTEK_CREG, tmp);
+
+       spin_unlock_irq(&mostek_lock);
+
+       rtc_tm->tm_mon--;
+       rtc_tm->tm_wday--;
+       rtc_tm->tm_year -= 1900;
+}
+
+static int mostek_set_rtc_time(struct rtc_time *rtc_tm)
+{
+       unsigned char mon, day, hrs, min, sec, wday;
+       void __iomem *regs = mstk48t02_regs;
+       unsigned int yrs;
+       u8 tmp;
+
+       yrs = rtc_tm->tm_year + 1900;
+       mon = rtc_tm->tm_mon + 1;
+       day = rtc_tm->tm_mday;
+       wday = rtc_tm->tm_wday + 1;
+       hrs = rtc_tm->tm_hour;
+       min = rtc_tm->tm_min;
+       sec = rtc_tm->tm_sec;
+
+       spin_lock_irq(&mostek_lock);
+
+       tmp = mostek_read(regs + MOSTEK_CREG);
+       tmp |= MSTK_CREG_WRITE;
+       mostek_write(regs + MOSTEK_CREG, tmp);
+
+       MSTK_SET_REG_SEC(regs, sec);
+       MSTK_SET_REG_MIN(regs, min);
+       MSTK_SET_REG_HOUR(regs, hrs);
+       MSTK_SET_REG_DOW(regs, wday);
+       MSTK_SET_REG_DOM(regs, day);
+       MSTK_SET_REG_MONTH(regs, mon);
+       MSTK_SET_REG_YEAR(regs, yrs - MSTK_YEAR_ZERO);
+
+       tmp = mostek_read(regs + MOSTEK_CREG);
+       tmp &= ~MSTK_CREG_WRITE;
+       mostek_write(regs + MOSTEK_CREG, tmp);
+
+       spin_unlock_irq(&mostek_lock);
+
+       return 0;
+}
+
 struct mini_rtc_ops {
        void (*get_rtc_time)(struct rtc_time *);
        int (*set_rtc_time)(struct rtc_time *);
@@ -1535,6 +1555,11 @@ static struct mini_rtc_ops cmos_rtc_ops = {
 };
 #endif /* CONFIG_PCI */
 
+static struct mini_rtc_ops mostek_rtc_ops = {
+       .get_rtc_time = mostek_get_rtc_time,
+       .set_rtc_time = mostek_set_rtc_time,
+};
+
 static struct mini_rtc_ops *mini_rtc_ops;
 
 static inline void mini_get_rtc_time(struct rtc_time *time)
@@ -1663,6 +1688,8 @@ static int __init rtc_mini_init(void)
        else if (ds1287_regs)
                mini_rtc_ops = &cmos_rtc_ops;
 #endif /* CONFIG_PCI */
+       else if (mstk48t02_regs)
+               mini_rtc_ops = &mostek_rtc_ops;
        else
                return -ENODEV;