1 /* 2 * arch/sh/kernel/time.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 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file "COPYING" in the main directory of this archive 11 * for more details. 12 */ 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/profile.h> 17 #include <linux/timex.h> 18 #include <linux/sched.h> 19 #include <linux/clockchips.h> 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 27 struct sys_timer *sys_timer; 28 29 /* Dummy RTC ops */ 30 static void null_rtc_get_time(struct timespec *tv) 31 { 32 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0); 33 tv->tv_nsec = 0; 34 } 35 36 static int null_rtc_set_time(const time_t secs) 37 { 38 return 0; 39 } 40 41 void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 42 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 43 44 #ifdef CONFIG_GENERIC_CMOS_UPDATE 45 unsigned long read_persistent_clock(void) 46 { 47 struct timespec tv; 48 rtc_sh_get_time(&tv); 49 return tv.tv_sec; 50 } 51 52 int update_persistent_clock(struct timespec now) 53 { 54 return rtc_sh_set_time(now.tv_sec); 55 } 56 #endif 57 58 unsigned int get_rtc_time(struct rtc_time *tm) 59 { 60 if (rtc_sh_get_time != null_rtc_get_time) { 61 struct timespec tv; 62 63 rtc_sh_get_time(&tv); 64 rtc_time_to_tm(tv.tv_sec, tm); 65 } 66 67 return RTC_24H; 68 } 69 EXPORT_SYMBOL(get_rtc_time); 70 71 int set_rtc_time(struct rtc_time *tm) 72 { 73 unsigned long secs; 74 75 rtc_tm_to_time(tm, &secs); 76 return rtc_sh_set_time(secs); 77 } 78 EXPORT_SYMBOL(set_rtc_time); 79 80 static int __init rtc_generic_init(void) 81 { 82 struct platform_device *pdev; 83 84 if (rtc_sh_get_time == null_rtc_get_time) 85 return -ENODEV; 86 87 pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); 88 if (IS_ERR(pdev)) 89 return PTR_ERR(pdev); 90 91 return 0; 92 } 93 module_init(rtc_generic_init); 94 95 void (*board_time_init)(void); 96 97 struct clocksource clocksource_sh = { 98 .name = "SuperH", 99 }; 100 101 unsigned long long sched_clock(void) 102 { 103 unsigned long long cycles; 104 105 /* jiffies based sched_clock if no clocksource is installed */ 106 if (!clocksource_sh.rating) 107 return (jiffies_64 - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ); 108 109 cycles = clocksource_sh.read(&clocksource_sh); 110 return cyc2ns(&clocksource_sh, cycles); 111 } 112 113 static void __init sh_late_time_init(void) 114 { 115 /* 116 * Make sure all compiled-in early timers register themselves. 117 * Run probe() for one "earlytimer" device. 118 */ 119 early_platform_driver_register_all("earlytimer"); 120 if (early_platform_driver_probe("earlytimer", 1, 0)) 121 return; 122 123 /* 124 * Find the timer to use as the system timer, it will be 125 * initialized for us. 126 */ 127 sys_timer = get_sys_timer(); 128 if (unlikely(!sys_timer)) 129 panic("System timer missing.\n"); 130 131 printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); 132 } 133 134 void __init time_init(void) 135 { 136 if (board_time_init) 137 board_time_init(); 138 139 clk_init(); 140 141 rtc_sh_get_time(&xtime); 142 set_normalized_timespec(&wall_to_monotonic, 143 -xtime.tv_sec, -xtime.tv_nsec); 144 145 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 146 local_timer_setup(smp_processor_id()); 147 #endif 148 149 late_time_init = sh_late_time_init; 150 } 151