* rtc_time64_to_tm - converts time64_t to rtc_time.
  *
  * @time:      The number of seconds since 01-01-1970 00:00:00.
- *             (Must be positive.)
+ *             Works for values since at least 1900
  * @tm:                Pointer to the struct rtc_time.
  */
 void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
 {
-       unsigned int secs;
-       int days;
+       int days, secs;
 
        u64 u64tmp;
        u32 u32tmp, udays, century, day_of_century, year_of_century, year,
                day_of_year, month, day;
        bool is_Jan_or_Feb, is_leap_year;
 
-       /* time must be positive */
+       /*
+        * Get days and seconds while preserving the sign to
+        * handle negative time values (dates before 1970-01-01)
+        */
        days = div_s64_rem(time, 86400, &secs);
 
+       /*
+        * We need 0 <= secs < 86400 which isn't given for negative
+        * values of time. Fixup accordingly.
+        */
+       if (secs < 0) {
+               days -= 1;
+               secs += 86400;
+       }
+
        /* day of the week, 1970-01-01 was a Thursday */
        tm->tm_wday = (days + 4) % 7;
+       /* Ensure tm_wday is always positive */
+       if (tm->tm_wday < 0)
+               tm->tm_wday += 7;
 
        /*
         * The following algorithm is, basically, Proposition 6.3 of Neri
         * thus, is slightly different from [1].
         */
 
-       udays           = ((u32) days) + 719468;
+       udays           = days + 719468;
 
        u32tmp          = 4 * udays + 3;
        century         = u32tmp / 146097;