LCOV - code coverage report
Current view: top level - lkbce/include/asm-generic - rtc.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 90 90 100.0 %
Date: 2017-01-25 Functions: 3 3 100.0 %

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

Generated by: LCOV version 1.10