| .. | .. |
|---|
| 13 | 13 | #include <linux/bcd.h> |
|---|
| 14 | 14 | #include <linux/rtc.h> |
|---|
| 15 | 15 | #include <linux/spinlock.h> |
|---|
| 16 | | -#include <asm/io.h> |
|---|
| 17 | | -#include <asm/rtc.h> |
|---|
| 16 | +#include <linux/io.h> |
|---|
| 17 | +#include <linux/rtc.h> |
|---|
| 18 | +#include <linux/platform_device.h> |
|---|
| 18 | 19 | |
|---|
| 19 | 20 | #define RTC_BASE 0xb0000000 |
|---|
| 20 | 21 | #define RTC_SEC1 (RTC_BASE + 0) |
|---|
| .. | .. |
|---|
| 38 | 39 | |
|---|
| 39 | 40 | static DEFINE_SPINLOCK(sh03_rtc_lock); |
|---|
| 40 | 41 | |
|---|
| 41 | | -unsigned long get_cmos_time(void) |
|---|
| 42 | +static int sh03_rtc_gettimeofday(struct device *dev, struct rtc_time *tm) |
|---|
| 42 | 43 | { |
|---|
| 43 | 44 | unsigned int year, mon, day, hour, min, sec; |
|---|
| 44 | 45 | |
|---|
| .. | .. |
|---|
| 75 | 76 | } |
|---|
| 76 | 77 | |
|---|
| 77 | 78 | spin_unlock(&sh03_rtc_lock); |
|---|
| 78 | | - return mktime(year, mon, day, hour, min, sec); |
|---|
| 79 | + |
|---|
| 80 | + tm->tm_sec = sec; |
|---|
| 81 | + tm->tm_min = min; |
|---|
| 82 | + tm->tm_hour = hour; |
|---|
| 83 | + tm->tm_mday = day; |
|---|
| 84 | + tm->tm_mon = mon; |
|---|
| 85 | + tm->tm_year = year - 1900; |
|---|
| 86 | + |
|---|
| 87 | + return 0; |
|---|
| 79 | 88 | } |
|---|
| 80 | 89 | |
|---|
| 81 | | -void sh03_rtc_gettimeofday(struct timespec *tv) |
|---|
| 82 | | -{ |
|---|
| 83 | | - |
|---|
| 84 | | - tv->tv_sec = get_cmos_time(); |
|---|
| 85 | | - tv->tv_nsec = 0; |
|---|
| 86 | | -} |
|---|
| 87 | | - |
|---|
| 88 | | -static int set_rtc_mmss(unsigned long nowtime) |
|---|
| 90 | +static int set_rtc_mmss(struct rtc_time *tm) |
|---|
| 89 | 91 | { |
|---|
| 90 | 92 | int retval = 0; |
|---|
| 91 | 93 | int real_seconds, real_minutes, cmos_minutes; |
|---|
| .. | .. |
|---|
| 97 | 99 | if (!(__raw_readb(RTC_CTL) & RTC_BUSY)) |
|---|
| 98 | 100 | break; |
|---|
| 99 | 101 | cmos_minutes = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10; |
|---|
| 100 | | - real_seconds = nowtime % 60; |
|---|
| 101 | | - real_minutes = nowtime / 60; |
|---|
| 102 | + real_seconds = tm->tm_sec; |
|---|
| 103 | + real_minutes = tm->tm_min; |
|---|
| 102 | 104 | if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) |
|---|
| 103 | 105 | real_minutes += 30; /* correct for half hour time zone */ |
|---|
| 104 | 106 | real_minutes %= 60; |
|---|
| .. | .. |
|---|
| 112 | 114 | printk_once(KERN_NOTICE |
|---|
| 113 | 115 | "set_rtc_mmss: can't update from %d to %d\n", |
|---|
| 114 | 116 | cmos_minutes, real_minutes); |
|---|
| 115 | | - retval = -1; |
|---|
| 117 | + retval = -EINVAL; |
|---|
| 116 | 118 | } |
|---|
| 117 | 119 | spin_unlock(&sh03_rtc_lock); |
|---|
| 118 | 120 | |
|---|
| 119 | 121 | return retval; |
|---|
| 120 | 122 | } |
|---|
| 121 | 123 | |
|---|
| 122 | | -int sh03_rtc_settimeofday(const time_t secs) |
|---|
| 124 | +int sh03_rtc_settimeofday(struct device *dev, struct rtc_time *tm) |
|---|
| 123 | 125 | { |
|---|
| 124 | | - unsigned long nowtime = secs; |
|---|
| 125 | | - |
|---|
| 126 | | - return set_rtc_mmss(nowtime); |
|---|
| 126 | + return set_rtc_mmss(tm); |
|---|
| 127 | 127 | } |
|---|
| 128 | 128 | |
|---|
| 129 | | -void sh03_time_init(void) |
|---|
| 129 | +static const struct rtc_class_ops rtc_generic_ops = { |
|---|
| 130 | + .read_time = sh03_rtc_gettimeofday, |
|---|
| 131 | + .set_time = sh03_rtc_settimeofday, |
|---|
| 132 | +}; |
|---|
| 133 | + |
|---|
| 134 | +static int __init sh03_time_init(void) |
|---|
| 130 | 135 | { |
|---|
| 131 | | - rtc_sh_get_time = sh03_rtc_gettimeofday; |
|---|
| 132 | | - rtc_sh_set_time = sh03_rtc_settimeofday; |
|---|
| 136 | + struct platform_device *pdev; |
|---|
| 137 | + |
|---|
| 138 | + pdev = platform_device_register_data(NULL, "rtc-generic", -1, |
|---|
| 139 | + &rtc_generic_ops, |
|---|
| 140 | + sizeof(rtc_generic_ops)); |
|---|
| 141 | + |
|---|
| 142 | + return PTR_ERR_OR_ZERO(pdev); |
|---|
| 133 | 143 | } |
|---|
| 144 | +arch_initcall(sh03_time_init); |
|---|