diff options
Diffstat (limited to 'drivers/rtc/rtc-lib.c')
| -rw-r--r-- | drivers/rtc/rtc-lib.c | 113 |
1 files changed, 31 insertions, 82 deletions
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 7bbc26a34bd..c4cf0573111 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -26,14 +26,13 @@ static const unsigned short rtc_ydays[2][13] = { }; #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) /* * The number of days in the month. */ int rtc_month_days(unsigned int month, unsigned int year) { - return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); + return rtc_days_in_month[month] + (is_leap_year(year) && month == 1); } EXPORT_SYMBOL(rtc_month_days); @@ -42,7 +41,7 @@ EXPORT_SYMBOL(rtc_month_days); */ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) { - return rtc_ydays[LEAP_YEAR(year)][month] + day-1; + return rtc_ydays[is_leap_year(year)][month] + day-1; } EXPORT_SYMBOL(rtc_year_days); @@ -51,10 +50,11 @@ EXPORT_SYMBOL(rtc_year_days); */ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) { - register int days, month, year; + unsigned int month, year; + int days; days = time / 86400; - time -= days * 86400; + time -= (unsigned int) days * 86400; /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; @@ -65,7 +65,7 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) - LEAPS_THRU_END_OF(1970 - 1); if (days < 0) { year -= 1; - days += 365 + LEAP_YEAR(year); + days += 365 + is_leap_year(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; @@ -85,6 +85,8 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) time -= tm->tm_hour * 3600; tm->tm_min = time / 60; tm->tm_sec = time - tm->tm_min * 60; + + tm->tm_isdst = 0; } EXPORT_SYMBOL(rtc_time_to_tm); @@ -117,85 +119,32 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) } EXPORT_SYMBOL(rtc_tm_to_time); - -/* Merge the valid (i.e. non-negative) fields of alarm into the current - * time. If the valid alarm fields are earlier than the equivalent - * fields in the time, carry one into the least significant invalid - * field, so that the alarm expiry is in the future. It assumes that the - * least significant invalid field is more significant than the most - * significant valid field, and that the seconds field is valid. - * - * This is used by alarms that take relative (rather than absolute) - * times, and/or have a simple binary second counter instead of - * day/hour/minute/sec registers. +/* + * Convert rtc_time to ktime */ -void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm) +ktime_t rtc_tm_to_ktime(struct rtc_time tm) { - int *alarmp = &alarm->tm_sec; - int *timep = &now->tm_sec; - int carry_into, i; - - /* Ignore everything past the 6th element (tm_year). */ - for (i = 5; i > 0; i--) { - if (alarmp[i] < 0) - alarmp[i] = timep[i]; - else - break; - } - - /* No carry needed if all fields are valid. */ - if (i == 5) - return; - - for (carry_into = i + 1; i >= 0; i--) { - if (alarmp[i] < timep[i]) - break; - - if (alarmp[i] > timep[i]) - return; - } - - switch (carry_into) { - case 1: - alarm->tm_min++; - - if (alarm->tm_min < 60) - return; - - alarm->tm_min = 0; - /* fall-through */ - - case 2: - alarm->tm_hour++; - - if (alarm->tm_hour < 60) - return; - - alarm->tm_hour = 0; - /* fall-through */ - - case 3: - alarm->tm_mday++; - - if (alarm->tm_mday <= rtc_days_in_month[alarm->tm_mon]) - return; - - alarm->tm_mday = 1; - /* fall-through */ - - case 4: - alarm->tm_mon++; - - if (alarm->tm_mon <= 12) - return; - - alarm->tm_mon = 1; - /* fall-through */ + time_t time; + rtc_tm_to_time(&tm, &time); + return ktime_set(time, 0); +} +EXPORT_SYMBOL_GPL(rtc_tm_to_ktime); - case 5: - alarm->tm_year++; - } +/* + * Convert ktime to rtc_time + */ +struct rtc_time rtc_ktime_to_tm(ktime_t kt) +{ + struct timespec ts; + struct rtc_time ret; + + ts = ktime_to_timespec(kt); + /* Round up any ns */ + if (ts.tv_nsec) + ts.tv_sec++; + rtc_time_to_tm(ts.tv_sec, &ret); + return ret; } -EXPORT_SYMBOL(rtc_merge_alarm); +EXPORT_SYMBOL_GPL(rtc_ktime_to_tm); MODULE_LICENSE("GPL"); |
