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