These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / rtc / rtc-efi.c
index cb989cd..3806961 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
  *
- * Author: dann frazier <dannf@hp.com>
+ * Author: dann frazier <dannf@dannf.org>
  * Based on efirtc.c by Stephane Eranian
  *
  *  This program is free software; you can redistribute  it and/or modify it
 #include <linux/efi.h>
 
 #define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
-/*
- * EFI Epoch is 1/1/1998
- */
-#define EFI_RTC_EPOCH          1998
 
 /*
  * returns day of the year [0-365]
@@ -38,31 +34,24 @@ compute_yday(efi_time_t *eft)
        /* efi_time_t.month is in the [1-12] so, we need -1 */
        return rtc_year_days(eft->day, eft->month - 1, eft->year);
 }
+
 /*
  * returns day of the week [0-6] 0=Sunday
- *
- * Don't try to provide a year that's before 1998, please !
  */
 static int
-compute_wday(efi_time_t *eft)
+compute_wday(efi_time_t *eft, int yday)
 {
-       int y;
-       int ndays = 0;
-
-       if (eft->year < EFI_RTC_EPOCH) {
-               pr_err("EFI year < " __stringify(EFI_RTC_EPOCH) ", invalid date\n");
-               return -1;
-       }
-
-       for (y = EFI_RTC_EPOCH; y < eft->year; y++)
-               ndays += 365 + (is_leap_year(y) ? 1 : 0);
-
-       ndays += compute_yday(eft);
+       int ndays = eft->year * (365 % 7)
+                   + (eft->year - 1) / 4
+                   - (eft->year - 1) / 100
+                   + (eft->year - 1) / 400
+                   + yday;
 
        /*
-        * 4=1/1/1998 was a Thursday
+        * 1/1/0000 may or may not have been a Sunday (if it ever existed at
+        * all) but assuming it was makes this calculation work correctly.
         */
-       return (ndays + 4) % 7;
+       return ndays % 7;
 }
 
 static void
@@ -103,16 +92,16 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
        if (!eft->month || eft->month > 12)
                return false;
        wtime->tm_mon  = eft->month - 1;
-       wtime->tm_year = eft->year - 1900;
 
-       /* day of the week [0-6], Sunday=0 */
-       wtime->tm_wday = compute_wday(eft);
-       if (wtime->tm_wday < 0)
+       if (eft->year < 1900 || eft->year > 9999)
                return false;
+       wtime->tm_year = eft->year - 1900;
 
        /* day in the year [1-365]*/
        wtime->tm_yday = compute_yday(eft);
 
+       /* day of the week [0-6], Sunday=0 */
+       wtime->tm_wday = compute_wday(eft, wtime->tm_yday);
 
        switch (eft->daylight & EFI_ISDST) {
        case EFI_ISDST:
@@ -233,7 +222,7 @@ static struct platform_driver efi_rtc_driver = {
 module_platform_driver_probe(efi_rtc_driver, efi_rtc_probe);
 
 MODULE_ALIAS("platform:rtc-efi");
-MODULE_AUTHOR("dann frazier <dannf@hp.com>");
+MODULE_AUTHOR("dann frazier <dannf@dannf.org>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("EFI RTC driver");
 MODULE_ALIAS("platform:rtc-efi");