Merge tag 'tegra-for-4.8-i2c' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra...
[cascardo/linux.git] / drivers / rtc / rtc-mc146818-lib.c
1 #include <linux/bcd.h>
2 #include <linux/delay.h>
3 #include <linux/export.h>
4 #include <linux/mc146818rtc.h>
5
6 #ifdef CONFIG_ACPI
7 #include <linux/acpi.h>
8 #endif
9
10 /*
11  * Returns true if a clock update is in progress
12  */
13 static inline unsigned char mc146818_is_updating(void)
14 {
15         unsigned char uip;
16         unsigned long flags;
17
18         spin_lock_irqsave(&rtc_lock, flags);
19         uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
20         spin_unlock_irqrestore(&rtc_lock, flags);
21         return uip;
22 }
23
24 unsigned int mc146818_get_time(struct rtc_time *time)
25 {
26         unsigned char ctrl;
27         unsigned long flags;
28         unsigned char century = 0;
29
30 #ifdef CONFIG_MACH_DECSTATION
31         unsigned int real_year;
32 #endif
33
34         /*
35          * read RTC once any update in progress is done. The update
36          * can take just over 2ms. We wait 20ms. There is no need to
37          * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
38          * If you need to know *exactly* when a second has started, enable
39          * periodic update complete interrupts, (via ioctl) and then
40          * immediately read /dev/rtc which will block until you get the IRQ.
41          * Once the read clears, read the RTC time (again via ioctl). Easy.
42          */
43         if (mc146818_is_updating())
44                 mdelay(20);
45
46         /*
47          * Only the values that we read from the RTC are set. We leave
48          * tm_wday, tm_yday and tm_isdst untouched. Even though the
49          * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
50          * by the RTC when initially set to a non-zero value.
51          */
52         spin_lock_irqsave(&rtc_lock, flags);
53         time->tm_sec = CMOS_READ(RTC_SECONDS);
54         time->tm_min = CMOS_READ(RTC_MINUTES);
55         time->tm_hour = CMOS_READ(RTC_HOURS);
56         time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
57         time->tm_mon = CMOS_READ(RTC_MONTH);
58         time->tm_year = CMOS_READ(RTC_YEAR);
59 #ifdef CONFIG_MACH_DECSTATION
60         real_year = CMOS_READ(RTC_DEC_YEAR);
61 #endif
62 #ifdef CONFIG_ACPI
63         if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
64             acpi_gbl_FADT.century)
65                 century = CMOS_READ(acpi_gbl_FADT.century);
66 #endif
67         ctrl = CMOS_READ(RTC_CONTROL);
68         spin_unlock_irqrestore(&rtc_lock, flags);
69
70         if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
71         {
72                 time->tm_sec = bcd2bin(time->tm_sec);
73                 time->tm_min = bcd2bin(time->tm_min);
74                 time->tm_hour = bcd2bin(time->tm_hour);
75                 time->tm_mday = bcd2bin(time->tm_mday);
76                 time->tm_mon = bcd2bin(time->tm_mon);
77                 time->tm_year = bcd2bin(time->tm_year);
78                 century = bcd2bin(century);
79         }
80
81 #ifdef CONFIG_MACH_DECSTATION
82         time->tm_year += real_year - 72;
83 #endif
84
85         if (century)
86                 time->tm_year += (century - 19) * 100;
87
88         /*
89          * Account for differences between how the RTC uses the values
90          * and how they are defined in a struct rtc_time;
91          */
92         if (time->tm_year <= 69)
93                 time->tm_year += 100;
94
95         time->tm_mon--;
96
97         return RTC_24H;
98 }
99 EXPORT_SYMBOL_GPL(mc146818_get_time);
100
101 /* Set the current date and time in the real time clock. */
102 int mc146818_set_time(struct rtc_time *time)
103 {
104         unsigned long flags;
105         unsigned char mon, day, hrs, min, sec;
106         unsigned char save_control, save_freq_select;
107         unsigned int yrs;
108 #ifdef CONFIG_MACH_DECSTATION
109         unsigned int real_yrs, leap_yr;
110 #endif
111         unsigned char century = 0;
112
113         yrs = time->tm_year;
114         mon = time->tm_mon + 1;   /* tm_mon starts at zero */
115         day = time->tm_mday;
116         hrs = time->tm_hour;
117         min = time->tm_min;
118         sec = time->tm_sec;
119
120         if (yrs > 255)  /* They are unsigned */
121                 return -EINVAL;
122
123         spin_lock_irqsave(&rtc_lock, flags);
124 #ifdef CONFIG_MACH_DECSTATION
125         real_yrs = yrs;
126         leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
127                         !((yrs + 1900) % 400));
128         yrs = 72;
129
130         /*
131          * We want to keep the year set to 73 until March
132          * for non-leap years, so that Feb, 29th is handled
133          * correctly.
134          */
135         if (!leap_yr && mon < 3) {
136                 real_yrs--;
137                 yrs = 73;
138         }
139 #endif
140
141 #ifdef CONFIG_ACPI
142         if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
143             acpi_gbl_FADT.century) {
144                 century = (yrs + 1900) / 100;
145                 yrs %= 100;
146         }
147 #endif
148
149         /* These limits and adjustments are independent of
150          * whether the chip is in binary mode or not.
151          */
152         if (yrs > 169) {
153                 spin_unlock_irqrestore(&rtc_lock, flags);
154                 return -EINVAL;
155         }
156
157         if (yrs >= 100)
158                 yrs -= 100;
159
160         if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
161             || RTC_ALWAYS_BCD) {
162                 sec = bin2bcd(sec);
163                 min = bin2bcd(min);
164                 hrs = bin2bcd(hrs);
165                 day = bin2bcd(day);
166                 mon = bin2bcd(mon);
167                 yrs = bin2bcd(yrs);
168                 century = bin2bcd(century);
169         }
170
171         save_control = CMOS_READ(RTC_CONTROL);
172         CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
173         save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
174         CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
175
176 #ifdef CONFIG_MACH_DECSTATION
177         CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
178 #endif
179         CMOS_WRITE(yrs, RTC_YEAR);
180         CMOS_WRITE(mon, RTC_MONTH);
181         CMOS_WRITE(day, RTC_DAY_OF_MONTH);
182         CMOS_WRITE(hrs, RTC_HOURS);
183         CMOS_WRITE(min, RTC_MINUTES);
184         CMOS_WRITE(sec, RTC_SECONDS);
185 #ifdef CONFIG_ACPI
186         if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
187             acpi_gbl_FADT.century)
188                 CMOS_WRITE(century, acpi_gbl_FADT.century);
189 #endif
190
191         CMOS_WRITE(save_control, RTC_CONTROL);
192         CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
193
194         spin_unlock_irqrestore(&rtc_lock, flags);
195
196         return 0;
197 }
198 EXPORT_SYMBOL_GPL(mc146818_set_time);