1 /* 2 * arch/sh/kernel/time_32.c 3 * 4 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka 5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 6 * Copyright (C) 2002 - 2009 Paul Mundt 7 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> 8 * 9 * Some code taken from i386 version. 10 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 11 */ 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/profile.h> 16 #include <linux/timex.h> 17 #include <linux/sched.h> 18 #include <linux/clockchips.h> 19 #include <linux/mc146818rtc.h> /* for rtc_lock */ 20 #include <linux/platform_device.h> 21 #include <linux/smp.h> 22 #include <linux/rtc.h> 23 #include <asm/clock.h> 24 #include <asm/rtc.h> 25 #include <asm/timer.h> 26 #include <asm/kgdb.h> 27 28 struct sys_timer *sys_timer; 29 30 /* Move this somewhere more sensible.. */ 31 DEFINE_SPINLOCK(rtc_lock); 32 EXPORT_SYMBOL(rtc_lock); 33 34 /* Dummy RTC ops */ 35 static void null_rtc_get_time(struct timespec *tv) 36 { 37 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0); 38 tv->tv_nsec = 0; 39 } 40 41 static int null_rtc_set_time(const time_t secs) 42 { 43 return 0; 44 } 45 46 void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 47 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 48 49 #ifdef CONFIG_GENERIC_CMOS_UPDATE 50 unsigned long read_persistent_clock(void) 51 { 52 struct timespec tv; 53 rtc_sh_get_time(&tv); 54 return tv.tv_sec; 55 } 56 57 int update_persistent_clock(struct timespec now) 58 { 59 return rtc_sh_set_time(now.tv_sec); 60 } 61 #endif 62 63 unsigned int get_rtc_time(struct rtc_time *tm) 64 { 65 if (rtc_sh_get_time != null_rtc_get_time) { 66 struct timespec tv; 67 68 rtc_sh_get_time(&tv); 69 rtc_time_to_tm(tv.tv_sec, tm); 70 } 71 72 return RTC_24H; 73 } 74 EXPORT_SYMBOL(get_rtc_time); 75 76 int set_rtc_time(struct rtc_time *tm) 77 { 78 unsigned long secs; 79 80 rtc_tm_to_time(tm, &secs); 81 return rtc_sh_set_time(secs); 82 } 83 EXPORT_SYMBOL(set_rtc_time); 84 85 static int __init rtc_generic_init(void) 86 { 87 struct platform_device *pdev; 88 89 if (rtc_sh_get_time == null_rtc_get_time) 90 return -ENODEV; 91 92 pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); 93 if (IS_ERR(pdev)) 94 return PTR_ERR(pdev); 95 96 return 0; 97 } 98 module_init(rtc_generic_init); 99 100 /* last time the RTC clock got updated */ 101 static long last_rtc_update; 102 103 /* 104 * handle_timer_tick() needs to keep up the real-time clock, 105 * as well as call the "do_timer()" routine every clocktick 106 */ 107 void handle_timer_tick(void) 108 { 109 if (current->pid) 110 profile_tick(CPU_PROFILING); 111 112 /* 113 * Here we are in the timer irq handler. We just have irqs locally 114 * disabled but we don't know if the timer_bh is running on the other 115 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need 116 * the irq version of write_lock because as just said we have irq 117 * locally disabled. -arca 118 */ 119 write_seqlock(&xtime_lock); 120 do_timer(1); 121 122 /* 123 * If we have an externally synchronized Linux clock, then update 124 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 125 * called as close as possible to 500 ms before the new second starts. 126 */ 127 if (ntp_synced() && 128 xtime.tv_sec > last_rtc_update + 660 && 129 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && 130 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { 131 if (rtc_sh_set_time(xtime.tv_sec) == 0) 132 last_rtc_update = xtime.tv_sec; 133 else 134 /* do it again in 60s */ 135 last_rtc_update = xtime.tv_sec - 600; 136 } 137 write_sequnlock(&xtime_lock); 138 139 #ifndef CONFIG_SMP 140 update_process_times(user_mode(get_irq_regs())); 141 #endif 142 } 143 144 #ifdef CONFIG_PM 145 int timer_suspend(struct sys_device *dev, pm_message_t state) 146 { 147 struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev); 148 149 sys_timer->ops->stop(); 150 151 return 0; 152 } 153 154 int timer_resume(struct sys_device *dev) 155 { 156 struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev); 157 158 sys_timer->ops->start(); 159 160 return 0; 161 } 162 #else 163 #define timer_suspend NULL 164 #define timer_resume NULL 165 #endif 166 167 static struct sysdev_class timer_sysclass = { 168 .name = "timer", 169 .suspend = timer_suspend, 170 .resume = timer_resume, 171 }; 172 173 static int __init timer_init_sysfs(void) 174 { 175 int ret; 176 177 if (!sys_timer) 178 return 0; 179 180 ret = sysdev_class_register(&timer_sysclass); 181 if (ret != 0) 182 return ret; 183 184 sys_timer->dev.cls = &timer_sysclass; 185 return sysdev_register(&sys_timer->dev); 186 } 187 device_initcall(timer_init_sysfs); 188 189 void (*board_time_init)(void); 190 191 struct clocksource clocksource_sh = { 192 .name = "SuperH", 193 }; 194 195 unsigned long long sched_clock(void) 196 { 197 unsigned long long cycles; 198 199 /* jiffies based sched_clock if no clocksource is installed */ 200 if (!clocksource_sh.rating) 201 return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ); 202 203 cycles = clocksource_sh.read(&clocksource_sh); 204 return cyc2ns(&clocksource_sh, cycles); 205 } 206 207 static void __init sh_late_time_init(void) 208 { 209 /* 210 * Make sure all compiled-in early timers register themselves. 211 * Run probe() for one "earlytimer" device. 212 */ 213 early_platform_driver_register_all("earlytimer"); 214 if (early_platform_driver_probe("earlytimer", 1, 0)) 215 return; 216 217 /* 218 * Find the timer to use as the system timer, it will be 219 * initialized for us. 220 */ 221 sys_timer = get_sys_timer(); 222 if (unlikely(!sys_timer)) 223 panic("System timer missing.\n"); 224 225 printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); 226 } 227 228 void __init time_init(void) 229 { 230 if (board_time_init) 231 board_time_init(); 232 233 clk_init(); 234 235 rtc_sh_get_time(&xtime); 236 set_normalized_timespec(&wall_to_monotonic, 237 -xtime.tv_sec, -xtime.tv_nsec); 238 239 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 240 local_timer_setup(smp_processor_id()); 241 #endif 242 243 late_time_init = sh_late_time_init; 244 } 245 246