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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php