diff options
Diffstat (limited to 'packages/linux/nslu2-kernel/2.6.15/40-rtc-class.patch')
| -rw-r--r-- | packages/linux/nslu2-kernel/2.6.15/40-rtc-class.patch | 2719 |
1 files changed, 0 insertions, 2719 deletions
diff --git a/packages/linux/nslu2-kernel/2.6.15/40-rtc-class.patch b/packages/linux/nslu2-kernel/2.6.15/40-rtc-class.patch deleted file mode 100644 index feea3f2f8b..0000000000 --- a/packages/linux/nslu2-kernel/2.6.15/40-rtc-class.patch +++ /dev/null @@ -1,2719 +0,0 @@ ---- linux-nslu2.orig/include/linux/rtc.h 2006-01-03 15:31:18.000000000 +0100 -+++ linux-nslu2/include/linux/rtc.h 2006-01-03 15:34:24.000000000 +0100 -@@ -91,8 +91,81 @@ struct rtc_pll_info { - #define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ - #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ - -+/* interrupt flags */ -+#define RTC_IRQF 0x80 /* any of the following is active */ -+#define RTC_PF 0x40 -+#define RTC_AF 0x20 -+#define RTC_UF 0x10 -+ - #ifdef __KERNEL__ - -+#include <linux/device.h> -+#include <linux/seq_file.h> -+#include <linux/cdev.h> -+#include <linux/poll.h> -+ -+struct rtc_class_ops { -+ int (*open)(struct device *); -+ void (*release)(struct device *); -+ int (*ioctl)(struct device *, unsigned int, unsigned long); -+ int (*read_time)(struct device *, struct rtc_time *); -+ int (*set_time)(struct device *, struct rtc_time *); -+ int (*read_alarm)(struct device *, struct rtc_wkalrm *); -+ int (*set_alarm)(struct device *, struct rtc_wkalrm *); -+ int (*proc)(struct device *, struct seq_file *); -+ int (*set_mmss)(struct device *, unsigned long secs); -+ int (*irq_set_state)(struct device *, int enabled); -+ int (*irq_set_freq)(struct device *, int freq); -+}; -+ -+#define RTC_DEVICE_NAME_SIZE 20 -+struct rtc_task; -+ -+struct rtc_device -+{ -+ int id; -+ struct module *owner; -+ struct rw_semaphore lock; -+ struct class_device class_dev; -+ struct rtc_class_ops *ops; -+ char name[RTC_DEVICE_NAME_SIZE]; -+ -+ struct cdev char_dev; -+ struct semaphore char_sem; -+ -+ unsigned long irq_data; -+ spinlock_t irq_lock; -+ wait_queue_head_t irq_queue; -+ struct fasync_struct *async_queue; -+ -+ spinlock_t irq_task_lock; -+ struct rtc_task *irq_task; -+ int irq_freq; -+}; -+#define to_rtc_device(d) container_of(d, struct rtc_device, class_dev) -+ -+extern struct rtc_device *rtc_device_register(char *name, -+ struct device *dev, -+ struct rtc_class_ops *ops, -+ struct module *owner); -+extern void rtc_device_unregister(struct rtc_device *rdev); -+extern int rtc_interface_register(struct class_interface *intf); -+ -+ -+extern int rtc_month_days(unsigned int month, unsigned int year); -+extern int rtc_valid_tm(struct rtc_time *tm); -+extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); -+extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); -+ -+extern int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm); -+extern int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm); -+extern int rtc_read_alarm(struct class_device *class_dev, -+ struct rtc_wkalrm *alrm); -+extern int rtc_set_alarm(struct class_device *class_dev, -+ struct rtc_wkalrm *alrm); -+extern void rtc_update_irq(struct class_device *class_dev, -+ unsigned long num, unsigned long events); -+ - typedef struct rtc_task { - void (*func)(void *private_data); - void *private_data; ---- linux-nslu2.orig/drivers/Kconfig 2006-01-03 15:31:19.000000000 +0100 -+++ linux-nslu2/drivers/Kconfig 2006-01-04 01:27:31.000000000 +0100 -@@ -66,4 +66,6 @@ source "drivers/infiniband/Kconfig" - - source "drivers/sn/Kconfig" - -+source "drivers/rtc/Kconfig" -+ - endmenu ---- linux-nslu2.orig/drivers/Makefile 2006-01-03 15:33:32.000000000 +0100 -+++ linux-nslu2/drivers/Makefile 2006-01-04 01:27:31.000000000 +0100 -@@ -54,6 +54,7 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/ - obj-$(CONFIG_GAMEPORT) += input/gameport/ - obj-$(CONFIG_INPUT) += input/ - obj-$(CONFIG_I2O) += message/ -+obj-y += rtc/ - obj-$(CONFIG_I2C) += i2c/ - obj-$(CONFIG_W1) += w1/ - obj-$(CONFIG_HWMON) += hwmon/ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/class.c 2006-01-03 15:45:19.000000000 +0100 -@@ -0,0 +1,141 @@ -+/* -+ * RTC subsystem, base class -+ * -+ * Copyright (C) 2005 Tower Technologies -+ * Author: Alessandro Zummo <a.zummo@towertech.it> -+ * -+ * class skeleton from drivers/hwmon/hwmon.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+*/ -+ -+#include <linux/module.h> -+#include <linux/rtc.h> -+#include <linux/kdev_t.h> -+#include <linux/idr.h> -+ -+static DEFINE_IDR(rtc_idr); -+static DECLARE_MUTEX(idr_lock); -+struct class *rtc_class; -+ -+static void rtc_device_release(struct class_device *class_dev) -+{ -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ down(&idr_lock); -+ idr_remove(&rtc_idr, rtc->id); -+ up(&idr_lock); -+ kfree(rtc); -+} -+ -+/** -+ * rtc_device_register - register w/ RTC class -+ * @dev: the device to register -+ * -+ * rtc_device_unregister() must be called when the class device is no -+ * longer needed. -+ * -+ * Returns the pointer to the new struct class device. -+ */ -+struct rtc_device *rtc_device_register(char *name, struct device *dev, -+ struct rtc_class_ops *ops, -+ struct module *owner) -+{ -+ struct rtc_device *rtc; -+ int id, err; -+ -+ if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ -+ down(&idr_lock); -+ err = idr_get_new(&rtc_idr, NULL, &id); -+ up(&idr_lock); -+ -+ if (err < 0) -+ goto exit; -+ -+ id = id & MAX_ID_MASK; -+ -+ if ((rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL)) == NULL) { -+ err = -ENOMEM; -+ goto exit_idr; -+ } -+ -+ rtc->id = id; -+ rtc->ops = ops; -+ rtc->owner = owner; -+ rtc->class_dev.dev = dev; -+ rtc->class_dev.class = rtc_class; -+ rtc->class_dev.release = rtc_device_release; -+ -+ init_rwsem(&rtc->lock); -+ spin_lock_init(&rtc->irq_lock); -+ spin_lock_init(&rtc->irq_task_lock); -+ -+ strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); -+ snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); -+ -+ if ((err = class_device_register(&rtc->class_dev))) -+ goto exit_kfree; -+ -+ dev_info(dev, "rtc core: registered %s as %s\n", -+ rtc->name, rtc->class_dev.class_id); -+ -+ return rtc; -+ -+exit_kfree: -+ kfree(rtc); -+ -+exit_idr: -+ idr_remove(&rtc_idr, id); -+ -+exit: -+ return ERR_PTR(err); -+} -+EXPORT_SYMBOL_GPL(rtc_device_register); -+ -+ -+/** -+ * rtc_device_unregister - removes the previously registered RTC class device -+ * -+ * @rtc: the RTC class device to destroy -+ */ -+void rtc_device_unregister(struct rtc_device *rtc) -+{ -+ down_write(&rtc->lock); -+ class_device_unregister(&rtc->class_dev); -+} -+EXPORT_SYMBOL_GPL(rtc_device_unregister); -+ -+int rtc_interface_register(struct class_interface *intf) -+{ -+ intf->class = rtc_class; -+ return class_interface_register(intf); -+} -+EXPORT_SYMBOL_GPL(rtc_interface_register); -+ -+static int __init rtc_init(void) -+{ -+ rtc_class = class_create(THIS_MODULE, "rtc"); -+ if (IS_ERR(rtc_class)) { -+ printk(KERN_ERR "%s: couldn't create class\n", __FILE__); -+ return PTR_ERR(rtc_class); -+ } -+ return 0; -+} -+ -+static void __exit rtc_exit(void) -+{ -+ class_destroy(rtc_class); -+} -+ -+module_init(rtc_init); -+module_exit(rtc_exit); -+ -+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towerteh.it>"); -+MODULE_DESCRIPTION("RTC class support"); -+MODULE_LICENSE("GPL"); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/Kconfig 2006-01-04 01:27:21.000000000 +0100 -@@ -0,0 +1,93 @@ -+# -+# RTC class/drivers configuration -+# -+ -+menu "Real Time Clock" -+ -+config RTC_CLASS -+ tristate "RTC class" -+ depends on EXPERIMENTAL -+ default y -+ help -+ Generic RTC class support. If you say yes here, you will -+ be allowed to plug one or more RTCs to your system. You will -+ probably want to enable one of more of the interfaces below. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-class. -+ -+comment "RTC interfaces" -+ depends on RTC_CLASS -+ -+config RTC_INTF_SYSFS -+ tristate "sysfs" -+ depends on RTC_CLASS && SYSFS -+ default RTC_CLASS -+ help -+ Say yes here if you want to use your RTC using the sysfs -+ interface, /sys/class/rtc/rtcX . -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-sysfs. -+ -+config RTC_INTF_PROC -+ tristate "proc" -+ depends on RTC_CLASS && PROC_FS -+ default RTC_CLASS -+ help -+ Say yes here if you want to use your RTC using the proc -+ interface, /proc/driver/rtc . -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-proc. -+ -+config RTC_INTF_DEV -+ tristate "dev" -+ depends on RTC_CLASS -+ default RTC_CLASS -+ help -+ Say yes here if you want to use your RTC using the dev -+ interface, /dev/rtc . -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-dev. -+ -+comment "RTC drivers" -+ depends on RTC_CLASS -+ -+config RTC_DRV_X1205 -+ tristate "Xicor/Intersil X1205 RTC chip" -+ depends on RTC_CLASS && I2C -+ help -+ If you say yes here you get support for the -+ Xicor/Intersil X1205 RTC chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-x1205. -+ -+config RTC_DRV_DS1672 -+ tristate "Dallas/Maxim DS1672" -+ depends on RTC_CLASS && I2C -+ help -+ If you say yes here you get support for the -+ Dallas/Maxim DS1672 timekeeping chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-ds1672. -+ -+config RTC_DRV_TEST -+ tristate "Test driver/device" -+ depends on RTC_CLASS -+ help -+ If you say yes here you get support for the -+ RTC test driver. It's a software RTC which can be -+ used to test the RTC subsystem APIs. It gets -+ the time from the system clock. -+ You want this driver only if you are doing development -+ on the RTC subsystem. Please read the source code -+ for further details. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-test. -+ -+endmenu ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/Makefile 2006-01-04 01:27:21.000000000 +0100 -@@ -0,0 +1,15 @@ -+# -+# Makefile for RTC class/drivers. -+# -+ -+obj-y += utils.o -+obj-$(CONFIG_RTC_CLASS) += rtc-core.o -+rtc-core-y := class.o interface.o -+obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o -+obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o -+obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o -+ -+obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o -+obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o -+obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o -+ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/interface.c 2006-01-03 15:34:24.000000000 +0100 -@@ -0,0 +1,189 @@ -+/* -+ * RTC subsystem, interface functions -+ * -+ * Copyright (C) 2005 Tower Technologies -+ * Author: Alessandro Zummo <a.zummo@towertech.it> -+ * -+ * based on arch/arm/common/rtctime.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+*/ -+ -+#include <linux/rtc.h> -+ -+extern struct class *rtc_class; -+ -+int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) -+{ -+ int err = -EINVAL; -+ struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; -+ -+ if (ops->read_time) { -+ memset(tm, 0, sizeof(struct rtc_time)); -+ err = ops->read_time(class_dev->dev, tm); -+ } -+ return err; -+} -+EXPORT_SYMBOL(rtc_read_time); -+ -+int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) -+{ -+ int err; -+ struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; -+ -+ err = rtc_valid_tm(tm); -+ if (err == 0 && ops->set_time) -+ err = ops->set_time(class_dev->dev, tm); -+ -+ return err; -+} -+EXPORT_SYMBOL(rtc_set_time); -+ -+int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) -+{ -+ struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; -+ int err = -EINVAL; -+ -+ if (ops->read_alarm) { -+ memset(alarm, 0, sizeof(struct rtc_wkalrm)); -+ err = ops->read_alarm(class_dev->dev, alarm); -+ } -+ return err; -+} -+EXPORT_SYMBOL(rtc_read_alarm); -+ -+int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) -+{ -+ int err = -EINVAL; -+ struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; -+ -+ if (ops->set_alarm) -+ err = ops->set_alarm(class_dev->dev, alarm); -+ return err; -+} -+EXPORT_SYMBOL(rtc_set_alarm); -+ -+void rtc_update_irq(struct class_device *class_dev, -+ unsigned long num, unsigned long events) -+{ -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ -+ spin_lock(&rtc->irq_lock); -+ rtc->irq_data = (rtc->irq_data + (num << 8)) | events; -+ spin_unlock(&rtc->irq_lock); -+ -+ spin_lock(&rtc->irq_task_lock); -+ if (rtc->irq_task) -+ rtc->irq_task->func(rtc->irq_task->private_data); -+ spin_unlock(&rtc->irq_task_lock); -+ -+ wake_up_interruptible(&rtc->irq_queue); -+ kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); -+} -+EXPORT_SYMBOL(rtc_update_irq); -+ -+struct class_device *rtc_open(char *name) -+{ -+ struct class_device *class_dev = NULL, -+ *class_dev_tmp; -+ -+ down(&rtc_class->sem); -+ list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { -+ if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { -+ class_dev = class_dev_tmp; -+ break; -+ } -+ } -+ up(&rtc_class->sem); -+ -+ return class_dev; -+} -+EXPORT_SYMBOL(rtc_open); -+ -+void rtc_close(struct class_device *class_dev) -+{ -+} -+EXPORT_SYMBOL(rtc_close); -+ -+int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) -+{ -+ int retval = -EBUSY; -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ -+ if (task == NULL || task->func == NULL) -+ return -EINVAL; -+ -+ spin_lock(&rtc->irq_task_lock); -+ if (rtc->irq_task == NULL) { -+ rtc->irq_task = task; -+ retval = 0; -+ } -+ spin_unlock(&rtc->irq_task_lock); -+ -+ return retval; -+} -+EXPORT_SYMBOL(rtc_irq_register); -+ -+void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) -+{ -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ -+ spin_lock(&rtc->irq_task_lock); -+ if (rtc->irq_task == task) -+ rtc->irq_task = NULL; -+ spin_unlock(&rtc->irq_task_lock); -+} -+EXPORT_SYMBOL(rtc_irq_unregister); -+ -+int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) -+{ -+ int err = 0; -+ unsigned long flags; -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ -+ spin_lock_irqsave(&rtc->irq_task_lock, flags); -+ if (rtc->irq_task != task) -+ err = -ENXIO; -+ spin_unlock_irqrestore(&rtc->irq_task_lock, flags); -+ -+ if (err == 0) -+ err = rtc->ops->irq_set_state(class_dev->dev, enabled); -+ -+ return err; -+} -+EXPORT_SYMBOL(rtc_irq_set_state); -+ -+int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) -+{ -+ int err = 0, tmp = 0; -+ unsigned long flags; -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ -+ /* allowed range is 2-8192 */ -+ if (freq < 2 || freq > 8192) -+ return -EINVAL; -+ -+/* if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) -+ return -EACCES; -+*/ -+ /* check if freq is a power of 2 */ -+ while (freq > (1 << tmp)) -+ tmp++; -+ -+ if (freq != (1 << tmp)) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&rtc->irq_task_lock, flags); -+ if (rtc->irq_task != task) -+ err = -ENXIO; -+ spin_unlock_irqrestore(&rtc->irq_task_lock, flags); -+ -+ if (err == 0) { -+ if ((err = rtc->ops->irq_set_freq(class_dev->dev, freq)) == 0) -+ rtc->irq_freq = freq; -+ } -+ return err; -+ -+} ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/utils.c 2006-01-03 15:34:24.000000000 +0100 -@@ -0,0 +1,97 @@ -+/* -+ * RTC subsystem, utility functions -+ * -+ * Copyright (C) 2005 Tower Technologies -+ * Author: Alessandro Zummo <a.zummo@towertech.it> -+ * -+ * based on arch/arm/common/rtctime.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+*/ -+ -+#include <linux/rtc.h> -+ -+static const unsigned char rtc_days_in_month[] = { -+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -+}; -+ -+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -+#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) -+ -+int rtc_month_days(unsigned int month, unsigned int year) -+{ -+ return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); -+} -+EXPORT_SYMBOL(rtc_month_days); -+ -+/* -+ * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. -+ */ -+void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) -+{ -+ int days, month, year; -+ -+ days = time / 86400; -+ time -= days * 86400; -+ -+ tm->tm_wday = (days + 4) % 7; -+ -+ year = 1970 + days / 365; -+ days -= (year - 1970) * 365 -+ + LEAPS_THRU_END_OF(year - 1) -+ - LEAPS_THRU_END_OF(1970 - 1); -+ if (days < 0) { -+ year -= 1; -+ days += 365 + LEAP_YEAR(year); -+ } -+ tm->tm_year = year - 1900; -+ tm->tm_yday = days + 1; -+ -+ for (month = 0; month < 11; month++) { -+ int newdays; -+ -+ newdays = days - rtc_month_days(month, year); -+ if (newdays < 0) -+ break; -+ days = newdays; -+ } -+ tm->tm_mon = month; -+ tm->tm_mday = days + 1; -+ -+ tm->tm_hour = time / 3600; -+ time -= tm->tm_hour * 3600; -+ tm->tm_min = time / 60; -+ tm->tm_sec = time - tm->tm_min * 60; -+} -+EXPORT_SYMBOL(rtc_time_to_tm); -+ -+/* -+ * Does the rtc_time represent a valid date/time? -+ */ -+int rtc_valid_tm(struct rtc_time *tm) -+{ -+ if (tm->tm_year < 70 || -+ tm->tm_mon >= 12 || -+ tm->tm_mday < 1 || -+ tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) || -+ tm->tm_hour >= 24 || -+ tm->tm_min >= 60 || -+ tm->tm_sec >= 60) -+ return -EINVAL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(rtc_valid_tm); -+ -+/* -+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00. -+ */ -+int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) -+{ -+ *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, -+ tm->tm_hour, tm->tm_min, tm->tm_sec); -+ return 0; -+} -+EXPORT_SYMBOL(rtc_tm_to_time); ---- linux-nslu2.orig/arch/arm/Kconfig 2006-01-04 01:27:04.000000000 +0100 -+++ linux-nslu2/arch/arm/Kconfig 2006-01-04 01:27:31.000000000 +0100 -@@ -750,6 +750,8 @@ source "drivers/usb/Kconfig" - - source "drivers/mmc/Kconfig" - -+source "drivers/rtc/Kconfig" -+ - endmenu - - source "fs/Kconfig" ---- linux-nslu2.orig/arch/arm/common/rtctime.c 2006-01-04 01:27:04.000000000 +0100 -+++ linux-nslu2/arch/arm/common/rtctime.c 2006-01-04 01:27:09.000000000 +0100 -@@ -40,89 +40,6 @@ static struct rtc_ops *rtc_ops; - - #define rtc_epoch 1900UL - --static const unsigned char days_in_month[] = { -- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 --}; -- --#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) --#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) -- --static int month_days(unsigned int month, unsigned int year) --{ -- return days_in_month[month] + (LEAP_YEAR(year) && month == 1); --} -- --/* -- * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. -- */ --void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) --{ -- int days, month, year; -- -- days = time / 86400; -- time -= days * 86400; -- -- tm->tm_wday = (days + 4) % 7; -- -- year = 1970 + days / 365; -- days -= (year - 1970) * 365 -- + LEAPS_THRU_END_OF(year - 1) -- - LEAPS_THRU_END_OF(1970 - 1); -- if (days < 0) { -- year -= 1; -- days += 365 + LEAP_YEAR(year); -- } -- tm->tm_year = year - 1900; -- tm->tm_yday = days + 1; -- -- for (month = 0; month < 11; month++) { -- int newdays; -- -- newdays = days - month_days(month, year); -- if (newdays < 0) -- break; -- days = newdays; -- } -- tm->tm_mon = month; -- tm->tm_mday = days + 1; -- -- tm->tm_hour = time / 3600; -- time -= tm->tm_hour * 3600; -- tm->tm_min = time / 60; -- tm->tm_sec = time - tm->tm_min * 60; --} --EXPORT_SYMBOL(rtc_time_to_tm); -- --/* -- * Does the rtc_time represent a valid date/time? -- */ --int rtc_valid_tm(struct rtc_time *tm) --{ -- if (tm->tm_year < 70 || -- tm->tm_mon >= 12 || -- tm->tm_mday < 1 || -- tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) || -- tm->tm_hour >= 24 || -- tm->tm_min >= 60 || -- tm->tm_sec >= 60) -- return -EINVAL; -- -- return 0; --} --EXPORT_SYMBOL(rtc_valid_tm); -- --/* -- * Convert Gregorian date to seconds since 01-01-1970 00:00:00. -- */ --int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) --{ -- *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, -- tm->tm_hour, tm->tm_min, tm->tm_sec); -- -- return 0; --} --EXPORT_SYMBOL(rtc_tm_to_time); -- - /* - * Calculate the next alarm time given the requested alarm time mask - * and the current time. -@@ -141,13 +58,13 @@ void rtc_next_alarm_time(struct rtc_time - next->tm_sec = alrm->tm_sec; - } - --static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) -+static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) - { - memset(tm, 0, sizeof(struct rtc_time)); - return ops->read_time(tm); - } - --static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) -+static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) - { - int ret; - -@@ -158,7 +75,7 @@ static inline int rtc_set_time(struct rt - return ret; - } - --static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -+static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) - { - int ret = -EINVAL; - if (ops->read_alarm) { -@@ -168,7 +85,7 @@ static inline int rtc_read_alarm(struct - return ret; - } - --static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -+static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) - { - int ret = -EINVAL; - if (ops->set_alarm) -@@ -256,7 +173,7 @@ static int rtc_ioctl(struct inode *inode - - switch (cmd) { - case RTC_ALM_READ: -- ret = rtc_read_alarm(ops, &alrm); -+ ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); -@@ -278,11 +195,11 @@ static int rtc_ioctl(struct inode *inode - alrm.time.tm_wday = -1; - alrm.time.tm_yday = -1; - alrm.time.tm_isdst = -1; -- ret = rtc_set_alarm(ops, &alrm); -+ ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_RD_TIME: -- ret = rtc_read_time(ops, &tm); -+ ret = rtc_arm_read_time(ops, &tm); - if (ret) - break; - ret = copy_to_user(uarg, &tm, sizeof(tm)); -@@ -300,7 +217,7 @@ static int rtc_ioctl(struct inode *inode - ret = -EFAULT; - break; - } -- ret = rtc_set_time(ops, &tm); -+ ret = rtc_arm_set_time(ops, &tm); - break; - - case RTC_EPOCH_SET: -@@ -331,11 +248,11 @@ static int rtc_ioctl(struct inode *inode - ret = -EFAULT; - break; - } -- ret = rtc_set_alarm(ops, &alrm); -+ ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_WKALM_RD: -- ret = rtc_read_alarm(ops, &alrm); -+ ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm, sizeof(alrm)); -@@ -425,7 +342,7 @@ static int rtc_read_proc(char *page, cha - struct rtc_time tm; - char *p = page; - -- if (rtc_read_time(ops, &tm) == 0) { -+ if (rtc_arm_read_time(ops, &tm) == 0) { - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" -@@ -435,7 +352,7 @@ static int rtc_read_proc(char *page, cha - rtc_epoch); - } - -- if (rtc_read_alarm(ops, &alrm) == 0) { -+ if (rtc_arm_read_alarm(ops, &alrm) == 0) { - p += sprintf(p, "alrm_time\t: "); - if ((unsigned int)alrm.time.tm_hour <= 24) - p += sprintf(p, "%02d:", alrm.time.tm_hour); ---- linux-nslu2.orig/include/asm-arm/rtc.h 2006-01-04 01:27:04.000000000 +0100 -+++ linux-nslu2/include/asm-arm/rtc.h 2006-01-04 01:27:09.000000000 +0100 -@@ -25,9 +25,6 @@ struct rtc_ops { - int (*proc)(char *buf); - }; - --void rtc_time_to_tm(unsigned long, struct rtc_time *); --int rtc_tm_to_time(struct rtc_time *, unsigned long *); --int rtc_valid_tm(struct rtc_time *); - void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); - void rtc_update(unsigned long, unsigned long); - int register_rtc(struct rtc_ops *); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/rtc-sysfs.c 2006-01-04 01:27:12.000000000 +0100 -@@ -0,0 +1,125 @@ -+/* -+ * RTC subsystem, sysfs interface -+ * -+ * Copyright (C) 2005 Tower Technologies -+ * Author: Alessandro Zummo <a.zummo@towertech.it> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+*/ -+ -+#include <linux/module.h> -+#include <linux/rtc.h> -+ -+/* device attributes */ -+ -+static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf) -+{ -+ return sprintf(buf, "%s\n", to_rtc_device(dev)->name); -+} -+static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL); -+ -+static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf) -+{ -+ ssize_t retval = 0; -+ struct rtc_device *rtc = to_rtc_device(dev); -+ struct rtc_time tm; -+ -+ if (down_read_trylock(&rtc->lock) == 0) -+ return -ENODEV; -+ -+ if (rtc_read_time(dev, &tm) == 0) { -+ retval = sprintf(buf, "%04d-%02d-%02d\n", -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); -+ } -+ -+ up_read(&rtc->lock); -+ return retval; -+} -+static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL); -+ -+static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf) -+{ -+ ssize_t retval = 0; -+ struct rtc_device *rtc = to_rtc_device(dev); -+ struct rtc_time tm; -+ -+ if (down_read_trylock(&rtc->lock) == 0) -+ return -ENODEV; -+ -+ if (rtc_read_time(dev, &tm) == 0) { -+ retval = sprintf(buf, "%02d:%02d:%02d\n", -+ tm.tm_hour, tm.tm_min, tm.tm_sec); -+ } -+ -+ up_read(&rtc->lock); -+ return retval; -+} -+static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL); -+ -+static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf) -+{ -+ ssize_t retval = 0; -+ struct rtc_device *rtc = to_rtc_device(dev); -+ struct rtc_time tm; -+ -+ if (down_read_trylock(&rtc->lock) == 0) -+ return -ENODEV; -+ -+ if (rtc_read_time(dev, &tm) == 0) { -+ unsigned long time; -+ rtc_tm_to_time(&tm, &time); -+ retval = sprintf(buf, "%lu\n", time); -+ } -+ -+ up_read(&rtc->lock); -+ return retval; -+} -+static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL); -+ -+/* insertion/removal hooks */ -+ -+static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, -+ struct class_interface *class_intf) -+{ -+ class_device_create_file(class_dev, &class_device_attr_name); -+ class_device_create_file(class_dev, &class_device_attr_date); -+ class_device_create_file(class_dev, &class_device_attr_time); -+ class_device_create_file(class_dev, &class_device_attr_since_epoch); -+ dev_info(class_dev->dev, "rtc intf: sysfs\n"); -+ return 0; -+} -+ -+static void rtc_sysfs_remove_device(struct class_device *class_dev, -+ struct class_interface *class_intf) -+{ -+ class_device_remove_file(class_dev, &class_device_attr_name); -+ class_device_remove_file(class_dev, &class_device_attr_date); -+ class_device_remove_file(class_dev, &class_device_attr_time); -+ class_device_remove_file(class_dev, &class_device_attr_since_epoch); -+} -+ -+/* interface registration */ -+ -+struct class_interface rtc_sysfs_interface = { -+ .add = &rtc_sysfs_add_device, -+ .remove = &rtc_sysfs_remove_device, -+}; -+ -+static int __init rtc_sysfs_init(void) -+{ -+ return rtc_interface_register(&rtc_sysfs_interface); -+} -+ -+static void __exit rtc_sysfs_exit(void) -+{ -+ class_interface_unregister(&rtc_sysfs_interface); -+} -+ -+module_init(rtc_sysfs_init); -+module_exit(rtc_sysfs_exit); -+ -+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); -+MODULE_DESCRIPTION("RTC class sysfs interface"); -+MODULE_LICENSE("GPL"); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-nslu2/drivers/rtc/rtc-proc.c 2006-01-04 01:27:14.000000000 +0100 -@@ -0,0 +1,158 @@ -+/* -+ * RTC subsystem, proc interface -+ * -+ * Copyright (C) 2005 Tower Technologies -+ * Author: Alessandro Zummo <a.zummo@towertech.it> -+ * -+ * based on arch/arm/common/rtctime.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+*/ -+ -+#include <linux/module.h> -+#include <linux/rtc.h> -+#include <linux/proc_fs.h> -+#include <linux/seq_file.h> -+ -+static struct class_device *rtc_dev = NULL; -+static DECLARE_MUTEX(rtc_sem); -+ -+static int rtc_proc_show(struct seq_file *seq, void *offset) -+{ -+ struct class_device *class_dev = seq->private; -+ struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; -+ struct rtc_wkalrm alrm; -+ struct rtc_time tm; -+ -+ if (rtc_read_time(class_dev, &tm) == 0) { -+ seq_printf(seq, -+ "rtc_time\t: %02d:%02d:%02d\n" -+ "rtc_date\t: %04d-%02d-%02d\n", -+ tm.tm_hour, tm.tm_min, tm.tm_sec, -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); -+ } -+ -+ if (rtc_read_alarm(class_dev, &alrm) == 0) { -+ seq_printf(seq, "alrm_time\t: "); -+ if ((unsigned int)alrm.time.tm_hour <= 24) -+ seq_printf(seq, "%02d:", alrm.time.tm_hour); -+ else -+ seq_printf(seq, "**:"); -+ if ((unsigned int)alrm.time.tm_min <= 59) -+ seq_printf(seq, "%02d:", alrm.time.tm_min); -+ else -+ seq_printf(seq, "**:"); -+ if ((unsigned int)alrm.time.tm_sec <= 59) -+ seq_printf(seq, "%02d\n", alrm.time.tm_sec); -+ else -+ seq_printf(seq, "**\n"); -+ -+ seq_printf(seq, "alrm_date\t: "); -+ if ((unsigned int)alrm.time.tm_year <= 200) -+ seq_printf(seq, "%04d-", alrm.time.tm_year + 1900); -+ else -+ seq_printf(seq, "****-"); -+ if ((unsigned int)alrm.time.tm_mon <= 11) -+ seq_printf(seq, "%02d-", alrm.time.tm_mon + 1); -+ else -+ seq_printf(seq, "**-"); -+ if ((unsigned int)alrm.time.tm_mday <= 31) -+ seq_printf(seq, "%02d\n", alrm.time.tm_mday); -+ else -+ seq_printf(seq, "**\n"); -+ seq_printf(seq, "alrm_wakeup\t: %s\n", -+ alrm.enabled ? "yes" : "no"); -+ seq_printf(seq, "alrm_pending\t: %s\n", -+ alrm.pending ? "yes" : "no"); -+ } -+ -+ if (ops->proc) -+ ops->proc(class_dev->dev, seq); -+ -+ return 0; -+} -+ -+static int rtc_proc_open(struct inode *inode, struct file *file) -+{ -+ struct class_device *class_dev = PDE(inode)->data; -+ -+ if (!try_module_get(THIS_MODULE)) -+ return -ENODEV; -+ -+ return single_open(file, rtc_proc_show, class_dev); -+} -+ -+static int rtc_proc_release(struct inode *inode, struct file *file) -+{ -+ int res = single_release(inode, file); -+ module_put(THIS_MODULE); -+ return res; -+} -+ -+static struct file_operations rtc_proc_fops = { -+ .open = rtc_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = rtc_proc_release, -+}; -+ -+static int rtc_proc_add_device(struct class_device *class_dev, -+ struct class_interface *class_intf) -+{ -+ down(&rtc_sem); -+ if (rtc_dev == NULL) { -+ struct proc_dir_entry *ent; -+ -+ rtc_dev = class_dev; -+ -+ if ((ent = create_proc_entry("driver/rtc", 0, NULL))) { -+ struct rtc_device *rtc = to_rtc_device(class_dev); -+ -+ ent->proc_fops = &rtc_proc_fops; -+ ent->owner = rtc->owner; -+ ent->data = class_dev; -+ -+ dev_info(class_dev->dev, "rtc intf: proc\n"); -+ } -+ else -+ rtc_dev = NULL; -+ } -+ up(&rtc_sem); -+ -+ return 0; -+} -+ -+static void rtc_proc_remove_device(struct class_device *class_dev, -+ struct class_interface *class_intf) -+{ -+ down(&rtc_sem); -+ if (rtc_dev == class_dev) { -+ remove_proc_entry("driver/rtc", NULL); -+ rtc_dev = NULL; -+ } -+ up(&rtc_sem); -+} -+ -+struct class_interface rtc_proc_interface = { -+ .add = &rtc_proc_add_device, -+ .remove = &rtc_proc_remove_device, -+}; -+ -+static int __init rtc_proc_init(void) -+{ -+ return rtc_interface_register(&rtc_proc_interface); - |
