Commit c58411e95d7f5062dedd1a3064af4d359da1e633

Authored by Alessandro Zummo
Committed by Linus Torvalds
1 parent d23ee8fe6e

[PATCH] RTC Subsystem: library functions

RTC and date/time related functions.

Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 6 changed files with 120 additions and 0 deletions Side-by-side Diff

... ... @@ -70,5 +70,7 @@
70 70  
71 71 source "drivers/edac/Kconfig"
72 72  
  73 +source "drivers/rtc/Kconfig"
  74 +
73 75 endmenu
... ... @@ -56,6 +56,7 @@
56 56 obj-$(CONFIG_GAMEPORT) += input/gameport/
57 57 obj-$(CONFIG_INPUT) += input/
58 58 obj-$(CONFIG_I2O) += message/
  59 +obj-$(CONFIG_RTC_LIB) += rtc/
59 60 obj-$(CONFIG_I2C) += i2c/
60 61 obj-$(CONFIG_W1) += w1/
61 62 obj-$(CONFIG_HWMON) += hwmon/
  1 +#
  2 +# RTC class/drivers configuration
  3 +#
  4 +
  5 +config RTC_LIB
  6 + tristate
drivers/rtc/Makefile
  1 +#
  2 +# Makefile for RTC class/drivers.
  3 +#
  4 +
  5 +obj-$(CONFIG_RTC_LIB) += rtc-lib.o
drivers/rtc/rtc-lib.c
  1 +/*
  2 + * rtc and date/time utility functions
  3 + *
  4 + * Copyright (C) 2005-06 Tower Technologies
  5 + * Author: Alessandro Zummo <a.zummo@towertech.it>
  6 + *
  7 + * based on arch/arm/common/rtctime.c and other bits
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License version 2 as
  11 + * published by the Free Software Foundation.
  12 +*/
  13 +
  14 +#include <linux/module.h>
  15 +#include <linux/rtc.h>
  16 +
  17 +static const unsigned char rtc_days_in_month[] = {
  18 + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  19 +};
  20 +
  21 +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
  22 +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
  23 +
  24 +int rtc_month_days(unsigned int month, unsigned int year)
  25 +{
  26 + return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
  27 +}
  28 +EXPORT_SYMBOL(rtc_month_days);
  29 +
  30 +/*
  31 + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
  32 + */
  33 +void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
  34 +{
  35 + register int days, month, year;
  36 +
  37 + days = time / 86400;
  38 + time -= days * 86400;
  39 +
  40 + /* day of the week, 1970-01-01 was a Thursday */
  41 + tm->tm_wday = (days + 4) % 7;
  42 +
  43 + year = 1970 + days / 365;
  44 + days -= (year - 1970) * 365
  45 + + LEAPS_THRU_END_OF(year - 1)
  46 + - LEAPS_THRU_END_OF(1970 - 1);
  47 + if (days < 0) {
  48 + year -= 1;
  49 + days += 365 + LEAP_YEAR(year);
  50 + }
  51 + tm->tm_year = year - 1900;
  52 + tm->tm_yday = days + 1;
  53 +
  54 + for (month = 0; month < 11; month++) {
  55 + int newdays;
  56 +
  57 + newdays = days - rtc_month_days(month, year);
  58 + if (newdays < 0)
  59 + break;
  60 + days = newdays;
  61 + }
  62 + tm->tm_mon = month;
  63 + tm->tm_mday = days + 1;
  64 +
  65 + tm->tm_hour = time / 3600;
  66 + time -= tm->tm_hour * 3600;
  67 + tm->tm_min = time / 60;
  68 + tm->tm_sec = time - tm->tm_min * 60;
  69 +}
  70 +EXPORT_SYMBOL(rtc_time_to_tm);
  71 +
  72 +/*
  73 + * Does the rtc_time represent a valid date/time?
  74 + */
  75 +int rtc_valid_tm(struct rtc_time *tm)
  76 +{
  77 + if (tm->tm_year < 70
  78 + || tm->tm_mon >= 12
  79 + || tm->tm_mday < 1
  80 + || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900)
  81 + || tm->tm_hour >= 24
  82 + || tm->tm_min >= 60
  83 + || tm->tm_sec >= 60)
  84 + return -EINVAL;
  85 +
  86 + return 0;
  87 +}
  88 +EXPORT_SYMBOL(rtc_valid_tm);
  89 +
  90 +/*
  91 + * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
  92 + */
  93 +int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
  94 +{
  95 + *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
  96 + tm->tm_hour, tm->tm_min, tm->tm_sec);
  97 + return 0;
  98 +}
  99 +EXPORT_SYMBOL(rtc_tm_to_time);
  100 +
  101 +MODULE_LICENSE("GPL");
... ... @@ -95,6 +95,11 @@
95 95  
96 96 #include <linux/interrupt.h>
97 97  
  98 +extern int rtc_month_days(unsigned int month, unsigned int year);
  99 +extern int rtc_valid_tm(struct rtc_time *tm);
  100 +extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
  101 +extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
  102 +
98 103 typedef struct rtc_task {
99 104 void (*func)(void *private_data);
100 105 void *private_data;