~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kernel/rtas-rtc.c

Version: ~ [ linux-5.14-rc3 ] ~ [ linux-5.13.5 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.53 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.135 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.198 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.240 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.276 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.276 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/kernel.h>
  2 #include <linux/time.h>
  3 #include <linux/timer.h>
  4 #include <linux/init.h>
  5 #include <linux/rtc.h>
  6 #include <linux/delay.h>
  7 #include <asm/prom.h>
  8 #include <asm/rtas.h>
  9 #include <asm/time.h>
 10 
 11 
 12 #define MAX_RTC_WAIT 5000       /* 5 sec */
 13 #define RTAS_CLOCK_BUSY (-2)
 14 unsigned long __init rtas_get_boot_time(void)
 15 {
 16         int ret[8];
 17         int error;
 18         unsigned int wait_time;
 19         u64 max_wait_tb;
 20 
 21         max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
 22         do {
 23                 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
 24 
 25                 wait_time = rtas_busy_delay_time(error);
 26                 if (wait_time) {
 27                         /* This is boot time so we spin. */
 28                         udelay(wait_time*1000);
 29                 }
 30         } while (wait_time && (get_tb() < max_wait_tb));
 31 
 32         if (error != 0 && printk_ratelimit()) {
 33                 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
 34                         error);
 35                 return 0;
 36         }
 37 
 38         return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
 39 }
 40 
 41 /* NOTE: get_rtc_time will get an error if executed in interrupt context
 42  * and if a delay is needed to read the clock.  In this case we just
 43  * silently return without updating rtc_tm.
 44  */
 45 void rtas_get_rtc_time(struct rtc_time *rtc_tm)
 46 {
 47         int ret[8];
 48         int error;
 49         unsigned int wait_time;
 50         u64 max_wait_tb;
 51 
 52         max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
 53         do {
 54                 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
 55 
 56                 wait_time = rtas_busy_delay_time(error);
 57                 if (wait_time) {
 58                         if (in_interrupt() && printk_ratelimit()) {
 59                                 memset(rtc_tm, 0, sizeof(struct rtc_time));
 60                                 printk(KERN_WARNING "error: reading clock"
 61                                        " would delay interrupt\n");
 62                                 return; /* delay not allowed */
 63                         }
 64                         msleep(wait_time);
 65                 }
 66         } while (wait_time && (get_tb() < max_wait_tb));
 67 
 68         if (error != 0 && printk_ratelimit()) {
 69                 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
 70                        error);
 71                 return;
 72         }
 73 
 74         rtc_tm->tm_sec = ret[5];
 75         rtc_tm->tm_min = ret[4];
 76         rtc_tm->tm_hour = ret[3];
 77         rtc_tm->tm_mday = ret[2];
 78         rtc_tm->tm_mon = ret[1] - 1;
 79         rtc_tm->tm_year = ret[0] - 1900;
 80 }
 81 
 82 int rtas_set_rtc_time(struct rtc_time *tm)
 83 {
 84         int error, wait_time;
 85         u64 max_wait_tb;
 86 
 87         max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
 88         do {
 89                 error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
 90                                   tm->tm_year + 1900, tm->tm_mon + 1,
 91                                   tm->tm_mday, tm->tm_hour, tm->tm_min,
 92                                   tm->tm_sec, 0);
 93 
 94                 wait_time = rtas_busy_delay_time(error);
 95                 if (wait_time) {
 96                         if (in_interrupt())
 97                                 return 1;       /* probably decrementer */
 98                         msleep(wait_time);
 99                 }
100         } while (wait_time && (get_tb() < max_wait_tb));
101 
102         if (error != 0 && printk_ratelimit())
103                 printk(KERN_WARNING "error: setting the clock failed (%d)\n",
104                        error);
105 
106         return 0;
107 }
108 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp