xref: /openbmc/linux/arch/m68k/atari/time.c (revision 3d92e8f3)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * linux/arch/m68k/atari/time.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Atari time and real time clock stuff
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * This file is subject to the terms and conditions of the GNU General Public
91da177e4SLinus Torvalds  * License.  See the file COPYING in the main directory of this archive
101da177e4SLinus Torvalds  * for more details.
111da177e4SLinus Torvalds  */
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds #include <linux/types.h>
141da177e4SLinus Torvalds #include <linux/mc146818rtc.h>
151da177e4SLinus Torvalds #include <linux/interrupt.h>
161da177e4SLinus Torvalds #include <linux/init.h>
171da177e4SLinus Torvalds #include <linux/rtc.h>
181da177e4SLinus Torvalds #include <linux/bcd.h>
1969961c37SGeert Uytterhoeven #include <linux/delay.h>
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds #include <asm/atariints.h>
221da177e4SLinus Torvalds 
237ae4833aSGeert Uytterhoeven DEFINE_SPINLOCK(rtc_lock);
247ae4833aSGeert Uytterhoeven EXPORT_SYMBOL_GPL(rtc_lock);
257ae4833aSGeert Uytterhoeven 
261da177e4SLinus Torvalds void __init
2740220c1aSDavid Howells atari_sched_init(irq_handler_t timer_routine)
281da177e4SLinus Torvalds {
291da177e4SLinus Torvalds     /* set Timer C data Register */
303d92e8f3SGeert Uytterhoeven     st_mfp.tim_dt_c = INT_TICKS;
311da177e4SLinus Torvalds     /* start timer C, div = 1:100 */
323d92e8f3SGeert Uytterhoeven     st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 15) | 0x60;
331da177e4SLinus Torvalds     /* install interrupt service routine for MFP Timer C */
345b8b4c3dSGeert Uytterhoeven     if (request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
355b8b4c3dSGeert Uytterhoeven 		    "timer", timer_routine))
365b8b4c3dSGeert Uytterhoeven 	pr_err("Couldn't register timer interrupt\n");
371da177e4SLinus Torvalds }
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds /* ++andreas: gettimeoffset fixed to check for pending interrupt */
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds #define TICK_SIZE 10000
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds /* This is always executed with interrupts disabled.  */
441da177e4SLinus Torvalds unsigned long atari_gettimeoffset (void)
451da177e4SLinus Torvalds {
461da177e4SLinus Torvalds   unsigned long ticks, offset = 0;
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds   /* read MFP timer C current value */
493d92e8f3SGeert Uytterhoeven   ticks = st_mfp.tim_dt_c;
501da177e4SLinus Torvalds   /* The probability of underflow is less than 2% */
511da177e4SLinus Torvalds   if (ticks > INT_TICKS - INT_TICKS / 50)
521da177e4SLinus Torvalds     /* Check for pending timer interrupt */
533d92e8f3SGeert Uytterhoeven     if (st_mfp.int_pn_b & (1 << 5))
541da177e4SLinus Torvalds       offset = TICK_SIZE;
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds   ticks = INT_TICKS - ticks;
571da177e4SLinus Torvalds   ticks = ticks * 10000L / INT_TICKS;
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds   return ticks + offset;
601da177e4SLinus Torvalds }
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds static void mste_read(struct MSTE_RTC *val)
641da177e4SLinus Torvalds {
651da177e4SLinus Torvalds #define COPY(v) val->v=(mste_rtc.v & 0xf)
661da177e4SLinus Torvalds 	do {
671da177e4SLinus Torvalds 		COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ;
681da177e4SLinus Torvalds 		COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ;
691da177e4SLinus Torvalds 		COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ;
701da177e4SLinus Torvalds 		COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
711da177e4SLinus Torvalds 		COPY(year_tens) ;
721da177e4SLinus Torvalds 	/* prevent from reading the clock while it changed */
731da177e4SLinus Torvalds 	} while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
741da177e4SLinus Torvalds #undef COPY
751da177e4SLinus Torvalds }
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds static void mste_write(struct MSTE_RTC *val)
781da177e4SLinus Torvalds {
791da177e4SLinus Torvalds #define COPY(v) mste_rtc.v=val->v
801da177e4SLinus Torvalds 	do {
811da177e4SLinus Torvalds 		COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ;
821da177e4SLinus Torvalds 		COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ;
831da177e4SLinus Torvalds 		COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ;
841da177e4SLinus Torvalds 		COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
851da177e4SLinus Torvalds 		COPY(year_tens) ;
861da177e4SLinus Torvalds 	/* prevent from writing the clock while it changed */
871da177e4SLinus Torvalds 	} while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
881da177e4SLinus Torvalds #undef COPY
891da177e4SLinus Torvalds }
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds #define	RTC_READ(reg)				\
921da177e4SLinus Torvalds     ({	unsigned char	__val;			\
931da177e4SLinus Torvalds 		(void) atari_writeb(reg,&tt_rtc.regsel);	\
941da177e4SLinus Torvalds 		__val = tt_rtc.data;		\
951da177e4SLinus Torvalds 		__val;				\
961da177e4SLinus Torvalds 	})
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds #define	RTC_WRITE(reg,val)			\
991da177e4SLinus Torvalds     do {					\
1001da177e4SLinus Torvalds 		atari_writeb(reg,&tt_rtc.regsel);	\
1011da177e4SLinus Torvalds 		tt_rtc.data = (val);		\
1021da177e4SLinus Torvalds 	} while(0)
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds #define HWCLK_POLL_INTERVAL	5
1061da177e4SLinus Torvalds 
1071da177e4SLinus Torvalds int atari_mste_hwclk( int op, struct rtc_time *t )
1081da177e4SLinus Torvalds {
1091da177e4SLinus Torvalds     int hour, year;
1101da177e4SLinus Torvalds     int hr24=0;
1111da177e4SLinus Torvalds     struct MSTE_RTC val;
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds     mste_rtc.mode=(mste_rtc.mode | 1);
1141da177e4SLinus Torvalds     hr24=mste_rtc.mon_tens & 1;
1151da177e4SLinus Torvalds     mste_rtc.mode=(mste_rtc.mode & ~1);
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds     if (op) {
1181da177e4SLinus Torvalds         /* write: prepare values */
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds         val.sec_ones = t->tm_sec % 10;
1211da177e4SLinus Torvalds         val.sec_tens = t->tm_sec / 10;
1221da177e4SLinus Torvalds         val.min_ones = t->tm_min % 10;
1231da177e4SLinus Torvalds         val.min_tens = t->tm_min / 10;
1241da177e4SLinus Torvalds         hour = t->tm_hour;
1251da177e4SLinus Torvalds         if (!hr24) {
1261da177e4SLinus Torvalds 	    if (hour > 11)
1271da177e4SLinus Torvalds 		hour += 20 - 12;
1281da177e4SLinus Torvalds 	    if (hour == 0 || hour == 20)
1291da177e4SLinus Torvalds 		hour += 12;
1301da177e4SLinus Torvalds         }
1311da177e4SLinus Torvalds         val.hr_ones = hour % 10;
1321da177e4SLinus Torvalds         val.hr_tens = hour / 10;
1331da177e4SLinus Torvalds         val.day_ones = t->tm_mday % 10;
1341da177e4SLinus Torvalds         val.day_tens = t->tm_mday / 10;
1351da177e4SLinus Torvalds         val.mon_ones = (t->tm_mon+1) % 10;
1361da177e4SLinus Torvalds         val.mon_tens = (t->tm_mon+1) / 10;
1371da177e4SLinus Torvalds         year = t->tm_year - 80;
1381da177e4SLinus Torvalds         val.year_ones = year % 10;
1391da177e4SLinus Torvalds         val.year_tens = year / 10;
1401da177e4SLinus Torvalds         val.weekday = t->tm_wday;
1411da177e4SLinus Torvalds         mste_write(&val);
1421da177e4SLinus Torvalds         mste_rtc.mode=(mste_rtc.mode | 1);
1431da177e4SLinus Torvalds         val.year_ones = (year % 4);	/* leap year register */
1441da177e4SLinus Torvalds         mste_rtc.mode=(mste_rtc.mode & ~1);
1451da177e4SLinus Torvalds     }
1461da177e4SLinus Torvalds     else {
1471da177e4SLinus Torvalds         mste_read(&val);
1481da177e4SLinus Torvalds         t->tm_sec = val.sec_ones + val.sec_tens * 10;
1491da177e4SLinus Torvalds         t->tm_min = val.min_ones + val.min_tens * 10;
1501da177e4SLinus Torvalds         hour = val.hr_ones + val.hr_tens * 10;
1511da177e4SLinus Torvalds 	if (!hr24) {
1521da177e4SLinus Torvalds 	    if (hour == 12 || hour == 12 + 20)
1531da177e4SLinus Torvalds 		hour -= 12;
1541da177e4SLinus Torvalds 	    if (hour >= 20)
1551da177e4SLinus Torvalds                 hour += 12 - 20;
1561da177e4SLinus Torvalds         }
1571da177e4SLinus Torvalds 	t->tm_hour = hour;
1581da177e4SLinus Torvalds 	t->tm_mday = val.day_ones + val.day_tens * 10;
1591da177e4SLinus Torvalds         t->tm_mon  = val.mon_ones + val.mon_tens * 10 - 1;
1601da177e4SLinus Torvalds         t->tm_year = val.year_ones + val.year_tens * 10 + 80;
1611da177e4SLinus Torvalds         t->tm_wday = val.weekday;
1621da177e4SLinus Torvalds     }
1631da177e4SLinus Torvalds     return 0;
1641da177e4SLinus Torvalds }
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds int atari_tt_hwclk( int op, struct rtc_time *t )
1671da177e4SLinus Torvalds {
1681da177e4SLinus Torvalds     int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0;
1691da177e4SLinus Torvalds     unsigned long	flags;
1701da177e4SLinus Torvalds     unsigned char	ctrl;
1711da177e4SLinus Torvalds     int pm = 0;
1721da177e4SLinus Torvalds 
1731da177e4SLinus Torvalds     ctrl = RTC_READ(RTC_CONTROL); /* control registers are
1741da177e4SLinus Torvalds                                    * independent from the UIP */
1751da177e4SLinus Torvalds 
1761da177e4SLinus Torvalds     if (op) {
1771da177e4SLinus Torvalds         /* write: prepare values */
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds         sec  = t->tm_sec;
1801da177e4SLinus Torvalds         min  = t->tm_min;
1811da177e4SLinus Torvalds         hour = t->tm_hour;
1821da177e4SLinus Torvalds         day  = t->tm_mday;
1831da177e4SLinus Torvalds         mon  = t->tm_mon + 1;
1841da177e4SLinus Torvalds         year = t->tm_year - atari_rtc_year_offset;
1851da177e4SLinus Torvalds         wday = t->tm_wday + (t->tm_wday >= 0);
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds         if (!(ctrl & RTC_24H)) {
1881da177e4SLinus Torvalds 	    if (hour > 11) {
1891da177e4SLinus Torvalds 		pm = 0x80;
1901da177e4SLinus Torvalds 		if (hour != 12)
1911da177e4SLinus Torvalds 		    hour -= 12;
1921da177e4SLinus Torvalds 	    }
1931da177e4SLinus Torvalds 	    else if (hour == 0)
1941da177e4SLinus Torvalds 		hour = 12;
1951da177e4SLinus Torvalds         }
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds         if (!(ctrl & RTC_DM_BINARY)) {
1985b1d5f95SAdrian Bunk 	    sec = bin2bcd(sec);
1995b1d5f95SAdrian Bunk 	    min = bin2bcd(min);
2005b1d5f95SAdrian Bunk 	    hour = bin2bcd(hour);
2015b1d5f95SAdrian Bunk 	    day = bin2bcd(day);
2025b1d5f95SAdrian Bunk 	    mon = bin2bcd(mon);
2035b1d5f95SAdrian Bunk 	    year = bin2bcd(year);
2045b1d5f95SAdrian Bunk 	    if (wday >= 0)
2055b1d5f95SAdrian Bunk 		wday = bin2bcd(wday);
2061da177e4SLinus Torvalds         }
2071da177e4SLinus Torvalds     }
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds     /* Reading/writing the clock registers is a bit critical due to
2101da177e4SLinus Torvalds      * the regular update cycle of the RTC. While an update is in
2111da177e4SLinus Torvalds      * progress, registers 0..9 shouldn't be touched.
2121da177e4SLinus Torvalds      * The problem is solved like that: If an update is currently in
2131da177e4SLinus Torvalds      * progress (the UIP bit is set), the process sleeps for a while
2141da177e4SLinus Torvalds      * (50ms). This really should be enough, since the update cycle
2151da177e4SLinus Torvalds      * normally needs 2 ms.
2161da177e4SLinus Torvalds      * If the UIP bit reads as 0, we have at least 244 usecs until the
2171da177e4SLinus Torvalds      * update starts. This should be enough... But to be sure,
2181da177e4SLinus Torvalds      * additionally the RTC_SET bit is set to prevent an update cycle.
2191da177e4SLinus Torvalds      */
2201da177e4SLinus Torvalds 
22169961c37SGeert Uytterhoeven     while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
22269961c37SGeert Uytterhoeven 	if (in_atomic() || irqs_disabled())
22369961c37SGeert Uytterhoeven 	    mdelay(1);
22469961c37SGeert Uytterhoeven 	else
22528faa429SNishanth Aravamudan 	    schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
22669961c37SGeert Uytterhoeven     }
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds     local_irq_save(flags);
2291da177e4SLinus Torvalds     RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
2301da177e4SLinus Torvalds     if (!op) {
2311da177e4SLinus Torvalds         sec  = RTC_READ( RTC_SECONDS );
2321da177e4SLinus Torvalds         min  = RTC_READ( RTC_MINUTES );
2331da177e4SLinus Torvalds         hour = RTC_READ( RTC_HOURS );
2341da177e4SLinus Torvalds         day  = RTC_READ( RTC_DAY_OF_MONTH );
2351da177e4SLinus Torvalds         mon  = RTC_READ( RTC_MONTH );
2361da177e4SLinus Torvalds         year = RTC_READ( RTC_YEAR );
2371da177e4SLinus Torvalds         wday = RTC_READ( RTC_DAY_OF_WEEK );
2381da177e4SLinus Torvalds     }
2391da177e4SLinus Torvalds     else {
2401da177e4SLinus Torvalds         RTC_WRITE( RTC_SECONDS, sec );
2411da177e4SLinus Torvalds         RTC_WRITE( RTC_MINUTES, min );
2421da177e4SLinus Torvalds         RTC_WRITE( RTC_HOURS, hour + pm);
2431da177e4SLinus Torvalds         RTC_WRITE( RTC_DAY_OF_MONTH, day );
2441da177e4SLinus Torvalds         RTC_WRITE( RTC_MONTH, mon );
2451da177e4SLinus Torvalds         RTC_WRITE( RTC_YEAR, year );
2461da177e4SLinus Torvalds         if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday );
2471da177e4SLinus Torvalds     }
2481da177e4SLinus Torvalds     RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET );
2491da177e4SLinus Torvalds     local_irq_restore(flags);
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds     if (!op) {
2521da177e4SLinus Torvalds         /* read: adjust values */
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds         if (hour & 0x80) {
2551da177e4SLinus Torvalds 	    hour &= ~0x80;
2561da177e4SLinus Torvalds 	    pm = 1;
2571da177e4SLinus Torvalds 	}
2581da177e4SLinus Torvalds 
2591da177e4SLinus Torvalds 	if (!(ctrl & RTC_DM_BINARY)) {
2605b1d5f95SAdrian Bunk 	    sec = bcd2bin(sec);
2615b1d5f95SAdrian Bunk 	    min = bcd2bin(min);
2625b1d5f95SAdrian Bunk 	    hour = bcd2bin(hour);
2635b1d5f95SAdrian Bunk 	    day = bcd2bin(day);
2645b1d5f95SAdrian Bunk 	    mon = bcd2bin(mon);
2655b1d5f95SAdrian Bunk 	    year = bcd2bin(year);
2665b1d5f95SAdrian Bunk 	    wday = bcd2bin(wday);
2671da177e4SLinus Torvalds         }
2681da177e4SLinus Torvalds 
2691da177e4SLinus Torvalds         if (!(ctrl & RTC_24H)) {
2701da177e4SLinus Torvalds 	    if (!pm && hour == 12)
2711da177e4SLinus Torvalds 		hour = 0;
2721da177e4SLinus Torvalds 	    else if (pm && hour != 12)
2731da177e4SLinus Torvalds 		hour += 12;
2741da177e4SLinus Torvalds         }
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds         t->tm_sec  = sec;
2771da177e4SLinus Torvalds         t->tm_min  = min;
2781da177e4SLinus Torvalds         t->tm_hour = hour;
2791da177e4SLinus Torvalds         t->tm_mday = day;
2801da177e4SLinus Torvalds         t->tm_mon  = mon - 1;
2811da177e4SLinus Torvalds         t->tm_year = year + atari_rtc_year_offset;
2821da177e4SLinus Torvalds         t->tm_wday = wday - 1;
2831da177e4SLinus Torvalds     }
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds     return( 0 );
2861da177e4SLinus Torvalds }
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds int atari_mste_set_clock_mmss (unsigned long nowtime)
2901da177e4SLinus Torvalds {
2911da177e4SLinus Torvalds     short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
2921da177e4SLinus Torvalds     struct MSTE_RTC val;
2931da177e4SLinus Torvalds     unsigned char rtc_minutes;
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds     mste_read(&val);
2961da177e4SLinus Torvalds     rtc_minutes= val.min_ones + val.min_tens * 10;
2971da177e4SLinus Torvalds     if ((rtc_minutes < real_minutes
2981da177e4SLinus Torvalds          ? real_minutes - rtc_minutes
2991da177e4SLinus Torvalds          : rtc_minutes - real_minutes) < 30)
3001da177e4SLinus Torvalds     {
3011da177e4SLinus Torvalds         val.sec_ones = real_seconds % 10;
3021da177e4SLinus Torvalds         val.sec_tens = real_seconds / 10;
3031da177e4SLinus Torvalds         val.min_ones = real_minutes % 10;
3041da177e4SLinus Torvalds         val.min_tens = real_minutes / 10;
3051da177e4SLinus Torvalds         mste_write(&val);
3061da177e4SLinus Torvalds     }
3071da177e4SLinus Torvalds     else
3081da177e4SLinus Torvalds         return -1;
3091da177e4SLinus Torvalds     return 0;
3101da177e4SLinus Torvalds }
3111da177e4SLinus Torvalds 
3121da177e4SLinus Torvalds int atari_tt_set_clock_mmss (unsigned long nowtime)
3131da177e4SLinus Torvalds {
3141da177e4SLinus Torvalds     int retval = 0;
3151da177e4SLinus Torvalds     short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
3161da177e4SLinus Torvalds     unsigned char save_control, save_freq_select, rtc_minutes;
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds     save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */
3191da177e4SLinus Torvalds     RTC_WRITE (RTC_CONTROL, save_control | RTC_SET);
3201da177e4SLinus Torvalds 
3211da177e4SLinus Torvalds     save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */
3221da177e4SLinus Torvalds     RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2);
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds     rtc_minutes = RTC_READ (RTC_MINUTES);
3251da177e4SLinus Torvalds     if (!(save_control & RTC_DM_BINARY))
3265b1d5f95SAdrian Bunk 	rtc_minutes = bcd2bin(rtc_minutes);
3271da177e4SLinus Torvalds 
3281da177e4SLinus Torvalds     /* Since we're only adjusting minutes and seconds, don't interfere
3291da177e4SLinus Torvalds        with hour overflow.  This avoids messing with unknown time zones
3301da177e4SLinus Torvalds        but requires your RTC not to be off by more than 30 minutes.  */
3311da177e4SLinus Torvalds     if ((rtc_minutes < real_minutes
3321da177e4SLinus Torvalds          ? real_minutes - rtc_minutes
3331da177e4SLinus Torvalds          : rtc_minutes - real_minutes) < 30)
3341da177e4SLinus Torvalds         {
3351da177e4SLinus Torvalds             if (!(save_control & RTC_DM_BINARY))
3361da177e4SLinus Torvalds                 {
3375b1d5f95SAdrian Bunk 		    real_seconds = bin2bcd(real_seconds);
3385b1d5f95SAdrian Bunk 		    real_minutes = bin2bcd(real_minutes);
3391da177e4SLinus Torvalds                 }
3401da177e4SLinus Torvalds             RTC_WRITE (RTC_SECONDS, real_seconds);
3411da177e4SLinus Torvalds             RTC_WRITE (RTC_MINUTES, real_minutes);
3421da177e4SLinus Torvalds         }
3431da177e4SLinus Torvalds     else
3441da177e4SLinus Torvalds         retval = -1;
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds     RTC_WRITE (RTC_FREQ_SELECT, save_freq_select);
3471da177e4SLinus Torvalds     RTC_WRITE (RTC_CONTROL, save_control);
3481da177e4SLinus Torvalds     return retval;
3491da177e4SLinus Torvalds }
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds /*
3521da177e4SLinus Torvalds  * Local variables:
3531da177e4SLinus Torvalds  *  c-indent-level: 4
3541da177e4SLinus Torvalds  *  tab-width: 8
3551da177e4SLinus Torvalds  * End:
3561da177e4SLinus Torvalds  */
357