Blame view
include/asm-generic/rtc.h
5.33 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
f30c22695 fix file specific... |
2 |
* include/asm-generic/rtc.h |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 11 12 13 |
* * Author: Tom Rini <trini@mvista.com> * * Based on: * drivers/char/rtc.c * * Please read the COPYING file for all license details. */ #ifndef __ASM_RTC_H__ #define __ASM_RTC_H__ |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 |
#include <linux/mc146818rtc.h> #include <linux/rtc.h> #include <linux/bcd.h> |
38c052f8c rtc: fix deadlock |
17 |
#include <linux/delay.h> |
1da177e4c Linux-2.6.12-rc2 |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#define RTC_PIE 0x40 /* periodic interrupt enable */ #define RTC_AIE 0x20 /* alarm interrupt enable */ #define RTC_UIE 0x10 /* update-finished interrupt enable */ /* some dummy definitions */ #define RTC_BATT_BAD 0x100 /* battery bad */ #define RTC_SQWE 0x08 /* enable square-wave output */ #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ /* * Returns true if a clock update is in progress */ static inline unsigned char rtc_is_updating(void) { unsigned char uip; |
795d45b22 x86: fix RTC lock... |
36 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
37 |
|
795d45b22 x86: fix RTC lock... |
38 |
spin_lock_irqsave(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
39 |
uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); |
795d45b22 x86: fix RTC lock... |
40 |
spin_unlock_irqrestore(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
41 42 |
return uip; } |
5f7dc5d75 alpha: fix RTC on... |
43 |
static inline unsigned int __get_rtc_time(struct rtc_time *time) |
1da177e4c Linux-2.6.12-rc2 |
44 |
{ |
1da177e4c Linux-2.6.12-rc2 |
45 |
unsigned char ctrl; |
795d45b22 x86: fix RTC lock... |
46 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 50 51 52 |
#ifdef CONFIG_MACH_DECSTATION unsigned int real_year; #endif /* * read RTC once any update in progress is done. The update |
38c052f8c rtc: fix deadlock |
53 |
* can take just over 2ms. We wait 20ms. There is no need to |
1da177e4c Linux-2.6.12-rc2 |
54 55 56 57 58 59 |
* to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. * If you need to know *exactly* when a second has started, enable * periodic update complete interrupts, (via ioctl) and then * immediately read /dev/rtc which will block until you get the IRQ. * Once the read clears, read the RTC time (again via ioctl). Easy. */ |
38c052f8c rtc: fix deadlock |
60 61 |
if (rtc_is_updating()) mdelay(20); |
1da177e4c Linux-2.6.12-rc2 |
62 63 64 65 66 67 68 |
/* * Only the values that we read from the RTC are set. We leave * tm_wday, tm_yday and tm_isdst untouched. Even though the * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated * by the RTC when initially set to a non-zero value. */ |
795d45b22 x86: fix RTC lock... |
69 |
spin_lock_irqsave(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
70 71 72 73 74 75 76 77 78 79 |
time->tm_sec = CMOS_READ(RTC_SECONDS); time->tm_min = CMOS_READ(RTC_MINUTES); time->tm_hour = CMOS_READ(RTC_HOURS); time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); time->tm_mon = CMOS_READ(RTC_MONTH); time->tm_year = CMOS_READ(RTC_YEAR); #ifdef CONFIG_MACH_DECSTATION real_year = CMOS_READ(RTC_DEC_YEAR); #endif ctrl = CMOS_READ(RTC_CONTROL); |
795d45b22 x86: fix RTC lock... |
80 |
spin_unlock_irqrestore(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
81 82 83 |
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
357c6e635 rtc: use bcd2bin/... |
84 85 86 87 88 89 |
time->tm_sec = bcd2bin(time->tm_sec); time->tm_min = bcd2bin(time->tm_min); time->tm_hour = bcd2bin(time->tm_hour); time->tm_mday = bcd2bin(time->tm_mday); time->tm_mon = bcd2bin(time->tm_mon); time->tm_year = bcd2bin(time->tm_year); |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
} #ifdef CONFIG_MACH_DECSTATION time->tm_year += real_year - 72; #endif /* * Account for differences between how the RTC uses the values * and how they are defined in a struct rtc_time; */ if (time->tm_year <= 69) time->tm_year += 100; time->tm_mon--; return RTC_24H; } |
5f7dc5d75 alpha: fix RTC on... |
107 108 109 |
#ifndef get_rtc_time #define get_rtc_time __get_rtc_time #endif |
1da177e4c Linux-2.6.12-rc2 |
110 |
/* Set the current date and time in the real time clock. */ |
5f7dc5d75 alpha: fix RTC on... |
111 |
static inline int __set_rtc_time(struct rtc_time *time) |
1da177e4c Linux-2.6.12-rc2 |
112 |
{ |
eb71c87a4 Add some basic re... |
113 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
unsigned char mon, day, hrs, min, sec; unsigned char save_control, save_freq_select; unsigned int yrs; #ifdef CONFIG_MACH_DECSTATION unsigned int real_yrs, leap_yr; #endif yrs = time->tm_year; mon = time->tm_mon + 1; /* tm_mon starts at zero */ day = time->tm_mday; hrs = time->tm_hour; min = time->tm_min; sec = time->tm_sec; if (yrs > 255) /* They are unsigned */ return -EINVAL; |
eb71c87a4 Add some basic re... |
130 |
spin_lock_irqsave(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
#ifdef CONFIG_MACH_DECSTATION real_yrs = yrs; leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) || !((yrs + 1900) % 400)); yrs = 72; /* * We want to keep the year set to 73 until March * for non-leap years, so that Feb, 29th is handled * correctly. */ if (!leap_yr && mon < 3) { real_yrs--; yrs = 73; } #endif /* These limits and adjustments are independent of * whether the chip is in binary mode or not. */ if (yrs > 169) { |
eb71c87a4 Add some basic re... |
151 |
spin_unlock_irqrestore(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 155 156 157 158 159 |
return -EINVAL; } if (yrs >= 100) yrs -= 100; if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
357c6e635 rtc: use bcd2bin/... |
160 161 162 163 164 165 |
sec = bin2bcd(sec); min = bin2bcd(min); hrs = bin2bcd(hrs); day = bin2bcd(day); mon = bin2bcd(mon); yrs = bin2bcd(yrs); |
1da177e4c Linux-2.6.12-rc2 |
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
} save_control = CMOS_READ(RTC_CONTROL); CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); save_freq_select = CMOS_READ(RTC_FREQ_SELECT); CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); #ifdef CONFIG_MACH_DECSTATION CMOS_WRITE(real_yrs, RTC_DEC_YEAR); #endif CMOS_WRITE(yrs, RTC_YEAR); CMOS_WRITE(mon, RTC_MONTH); CMOS_WRITE(day, RTC_DAY_OF_MONTH); CMOS_WRITE(hrs, RTC_HOURS); CMOS_WRITE(min, RTC_MINUTES); CMOS_WRITE(sec, RTC_SECONDS); CMOS_WRITE(save_control, RTC_CONTROL); CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); |
eb71c87a4 Add some basic re... |
185 |
spin_unlock_irqrestore(&rtc_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
186 187 188 |
return 0; } |
5f7dc5d75 alpha: fix RTC on... |
189 190 191 |
#ifndef set_rtc_time #define set_rtc_time __set_rtc_time #endif |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 |
static inline unsigned int get_rtc_ss(void) { struct rtc_time h; |
3aef39282 asm-generic: make... |
195 |
get_rtc_time(&h); |
1da177e4c Linux-2.6.12-rc2 |
196 197 198 199 200 201 202 203 204 205 206 |
return h.tm_sec; } static inline int get_rtc_pll(struct rtc_pll_info *pll) { return -EINVAL; } static inline int set_rtc_pll(struct rtc_pll_info *pll) { return -EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
207 |
#endif /* __ASM_RTC_H__ */ |