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/hwblk.h> 25 #include <asm/rtc.h> 26 27 /* Dummy RTC ops */ 28 static void null_rtc_get_time(struct timespec *tv) 29 { 30 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0); 31 tv->tv_nsec = 0; 32 } 33 34 static int null_rtc_set_time(const time_t secs) 35 { 36 return 0; 37 } 38 39 void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 40 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 41 42 #ifdef CONFIG_GENERIC_CMOS_UPDATE 43 unsigned long read_persistent_clock(void) 44 { 45 struct timespec tv; 46 rtc_sh_get_time(&tv); 47 return tv.tv_sec; 48 } 49 50 int update_persistent_clock(struct timespec now) 51 { 52 return rtc_sh_set_time(now.tv_sec); 53 } 54 #endif 55 56 unsigned int get_rtc_time(struct rtc_time *tm) 57 { 58 if (rtc_sh_get_time != null_rtc_get_time) { 59 struct timespec tv; 60 61 rtc_sh_get_time(&tv); 62 rtc_time_to_tm(tv.tv_sec, tm); 63 } 64 65 return RTC_24H; 66 } 67 EXPORT_SYMBOL(get_rtc_time); 68 69 int set_rtc_time(struct rtc_time *tm) 70 { 71 unsigned long secs; 72 73 rtc_tm_to_time(tm, &secs); 74 return rtc_sh_set_time(secs); 75 } 76 EXPORT_SYMBOL(set_rtc_time); 77 78 static int __init rtc_generic_init(void) 79 { 80 struct platform_device *pdev; 81 82 if (rtc_sh_get_time == null_rtc_get_time) 83 return -ENODEV; 84 85 pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); 86 if (IS_ERR(pdev)) 87 return PTR_ERR(pdev); 88 89 return 0; 90 } 91 module_init(rtc_generic_init); 92 93 void (*board_time_init)(void); 94 95 void __init time_init(void) 96 { 97 if (board_time_init) 98 board_time_init(); 99 100 hwblk_init(); 101 clk_init(); 102 103 rtc_sh_get_time(&xtime); 104 set_normalized_timespec(&wall_to_monotonic, 105 -xtime.tv_sec, -xtime.tv_nsec); 106 107 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 108 local_timer_setup(smp_processor_id()); 109 #endif 110 111 /* 112 * Make sure all compiled-in early timers register themselves. 113 * 114 * Run probe() for two "earlytimer" devices, these will be the 115 * clockevents and clocksource devices respectively. In the event 116 * that only a clockevents device is available, we -ENODEV on the 117 * clocksource and the jiffies clocksource is used transparently 118 * instead. No error handling is necessary here. 119 */ 120 early_platform_driver_register_all("earlytimer"); 121 early_platform_driver_probe("earlytimer", 2, 0); 122 } 123