0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/errno.h>
0011 #include <linux/sched.h>
0012 #include <linux/kernel.h>
0013 #include <linux/param.h>
0014 #include <linux/string.h>
0015 #include <linux/mm.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/time.h>
0018 #include <linux/timex.h>
0019 #include <linux/kernel_stat.h>
0020 #include <linux/mc146818rtc.h>
0021 #include <linux/init.h>
0022 #include <linux/bcd.h>
0023 #include <linux/ioport.h>
0024 #include <linux/of_address.h>
0025
0026 #include <asm/io.h>
0027 #include <asm/nvram.h>
0028 #include <asm/sections.h>
0029 #include <asm/time.h>
0030
0031 #include <platforms/chrp/chrp.h>
0032
0033 #define NVRAM_AS0 0x74
0034 #define NVRAM_AS1 0x75
0035 #define NVRAM_DATA 0x77
0036
0037 static int nvram_as1 = NVRAM_AS1;
0038 static int nvram_as0 = NVRAM_AS0;
0039 static int nvram_data = NVRAM_DATA;
0040
0041 long __init chrp_time_init(void)
0042 {
0043 struct device_node *rtcs;
0044 struct resource r;
0045 int base;
0046
0047 rtcs = of_find_compatible_node(NULL, "rtc", "pnpPNP,b00");
0048 if (rtcs == NULL)
0049 rtcs = of_find_compatible_node(NULL, "rtc", "ds1385-rtc");
0050 if (rtcs == NULL)
0051 return 0;
0052 if (of_address_to_resource(rtcs, 0, &r)) {
0053 of_node_put(rtcs);
0054 return 0;
0055 }
0056 of_node_put(rtcs);
0057
0058 base = r.start;
0059 nvram_as1 = 0;
0060 nvram_as0 = base;
0061 nvram_data = base + 1;
0062
0063 return 0;
0064 }
0065
0066 static int chrp_cmos_clock_read(int addr)
0067 {
0068 if (nvram_as1 != 0)
0069 outb(addr>>8, nvram_as1);
0070 outb(addr, nvram_as0);
0071 return (inb(nvram_data));
0072 }
0073
0074 static void chrp_cmos_clock_write(unsigned long val, int addr)
0075 {
0076 if (nvram_as1 != 0)
0077 outb(addr>>8, nvram_as1);
0078 outb(addr, nvram_as0);
0079 outb(val, nvram_data);
0080 return;
0081 }
0082
0083
0084
0085
0086 int chrp_set_rtc_time(struct rtc_time *tmarg)
0087 {
0088 unsigned char save_control, save_freq_select;
0089 struct rtc_time tm = *tmarg;
0090
0091 spin_lock(&rtc_lock);
0092
0093 save_control = chrp_cmos_clock_read(RTC_CONTROL);
0094
0095 chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
0096
0097 save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT);
0098
0099 chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
0100
0101 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
0102 tm.tm_sec = bin2bcd(tm.tm_sec);
0103 tm.tm_min = bin2bcd(tm.tm_min);
0104 tm.tm_hour = bin2bcd(tm.tm_hour);
0105 tm.tm_mon = bin2bcd(tm.tm_mon);
0106 tm.tm_mday = bin2bcd(tm.tm_mday);
0107 tm.tm_year = bin2bcd(tm.tm_year);
0108 }
0109 chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
0110 chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
0111 chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
0112 chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
0113 chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
0114 chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
0115
0116
0117
0118
0119
0120
0121
0122
0123 chrp_cmos_clock_write(save_control, RTC_CONTROL);
0124 chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
0125
0126 spin_unlock(&rtc_lock);
0127 return 0;
0128 }
0129
0130 void chrp_get_rtc_time(struct rtc_time *tm)
0131 {
0132 unsigned int year, mon, day, hour, min, sec;
0133
0134 do {
0135 sec = chrp_cmos_clock_read(RTC_SECONDS);
0136 min = chrp_cmos_clock_read(RTC_MINUTES);
0137 hour = chrp_cmos_clock_read(RTC_HOURS);
0138 day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
0139 mon = chrp_cmos_clock_read(RTC_MONTH);
0140 year = chrp_cmos_clock_read(RTC_YEAR);
0141 } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
0142
0143 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
0144 sec = bcd2bin(sec);
0145 min = bcd2bin(min);
0146 hour = bcd2bin(hour);
0147 day = bcd2bin(day);
0148 mon = bcd2bin(mon);
0149 year = bcd2bin(year);
0150 }
0151 if (year < 70)
0152 year += 100;
0153 tm->tm_sec = sec;
0154 tm->tm_min = min;
0155 tm->tm_hour = hour;
0156 tm->tm_mday = day;
0157 tm->tm_mon = mon;
0158 tm->tm_year = year;
0159 }