1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * arch/sh/kernel/time.c 4 * 5 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka 6 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 7 * Copyright (C) 2002 - 2009 Paul Mundt 8 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> 9 */ 10 #include <linux/kernel.h> 11 #include <linux/init.h> 12 #include <linux/profile.h> 13 #include <linux/timex.h> 14 #include <linux/sched.h> 15 #include <linux/clockchips.h> 16 #include <linux/platform_device.h> 17 #include <linux/smp.h> 18 #include <linux/rtc.h> 19 #include <asm/clock.h> 20 #include <asm/rtc.h> 21 22 /* Dummy RTC ops */ 23 static void null_rtc_get_time(struct timespec *tv) 24 { 25 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0); 26 tv->tv_nsec = 0; 27 } 28 29 static int null_rtc_set_time(const time_t secs) 30 { 31 return 0; 32 } 33 34 void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 35 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 36 37 void read_persistent_clock(struct timespec *ts) 38 { 39 rtc_sh_get_time(ts); 40 } 41 42 #ifdef CONFIG_GENERIC_CMOS_UPDATE 43 int update_persistent_clock(struct timespec now) 44 { 45 return rtc_sh_set_time(now.tv_sec); 46 } 47 #endif 48 49 static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) 50 { 51 struct timespec tv; 52 53 rtc_sh_get_time(&tv); 54 rtc_time_to_tm(tv.tv_sec, tm); 55 return 0; 56 } 57 58 static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) 59 { 60 unsigned long secs; 61 62 rtc_tm_to_time(tm, &secs); 63 if ((rtc_sh_set_time == null_rtc_set_time) || 64 (rtc_sh_set_time(secs) < 0)) 65 return -EOPNOTSUPP; 66 67 return 0; 68 } 69 70 static const struct rtc_class_ops rtc_generic_ops = { 71 .read_time = rtc_generic_get_time, 72 .set_time = rtc_generic_set_time, 73 }; 74 75 static 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_data(NULL, "rtc-generic", -1, 83 &rtc_generic_ops, 84 sizeof(rtc_generic_ops)); 85 86 87 return PTR_ERR_OR_ZERO(pdev); 88 } 89 device_initcall(rtc_generic_init); 90 91 void (*board_time_init)(void); 92 93 static void __init sh_late_time_init(void) 94 { 95 /* 96 * Make sure all compiled-in early timers register themselves. 97 * 98 * Run probe() for two "earlytimer" devices, these will be the 99 * clockevents and clocksource devices respectively. In the event 100 * that only a clockevents device is available, we -ENODEV on the 101 * clocksource and the jiffies clocksource is used transparently 102 * instead. No error handling is necessary here. 103 */ 104 early_platform_driver_register_all("earlytimer"); 105 early_platform_driver_probe("earlytimer", 2, 0); 106 } 107 108 void __init time_init(void) 109 { 110 if (board_time_init) 111 board_time_init(); 112 113 clk_init(); 114 115 late_time_init = sh_late_time_init; 116 } 117