summaryrefslogtreecommitdiff
path: root/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
diff options
context:
space:
mode:
authorRod Whitby <rod@whitby.id.au>2006-04-14 06:39:54 +0000
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>2006-04-14 06:39:54 +0000
commitc9cadd074271be3812dfc501d98ae93df22d7bd0 (patch)
tree5817ca1378e5e20cae845cfe0dfe48764529e6c5 /packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
parent5c26c1237a294e04c6a8542d11d15a4200f70a8a (diff)
ixp4xx-kernel: Removed obsolete patches, and refreshed patchset from the nslu2-linux kernel CVS repo.
Diffstat (limited to 'packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch')
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch2434
1 files changed, 1780 insertions, 654 deletions
diff --git a/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch b/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
index 3cc84b2a9b..044bd3abc1 100644
--- a/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
+++ b/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
@@ -1,6 +1,365 @@
---- linux-rtc.orig/include/linux/rtc.h 2006-02-19 23:33:10.000000000 +0100
-+++ linux-rtc/include/linux/rtc.h 2006-02-19 23:33:15.000000000 +0100
-@@ -93,8 +93,97 @@ struct rtc_pll_info {
+---
+ CREDITS | 5
+ MAINTAINERS | 6
+ arch/arm/Kconfig | 3
+ arch/arm/common/rtctime.c | 108 --
+ arch/arm/mach-integrator/time.c | 16
+ arch/arm/mach-pxa/generic.c | 6
+ arch/arm/mach-sa1100/generic.c | 6
+ arch/mips/ddb5xxx/common/rtc_ds1386.c | 4
+ arch/mips/dec/time.c | 4
+ arch/mips/ite-boards/generic/time.c | 4
+ arch/mips/jmr3927/common/rtc_ds1742.c | 4
+ arch/mips/kernel/time.c | 22
+ arch/mips/lasat/setup.c | 4
+ arch/mips/mips-boards/atlas/atlas_setup.c | 2
+ arch/mips/mips-boards/malta/malta_setup.c | 2
+ arch/mips/momentum/jaguar_atx/setup.c | 4
+ arch/mips/momentum/ocelot_3/setup.c | 4
+ arch/mips/momentum/ocelot_c/setup.c | 4
+ arch/mips/pmc-sierra/yosemite/setup.c | 4
+ arch/mips/sgi-ip22/ip22-time.c | 4
+ arch/mips/sgi-ip32/ip32-setup.c | 4
+ arch/mips/sibyte/swarm/setup.c | 8
+ arch/mips/sni/setup.c | 4
+ arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c | 4
+ arch/mips/tx4938/common/rtc_rx5c348.c | 4
+ drivers/Kconfig | 2
+ drivers/Makefile | 1
+ drivers/char/Kconfig | 2
+ drivers/i2c/chips/Kconfig | 18
+ drivers/i2c/chips/Makefile | 2
+ drivers/i2c/chips/rtc8564.c | 385 -------
+ drivers/i2c/chips/rtc8564.h | 78 -
+ drivers/i2c/chips/x1205.c | 698 -------------
+ drivers/rtc/Kconfig | 156 ++
+ drivers/rtc/Makefile | 20
+ drivers/rtc/class.c | 145 ++
+ drivers/rtc/hctosys.c | 69 +
+ drivers/rtc/interface.c | 277 +++++
+ drivers/rtc/rtc-dev.c | 382 +++++++
+ drivers/rtc/rtc-ds1672.c | 233 ++++
+ drivers/rtc/rtc-ep93xx.c | 163 +++
+ drivers/rtc/rtc-lib.c | 99 +
+ drivers/rtc/rtc-pcf8563.c | 355 ++++++
+ drivers/rtc/rtc-proc.c | 162 +++
+ drivers/rtc/rtc-rs5c372.c | 295 +++++
+ drivers/rtc/rtc-sa1100.c | 392 +++++++
+ drivers/rtc/rtc-sysfs.c | 124 ++
+ drivers/rtc/rtc-test.c | 205 +++
+ drivers/rtc/rtc-x1205.c | 619 +++++++++++
+ include/asm-arm/rtc.h | 3
+ include/asm-mips/time.h | 12
+ include/linux/rtc.h | 92 +
+ include/linux/x1205.h | 31
+ 53 files changed, 3888 insertions(+), 1372 deletions(-)
+
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-ixp4xx/drivers/rtc/rtc-lib.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,99 @@
++/*
++ * rtc and date/time utility functions
++ *
++ * Copyright (C) 2005-06 Tower Technologies
++ * Author: Alessandro Zummo <a.zummo@towertech.it>
++ *
++ * based on arch/arm/common/rtctime.c and other bits
++ *
++ * 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>
++
++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)
++{
++ register int days, month, year;
++
++ days = time / 86400;
++ time -= days * 86400;
++
++ /* day of the week, 1970-01-01 was a Thursday */
++ 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);
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-ixp4xx/drivers/rtc/Makefile 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,20 @@
++#
++# Makefile for RTC class/drivers.
++#
++
++obj-$(CONFIG_RTC_LIB) += rtc-lib.o
++obj-$(CONFIG_RTC_HCTOSYS) += hctosys.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
++obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
++obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
++obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
++obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-ixp4xx/drivers/rtc/Kconfig 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,156 @@
++\#
++# RTC class/drivers configuration
++#
++
++menu "Real Time Clock"
++
++config RTC_LIB
++ bool
++
++config RTC_CLASS
++ tristate "RTC class"
++ depends on EXPERIMENTAL
++ default n
++ select RTC_LIB
++ 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.
++
++config RTC_HCTOSYS
++ bool "Set system time from RTC on startup"
++ depends on RTC_CLASS = y
++ default y
++ help
++ If you say yes here, the system time will be set using
++ the value read from the specified RTC device. This is useful
++ in order to avoid unnecessary fschk runs.
++
++config RTC_HCTOSYS_DEVICE
++ string "The RTC to read the time from"
++ depends on RTC_HCTOSYS = y
++ default "rtc0"
++ help
++ The RTC device that will be used as the source for
++ the system time, usually rtc0.
++
++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_PCF8563
++ tristate "Philips PCF8563/Epson RTC8564"
++ depends on RTC_CLASS && I2C
++ help
++ If you say yes here you get support for the
++ Philips PCF8563 RTC chip. The Epson RTC8564
++ should work as well.
++
++ This driver can also be built as a module. If so, the module
++ will be called rtc-pcf8563.
++
++config RTC_DRV_RS5C372
++ tristate "Ricoh RS5C372A/B"
++ depends on RTC_CLASS && I2C
++ help
++ If you say yes here you get support for the
++ Ricoh RS5C372A and RS5C372B RTC chips.
++
++ This driver can also be built as a module. If so, the module
++ will be called rtc-rs5c372.
++
++config RTC_DRV_EP93XX
++ tristate "Cirrus Logic EP93XX"
++ depends on RTC_CLASS && ARCH_EP93XX
++ help
++ If you say yes here you get support for the
++ RTC embedded in the Cirrus Logic EP93XX processors.
++
++ This driver can also be built as a module. If so, the module
++ will be called rtc-ep93xx.
++
++
++config RTC_DRV_SA1100
++ bool "SA11x0/PXA2xx RTC support"
++ depends on ARCH_SA1100 || ARCH_PXA
++ help
++ If you say Y here you will get access to the real time clock
++ built into your SA11x0 or PXA2xx CPU.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rtc-sa1100.
++
++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
+--- linux-ixp4xx.orig/drivers/Kconfig 2006-03-08 01:59:18.000000000 +0100
++++ linux-ixp4xx/drivers/Kconfig 2006-03-08 01:59:26.000000000 +0100
+@@ -72,4 +72,6 @@ source "drivers/sn/Kconfig"
+
+ source "drivers/edac/Kconfig"
+
++source "drivers/rtc/Kconfig"
++
+ endmenu
+--- linux-ixp4xx.orig/drivers/Makefile 2006-03-08 01:59:18.000000000 +0100
++++ linux-ixp4xx/drivers/Makefile 2006-03-08 01:59:26.000000000 +0100
+@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/
+ obj-$(CONFIG_GAMEPORT) += input/gameport/
+ obj-$(CONFIG_INPUT) += input/
+ obj-$(CONFIG_I2O) += message/
++obj-$(CONFIG_RTC_LIB) += rtc/
+ obj-$(CONFIG_I2C) += i2c/
+ obj-$(CONFIG_W1) += w1/
+ obj-$(CONFIG_HWMON) += hwmon/
+--- linux-ixp4xx.orig/include/linux/rtc.h 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/include/linux/rtc.h 2006-03-08 01:59:26.000000000 +0100
+@@ -93,8 +93,100 @@ 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 */
@@ -12,12 +371,19 @@
+
#ifdef __KERNEL__
++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);
++
+#include <linux/device.h>
+#include <linux/seq_file.h>
+#include <linux/cdev.h>
+#include <linux/poll.h>
+#include <linux/mutex.h>
+
++extern struct class *rtc_class;
++
+struct rtc_class_ops {
+ int (*open)(struct device *);
+ void (*release)(struct device *);
@@ -47,6 +413,7 @@
+ struct rtc_class_ops *ops;
+ struct mutex ops_lock;
+
++ struct class_device *rtc_dev;
+ struct cdev char_dev;
+ struct mutex char_lock;
+
@@ -68,11 +435,6 @@
+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_set_mmss(struct class_device *class_dev, unsigned long secs);
@@ -98,28 +460,609 @@
typedef struct rtc_task {
void (*func)(void *private_data);
void *private_data;
---- linux-rtc.orig/drivers/Kconfig 2006-02-19 23:33:10.000000000 +0100
-+++ linux-rtc/drivers/Kconfig 2006-02-19 23:33:15.000000000 +0100
-@@ -70,4 +70,6 @@ source "drivers/sn/Kconfig"
+--- linux-ixp4xx.orig/arch/arm/common/rtctime.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/arm/common/rtctime.c 2006-03-08 01:59:26.000000000 +0100
+@@ -20,6 +20,7 @@
+ #include <linux/capability.h>
+ #include <linux/device.h>
+ #include <linux/mutex.h>
++#include <linux/rtc.h>
- source "drivers/edac/Kconfig"
+ #include <asm/rtc.h>
+ #include <asm/semaphore.h>
+@@ -42,89 +43,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.
+@@ -151,13 +69,13 @@ void rtc_next_alarm_time(struct rtc_time
+ }
+ }
+
+-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;
+
+@@ -168,7 +86,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) {
+@@ -178,7 +96,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)
+@@ -266,7 +184,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));
+@@ -288,11 +206,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));
+@@ -310,7 +228,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:
+@@ -341,11 +259,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));
+@@ -435,7 +353,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"
+@@ -445,7 +363,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-ixp4xx.orig/include/asm-arm/rtc.h 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/include/asm-arm/rtc.h 2006-03-08 01:59:26.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 *);
+--- linux-ixp4xx.orig/drivers/char/Kconfig 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/drivers/char/Kconfig 2006-03-08 01:59:26.000000000 +0100
+@@ -695,7 +695,7 @@ config NVRAM
+
+ config RTC
+ tristate "Enhanced Real Time Clock Support"
+- depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV
++ depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM
+ ---help---
+ If you say Y here and create a character special file /dev/rtc with
+ major number 10 and minor number 135 using mknod ("man mknod"), you
+--- linux-ixp4xx.orig/arch/arm/Kconfig 2006-03-08 01:59:18.000000000 +0100
++++ linux-ixp4xx/arch/arm/Kconfig 2006-03-08 01:59:26.000000000 +0100
+@@ -8,6 +8,7 @@ mainmenu "Linux Kernel Configuration"
+ config ARM
+ bool
+ default y
++ select RTC_LIB
+ help
+ The ARM series is a line of low-power-consumption RISC chip designs
+ licensed by ARM Ltd and targeted at embedded applications and
+@@ -819,6 +820,8 @@ source "drivers/usb/Kconfig"
+
+ source "drivers/mmc/Kconfig"
+source "drivers/rtc/Kconfig"
+
endmenu
---- linux-rtc.orig/drivers/Makefile 2006-02-19 23:33:10.000000000 +0100
-+++ linux-rtc/drivers/Makefile 2006-02-19 23:33:15.000000000 +0100
-@@ -56,6 +56,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/
+
+ source "fs/Kconfig"
+--- linux-ixp4xx.orig/arch/arm/mach-integrator/time.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/arm/mach-integrator/time.c 2006-03-08 01:59:26.000000000 +0100
+@@ -40,13 +40,13 @@ static int integrator_set_rtc(void)
+ return 1;
+ }
+
+-static int rtc_read_alarm(struct rtc_wkalrm *alrm)
++static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm)
+ {
+ rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
+ return 0;
+ }
+
+-static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
++static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm)
+ {
+ unsigned long time;
+ int ret;
+@@ -62,7 +62,7 @@ static inline int rtc_set_alarm(struct r
+ return ret;
+ }
+
+-static int rtc_read_time(struct rtc_time *tm)
++static int integrator_rtc_read_time(struct rtc_time *tm)
+ {
+ rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
+ return 0;
+@@ -76,7 +76,7 @@ static int rtc_read_time(struct rtc_time
+ * edge of the 1Hz clock, we must write the time one second
+ * in advance.
+ */
+-static inline int rtc_set_time(struct rtc_time *tm)
++static inline int integrator_rtc_set_time(struct rtc_time *tm)
+ {
+ unsigned long time;
+ int ret;
+@@ -90,10 +90,10 @@ static inline int rtc_set_time(struct rt
+
+ static struct rtc_ops rtc_ops = {
+ .owner = THIS_MODULE,
+- .read_time = rtc_read_time,
+- .set_time = rtc_set_time,
+- .read_alarm = rtc_read_alarm,
+- .set_alarm = rtc_set_alarm,
++ .read_time = integrator_rtc_read_time,
++ .set_time = integrator_rtc_set_time,
++ .read_alarm = integrator_rtc_read_alarm,
++ .set_alarm = integrator_rtc_set_alarm,
+ };
+
+ static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id,
+--- linux-ixp4xx.orig/arch/mips/ddb5xxx/common/rtc_ds1386.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/ddb5xxx/common/rtc_ds1386.c 2006-03-08 01:59:26.000000000 +0100
+@@ -165,6 +165,6 @@ rtc_ds1386_init(unsigned long base)
+ WRITE_RTC(0xB, byte);
+
+ /* set the function pointers */
+- rtc_get_time = rtc_ds1386_get_time;
+- rtc_set_time = rtc_ds1386_set_time;
++ rtc_mips_get_time = rtc_ds1386_get_time;
++ rtc_mips_set_time = rtc_ds1386_set_time;
+ }
+--- linux-ixp4xx.orig/arch/mips/dec/time.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/dec/time.c 2006-03-08 01:59:26.000000000 +0100
+@@ -193,8 +193,8 @@ static void dec_ioasic_hpt_init(unsigned
+
+ void __init dec_time_init(void)
+ {
+- rtc_get_time = dec_rtc_get_time;
+- rtc_set_mmss = dec_rtc_set_mmss;
++ rtc_mips_get_time = dec_rtc_get_time;
++ rtc_mips_set_mmss = dec_rtc_set_mmss;
+
+ mips_timer_state = dec_timer_state;
+ mips_timer_ack = dec_timer_ack;
+--- linux-ixp4xx.orig/arch/mips/ite-boards/generic/time.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/ite-boards/generic/time.c 2006-03-08 01:59:26.000000000 +0100
+@@ -227,8 +227,8 @@ void __init it8172_time_init(void)
+
+ local_irq_restore(flags);
+
+- rtc_get_time = it8172_rtc_get_time;
+- rtc_set_time = it8172_rtc_set_time;
++ rtc_mips_get_time = it8172_rtc_get_time;
++ rtc_mips_set_time = it8172_rtc_set_time;
+ }
+
+ #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+--- linux-ixp4xx.orig/arch/mips/jmr3927/common/rtc_ds1742.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/jmr3927/common/rtc_ds1742.c 2006-03-08 01:59:26.000000000 +0100
+@@ -159,8 +159,8 @@ rtc_ds1742_init(unsigned long base)
+ db_assert((rtc_base & 0xe0000000) == KSEG1);
+
+ /* set the function pointers */
+- rtc_get_time = rtc_ds1742_get_time;
+- rtc_set_time = rtc_ds1742_set_time;
++ rtc_mips_get_time = rtc_ds1742_get_time;
++ rtc_mips_set_time = rtc_ds1742_set_time;
+
+ /* clear oscillator stop bit */
+ CMOS_WRITE(RTC_READ, RTC_CONTROL);
+--- linux-ixp4xx.orig/arch/mips/kernel/time.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/kernel/time.c 2006-03-08 01:59:26.000000000 +0100
+@@ -65,9 +65,9 @@ static int null_rtc_set_time(unsigned lo
+ return 0;
+ }
+
+-unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
+-int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
+-int (*rtc_set_mmss)(unsigned long);
++unsigned long (*rtc_mips_get_time)(void) = null_rtc_get_time;
++int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time;
++int (*rtc_mips_set_mmss)(unsigned long);
+
+
+ /* usecs per counter cycle, shifted to left by 32 bits */
+@@ -438,7 +438,7 @@ irqreturn_t timer_interrupt(int irq, voi
+
+ /*
+ * If we have an externally synchronized Linux clock, then update
+- * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
++ * CMOS clock accordingly every ~11 minutes. rtc_mips_set_time() has to be
+ * called as close as possible to 500 ms before the new second starts.
+ */
+ write_seqlock(&xtime_lock);
+@@ -446,7 +446,7 @@ irqreturn_t timer_interrupt(int irq, voi
+ xtime.tv_sec > last_rtc_update + 660 &&
+ (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+ (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
+- if (rtc_set_mmss(xtime.tv_sec) == 0) {
++ if (rtc_mips_set_mmss(xtime.tv_sec) == 0) {
+ last_rtc_update = xtime.tv_sec;
+ } else {
+ /* do it again in 60 s */
+@@ -563,7 +563,7 @@ asmlinkage void ll_local_timer_interrupt
+ * b) (optional) calibrate and set the mips_hpt_frequency
+ * (only needed if you intended to use fixed_rate_gettimeoffset
+ * or use cpu counter as timer interrupt source)
+- * 2) setup xtime based on rtc_get_time().
++ * 2) setup xtime based on rtc_mips_get_time().
+ * 3) choose a appropriate gettimeoffset routine.
+ * 4) calculate a couple of cached variables for later usage
+ * 5) board_timer_setup() -
+@@ -631,10 +631,10 @@ void __init time_init(void)
+ if (board_time_init)
+ board_time_init();
+
+- if (!rtc_set_mmss)
+- rtc_set_mmss = rtc_set_time;
++ if (!rtc_mips_set_mmss)
++ rtc_mips_set_mmss = rtc_mips_set_time;
+
+- xtime.tv_sec = rtc_get_time();
++ xtime.tv_sec = rtc_mips_get_time();
+ xtime.tv_nsec = 0;
+
+ set_normalized_timespec(&wall_to_monotonic,
+@@ -770,8 +770,8 @@ void to_tm(unsigned long tim, struct rtc
+
+ EXPORT_SYMBOL(rtc_lock);
+ EXPORT_SYMBOL(to_tm);
+-EXPORT_SYMBOL(rtc_set_time);
+-EXPORT_SYMBOL(rtc_get_time);
++EXPORT_SYMBOL(rtc_mips_set_time);
++EXPORT_SYMBOL(rtc_mips_get_time);
+
+ unsigned long long sched_clock(void)
+ {
+--- linux-ixp4xx.orig/arch/mips/lasat/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/lasat/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -174,8 +174,8 @@ void __init plat_setup(void)
+
+ #ifdef CONFIG_DS1603
+ ds1603 = &ds_defs[mips_machtype];
+- rtc_get_time = ds1603_read;
+- rtc_set_time = ds1603_set;
++ rtc_mips_get_time = ds1603_read;
++ rtc_mips_set_time = ds1603_set;
+ #endif
+
+ #ifdef DYNAMIC_SERIAL_INIT
+--- linux-ixp4xx.orig/arch/mips/mips-boards/atlas/atlas_setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/mips-boards/atlas/atlas_setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -65,7 +65,7 @@ void __init plat_setup(void)
+
+ board_time_init = mips_time_init;
+ board_timer_setup = mips_timer_setup;
+- rtc_get_time = mips_rtc_get_time;
++ rtc_mips_get_time = mips_rtc_get_time;
+ }
+
+ static void __init serial_init(void)
+--- linux-ixp4xx.orig/arch/mips/mips-boards/malta/malta_setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/mips-boards/malta/malta_setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -225,5 +225,5 @@ void __init plat_setup(void)
+
+ board_time_init = mips_time_init;
+ board_timer_setup = mips_timer_setup;
+- rtc_get_time = mips_rtc_get_time;
++ rtc_mips_get_time = mips_rtc_get_time;
+ }
+--- linux-ixp4xx.orig/arch/mips/momentum/jaguar_atx/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/momentum/jaguar_atx/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -228,8 +228,8 @@ void momenco_time_init(void)
+ mips_hpt_frequency = cpu_clock / 2;
+ board_timer_setup = momenco_timer_setup;
+
+- rtc_get_time = m48t37y_get_time;
+- rtc_set_time = m48t37y_set_time;
++ rtc_mips_get_time = m48t37y_get_time;
++ rtc_mips_set_time = m48t37y_set_time;
+ }
+
+ static struct resource mv_pci_io_mem0_resource = {
+--- linux-ixp4xx.orig/arch/mips/momentum/ocelot_3/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/momentum/ocelot_3/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -215,8 +215,8 @@ void momenco_time_init(void)
+ mips_hpt_frequency = cpu_clock / 2;
+ board_timer_setup = momenco_timer_setup;
+
+- rtc_get_time = m48t37y_get_time;
+- rtc_set_time = m48t37y_set_time;
++ rtc_mips_get_time = m48t37y_get_time;
++ rtc_mips_set_time = m48t37y_set_time;
+ }
+
+ /*
+--- linux-ixp4xx.orig/arch/mips/momentum/ocelot_c/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/momentum/ocelot_c/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -226,8 +226,8 @@ void momenco_time_init(void)
+ printk("momenco_time_init cpu_clock=%d\n", cpu_clock);
+ board_timer_setup = momenco_timer_setup;
+
+- rtc_get_time = m48t37y_get_time;
+- rtc_set_time = m48t37y_set_time;
++ rtc_mips_get_time = m48t37y_get_time;
++ rtc_mips_set_time = m48t37y_set_time;
+ }
+
+ void __init plat_setup(void)
+--- linux-ixp4xx.orig/arch/mips/pmc-sierra/yosemite/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/pmc-sierra/yosemite/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -198,8 +198,8 @@ static void __init py_rtc_setup(void)
+ if (!m48t37_base)
+ printk(KERN_ERR "Mapping the RTC failed\n");
+
+- rtc_get_time = m48t37y_get_time;
+- rtc_set_time = m48t37y_set_time;
++ rtc_mips_get_time = m48t37y_get_time;
++ rtc_mips_set_time = m48t37y_set_time;
+
+ write_seqlock(&xtime_lock);
+ xtime.tv_sec = m48t37y_get_time();
+--- linux-ixp4xx.orig/arch/mips/sgi-ip22/ip22-time.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/sgi-ip22/ip22-time.c 2006-03-08 01:59:26.000000000 +0100
+@@ -212,8 +212,8 @@ static void indy_timer_setup(struct irqa
+ void __init ip22_time_init(void)
+ {
+ /* setup hookup functions */
+- rtc_get_time = indy_rtc_get_time;
+- rtc_set_time = indy_rtc_set_time;
++ rtc_mips_get_time = indy_rtc_get_time;
++ rtc_mips_set_time = indy_rtc_set_time;
+
+ board_time_init = indy_time_init;
+ board_timer_setup = indy_timer_setup;
+--- linux-ixp4xx.orig/arch/mips/sgi-ip32/ip32-setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/sgi-ip32/ip32-setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -91,8 +91,8 @@ void __init plat_setup(void)
+ {
+ board_be_init = ip32_be_init;
+
+- rtc_get_time = mc146818_get_cmos_time;
+- rtc_set_mmss = mc146818_set_rtc_mmss;
++ rtc_mips_get_time = mc146818_get_cmos_time;
++ rtc_mips_set_mmss = mc146818_set_rtc_mmss;
+
+ board_time_init = ip32_time_init;
+ board_timer_setup = ip32_timer_setup;
+--- linux-ixp4xx.orig/arch/mips/sibyte/swarm/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/sibyte/swarm/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -114,14 +114,14 @@ void __init plat_setup(void)
+
+ if (xicor_probe()) {
+ printk("swarm setup: Xicor 1241 RTC detected.\n");
+- rtc_get_time = xicor_get_time;
+- rtc_set_time = xicor_set_time;
++ rtc_mips_get_time = xicor_get_time;
++ rtc_mips_set_time = xicor_set_time;
+ }
+
+ if (m41t81_probe()) {
+ printk("swarm setup: M41T81 RTC detected.\n");
+- rtc_get_time = m41t81_get_time;
+- rtc_set_time = m41t81_set_time;
++ rtc_mips_get_time = m41t81_get_time;
++ rtc_mips_set_time = m41t81_set_time;
+ }
+
+ printk("This kernel optimized for "
+--- linux-ixp4xx.orig/arch/mips/sni/setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/sni/setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -164,8 +164,8 @@ static struct pci_controller sni_control
+
+ static inline void sni_pcimt_time_init(void)
+ {
+- rtc_get_time = mc146818_get_cmos_time;
+- rtc_set_time = mc146818_set_rtc_mmss;
++ rtc_mips_get_time = mc146818_get_cmos_time;
++ rtc_mips_set_time = mc146818_set_rtc_mmss;
+ }
+
+ void __init plat_setup(void)
+--- linux-ixp4xx.orig/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2006-03-08 01:59:26.000000000 +0100
+@@ -1036,8 +1036,8 @@ toshiba_rbtx4927_time_init(void)
+
+ #ifdef CONFIG_RTC_DS1742
+
+- rtc_get_time = rtc_ds1742_get_time;
+- rtc_set_time = rtc_ds1742_set_time;
++ rtc_mips_get_time = rtc_ds1742_get_time;
++ rtc_mips_set_time = rtc_ds1742_set_time;
+
+ TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+ ":rtc_ds1742_init()-\n");
+--- linux-ixp4xx.orig/arch/mips/tx4938/common/rtc_rx5c348.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/mips/tx4938/common/rtc_rx5c348.c 2006-03-08 01:59:26.000000000 +0100
+@@ -197,6 +197,6 @@ rtc_rx5c348_init(int chipid)
+ srtc_24h = 1;
+
+ /* set the function pointers */
+- rtc_get_time = rtc_rx5c348_get_time;
+- rtc_set_time = rtc_rx5c348_set_time;
++ rtc_mips_get_time = rtc_rx5c348_get_time;
++ rtc_mips_set_time = rtc_rx5c348_set_time;
+ }
+--- linux-ixp4xx.orig/include/asm-mips/time.h 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/include/asm-mips/time.h 2006-03-08 01:59:26.000000000 +0100
+@@ -26,14 +26,14 @@ extern spinlock_t rtc_lock;
+
+ /*
+ * RTC ops. By default, they point to no-RTC functions.
+- * rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds.
+- * rtc_set_time - reverse the above translation and set time to RTC.
+- * rtc_set_mmss - similar to rtc_set_time, but only min and sec need
++ * rtc_mips_get_time - mktime(year, mon, day, hour, min, sec) in seconds.
++ * rtc_mips_set_time - reverse the above translation and set time to RTC.
++ * rtc_mips_set_mmss - similar to rtc_set_time, but only min and sec need
+ * to be set. Used by RTC sync-up.
+ */
+-extern unsigned long (*rtc_get_time)(void);
+-extern int (*rtc_set_time)(unsigned long);
+-extern int (*rtc_set_mmss)(unsigned long);
++extern unsigned long (*rtc_mips_get_time)(void);
++extern int (*rtc_mips_set_time)(unsigned long);
++extern int (*rtc_mips_set_mmss)(unsigned long);
+
+ /*
+ * Timer interrupt functions.
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/class.c 2006-02-19 23:33:15.000000000 +0100
-@@ -0,0 +1,143 @@
++++ linux-ixp4xx/drivers/rtc/class.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,145 @@
+/*
+ * RTC subsystem, base class
+ *
@@ -182,7 +1125,8 @@
+
+ id = id & MAX_ID_MASK;
+
-+ if ((rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL)) == NULL) {
++ rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
++ if (rtc == NULL) {
+ err = -ENOMEM;
+ goto exit_idr;
+ }
@@ -201,7 +1145,8 @@
+ 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)))
++ err = class_device_register(&rtc->class_dev);
++ if (err)
+ goto exit_kfree;
+
+ dev_info(dev, "rtc core: registered %s as %s\n",
@@ -264,163 +1209,8 @@
+MODULE_DESCRIPTION("RTC class support");
+MODULE_LICENSE("GPL");
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/Kconfig 2006-02-21 00:36:43.000000000 +0100
-@@ -0,0 +1,131 @@
-+#
-+# 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.
-+
-+config RTC_HCTOSYS
-+ bool "Set system time from RTC on startup"
-+ depends on RTC_CLASS = y
-+ default y
-+ help
-+ If you say yes here, the system time will be set using
-+ the value read from the specified RTC device. This is useful
-+ in order to avoid unnecessary fschk runs.
-+
-+config RTC_HCTOSYS_DEVICE
-+ string "The RTC to read the time from"
-+ depends on RTC_HCTOSYS = y
-+ default "rtc0"
-+ help
-+ The RTC device that will be used as the source for
-+ the system time, usually rtc0.
-+
-+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_PCF8563
-+ tristate "Philips PCF8563/Epson RTC8564"
-+ depends on RTC_CLASS && I2C
-+ help
-+ If you say yes here you get support for the
-+ Philips PCF8563 RTC chip. The Epson RTC8564
-+ should work as well.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called rtc-pcf8563.
-+
-+config RTC_DRV_RS5C372
-+ tristate "Ricoh RS5C372A/B"
-+ depends on RTC_CLASS && I2C
-+ help
-+ If you say yes here you get support for the
-+ Ricoh RS5C372A and RS5C372B RTC chips.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called rtc-rs5c372.
-+
-+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-rtc/drivers/rtc/Makefile 2006-02-21 00:36:43.000000000 +0100
-@@ -0,0 +1,18 @@
-+#
-+# Makefile for RTC class/drivers.
-+#
-+
-+obj-y += utils.o
-+obj-$(CONFIG_RTC_HCTOSYS) += hctosys.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
-+obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
-+obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
-+
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/interface.c 2006-02-19 23:33:15.000000000 +0100
-@@ -0,0 +1,274 @@
++++ linux-ixp4xx/drivers/rtc/interface.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,277 @@
+/*
+ * RTC subsystem, interface functions
+ *
@@ -436,15 +1226,14 @@
+
+#include <linux/rtc.h>
+
-+extern struct class *rtc_class;
-+
+int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
+{
+ int err;
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
-+ if ((err = mutex_lock_interruptible(&rtc->ops_lock)))
-+ return err;
++ err = mutex_lock_interruptible(&rtc->ops_lock);
++ if (err)
++ return -EBUSY;
+
+ if (!rtc->ops)
+ err = -ENODEV;
@@ -458,18 +1247,20 @@
+ mutex_unlock(&rtc->ops_lock);
+ return err;
+}
-+EXPORT_SYMBOL(rtc_read_time);
++EXPORT_SYMBOL_GPL(rtc_read_time);
+
+int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm)
+{
+ int err;
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
-+ if ((err = rtc_valid_tm(tm)) != 0)
++ err = rtc_valid_tm(tm);
++ if (err != 0)
+ return err;
+
-+ if ((err = mutex_lock_interruptible(&rtc->ops_lock)))
-+ return err;
++ err = mutex_lock_interruptible(&rtc->ops_lock);
++ if (err)
++ return -EBUSY;
+
+ if (!rtc->ops)
+ err = -ENODEV;
@@ -481,57 +1272,56 @@
+ mutex_unlock(&rtc->ops_lock);
+ return err;
+}
-+EXPORT_SYMBOL(rtc_set_time);
++EXPORT_SYMBOL_GPL(rtc_set_time);
+
+int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
+{
+ int err;
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
-+ if ((err = mutex_lock_interruptible(&rtc->ops_lock)))
-+ return err;
++ err = mutex_lock_interruptible(&rtc->ops_lock);
++ if (err)
++ return -EBUSY;
+
+ if (!rtc->ops)
+ err = -ENODEV;
-+ else if (!rtc->ops->set_mmss) {
-+ if (rtc->ops->read_time && rtc->ops->set_time) {
-+ struct rtc_time new, old;
-+
-+ new.tm_sec = secs % 60;
-+ secs /= 60;
-+ new.tm_min = secs % 60;
-+ secs /= 60;
-+ new.tm_hour = secs % 24;
-+
-+ /*
-+ * avoid writing when we're going to change the day
-+ * of the month. We will retry in the next minute.
-+ * This basically means that if the RTC must not drift
-+ * by more than 1 minute in 11 minutes.
-+ */
++ else if (rtc->ops->set_mmss)
++ err = rtc->ops->set_mmss(class_dev->dev, secs);
++ else if (rtc->ops->read_time && rtc->ops->set_time) {
++ struct rtc_time new, old;
++
++ err = rtc->ops->read_time(class_dev->dev, &old);
++ if (err == 0) {
++ rtc_time_to_tm(secs, &new);
++
++ /*
++ * avoid writing when we're going to change the day of
++ * the month. We will retry in the next minute. This
++ * basically means that if the RTC must not drift
++ * by more than 1 minute in 11 minutes.
++ */
+ if (!((old.tm_hour == 23 && old.tm_min == 59) ||
-+ (new.tm_hour == 23 && new.tm_min == 59)))
++ (new.tm_hour == 23 && new.tm_min == 59)))
+ err = rtc->ops->set_time(class_dev->dev, &new);
+ }
-+ else
-+ err = -EINVAL;
+ }
+ else
-+ err = rtc->ops->set_mmss(class_dev->dev, secs);
++ err = -EINVAL;
+
+ mutex_unlock(&rtc->ops_lock);
+
+ return err;
+}
-+EXPORT_SYMBOL(rtc_set_mmss);
++EXPORT_SYMBOL_GPL(rtc_set_mmss);
+
+int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
+{
+ int err;
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
-+ if ((err = mutex_lock_interruptible(&rtc->ops_lock)))
-+ return err;
++ err = mutex_lock_interruptible(&rtc->ops_lock);
++ if (err)
++ return -EBUSY;
+
+ if (rtc->ops == NULL)
+ err = -ENODEV;
@@ -545,15 +1335,16 @@
+ mutex_unlock(&rtc->ops_lock);
+ return err;
+}
-+EXPORT_SYMBOL(rtc_read_alarm);
++EXPORT_SYMBOL_GPL(rtc_read_alarm);
+
+int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
+{
+ int err;
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
-+ if ((err = mutex_lock_interruptible(&rtc->ops_lock)))
-+ return err;
++ err = mutex_lock_interruptible(&rtc->ops_lock);
++ if (err)
++ return -EBUSY;
+
+ if (!rtc->ops)
+ err = -ENODEV;
@@ -565,7 +1356,7 @@
+ mutex_unlock(&rtc->ops_lock);
+ return err;
+}
-+EXPORT_SYMBOL(rtc_set_alarm);
++EXPORT_SYMBOL_GPL(rtc_set_alarm);
+
+void rtc_update_irq(struct class_device *class_dev,
+ unsigned long num, unsigned long events)
@@ -584,7 +1375,7 @@
+ wake_up_interruptible(&rtc->irq_queue);
+ kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
+}
-+EXPORT_SYMBOL(rtc_update_irq);
++EXPORT_SYMBOL_GPL(rtc_update_irq);
+
+struct class_device *rtc_class_open(char *name)
+{
@@ -607,13 +1398,13 @@
+
+ return class_dev;
+}
-+EXPORT_SYMBOL(rtc_class_open);
++EXPORT_SYMBOL_GPL(rtc_class_open);
+
+void rtc_class_close(struct class_device *class_dev)
+{
+ module_put(to_rtc_device(class_dev)->owner);
+}
-+EXPORT_SYMBOL(rtc_class_close);
++EXPORT_SYMBOL_GPL(rtc_class_close);
+
+int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
+{
@@ -632,7 +1423,7 @@
+
+ return retval;
+}
-+EXPORT_SYMBOL(rtc_irq_register);
++EXPORT_SYMBOL_GPL(rtc_irq_register);
+
+void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
+{
@@ -643,7 +1434,7 @@
+ rtc->irq_task = NULL;
+ spin_unlock(&rtc->irq_task_lock);
+}
-+EXPORT_SYMBOL(rtc_irq_unregister);
++EXPORT_SYMBOL_GPL(rtc_irq_unregister);
+
+int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled)
+{
@@ -661,7 +1452,7 @@
+
+ return err;
+}
-+EXPORT_SYMBOL(rtc_irq_set_state);
++EXPORT_SYMBOL_GPL(rtc_irq_set_state);
+
+int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq)
+{
@@ -672,8 +1463,10 @@
+ /* allowed range is 2-8192 */
+ if (freq < 2 || freq > 8192)
+ return -EINVAL;
-+
-+/* if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE)))
++/*
++ FIXME: this does not belong here, will move where appropriate
++ at a later stage. It cannot hurt right now, trust me :)
++ if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE)))
+ return -EACCES;
+*/
+ /* check if freq is a power of 2 */
@@ -689,115 +1482,15 @@
+ spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+
+ if (err == 0) {
-+ if ((err = rtc->ops->irq_set_freq(class_dev->dev, freq)) == 0)
++ err = rtc->ops->irq_set_freq(class_dev->dev, freq);
++ if (err == 0)
+ rtc->irq_freq = freq;
+ }
+ return err;
-+
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/utils.c 2006-02-19 23:33:15.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);
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/hctosys.c 2006-02-21 00:34:57.000000000 +0100
-@@ -0,0 +1,67 @@
++++ linux-ixp4xx/drivers/rtc/hctosys.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,69 @@
+/*
+ * RTC subsystem, initialize system time on startup
+ *
@@ -834,8 +1527,10 @@
+ return -ENODEV;
+ }
+
-+ if ((err = rtc_read_time(class_dev, &tm)) == 0) {
-+ if (rtc_valid_tm(&tm) == 0) {
++ err = rtc_read_time(class_dev, &tm);
++ if (err == 0) {
++ err = rtc_valid_tm(&tm);
++ if (err == 0) {
+ struct timespec tv;
+
+ tv.tv_nsec = NSEC_PER_SEC >> 1;
@@ -865,231 +1560,38 @@
+}
+
+late_initcall(rtc_hctosys);
---- linux-rtc.orig/arch/arm/Kconfig 2006-02-21 00:34:27.000000000 +0100
-+++ linux-rtc/arch/arm/Kconfig 2006-02-21 00:36:42.000000000 +0100
-@@ -817,6 +817,8 @@ source "drivers/usb/Kconfig"
-
- source "drivers/mmc/Kconfig"
-
-+source "drivers/rtc/Kconfig"
-+
- endmenu
-
- source "fs/Kconfig"
---- linux-rtc.orig/arch/arm/common/rtctime.c 2006-02-21 00:34:27.000000000 +0100
-+++ linux-rtc/arch/arm/common/rtctime.c 2006-02-21 00:36:42.000000000 +0100
-@@ -42,89 +42,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.
-@@ -143,13 +60,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;
-
-@@ -160,7 +77,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) {
-@@ -170,7 +87,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)
-@@ -258,7 +175,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));
-@@ -280,11 +197,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));
-@@ -302,7 +219,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:
-@@ -333,11 +250,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));
-@@ -427,7 +344,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"
-@@ -437,7 +354,7 @@ static int rtc_read_proc(char *page, cha
- rtc_epoch);
- }
+--- linux-ixp4xx.orig/CREDITS 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/CREDITS 2006-03-08 01:59:26.000000000 +0100
+@@ -3741,10 +3741,11 @@ D: Mylex DAC960 PCI RAID driver
+ D: Miscellaneous kernel fixes
-- 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-rtc.orig/include/asm-arm/rtc.h 2006-02-21 00:34:27.000000000 +0100
-+++ linux-rtc/include/asm-arm/rtc.h 2006-02-21 00:36:42.000000000 +0100
-@@ -25,9 +25,6 @@ struct rtc_ops {
- int (*proc)(char *buf);
- };
+ N: Alessandro Zummo
+-E: azummo@ita.flashnet.it
+-W: http://freepage.logicom.it/azummo/
++E: a.zummo@towertech.it
+ D: CMI8330 support is sb_card.c
+ D: ISAPnP fixes in sb_card.c
++D: ZyXEL omni.net lcd plus driver
++D: RTC subsystem
+ S: Italy
--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 *);
---- linux-rtc.orig/drivers/char/Kconfig 2006-02-21 00:34:27.000000000 +0100
-+++ linux-rtc/drivers/char/Kconfig 2006-02-21 00:36:42.000000000 +0100
-@@ -695,7 +695,7 @@ config NVRAM
+ N: Marc Zyngier
+--- linux-ixp4xx.orig/MAINTAINERS 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/MAINTAINERS 2006-03-08 01:59:26.000000000 +0100
+@@ -2193,6 +2193,12 @@ M: p_gortmaker@yahoo.com
+ L: linux-kernel@vger.kernel.org
+ S: Maintained
- config RTC
- tristate "Enhanced Real Time Clock Support"
-- depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV
-+ depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM
- ---help---
- If you say Y here and create a character special file /dev/rtc with
- major number 10 and minor number 135 using mknod ("man mknod"), you
---- linux-rtc.orig/drivers/i2c/chips/x1205.c 2006-02-21 00:34:27.000000000 +0100
++REAL TIME CLOCK (RTC) SUBSYSTEM
++P: Alessandro Zummo
++M: a.zummo@towertech.it
++L: linux-kernel@vger.kernel.org
++S: Maintained
++
+ REISERFS FILE SYSTEM
+ P: Hans Reiser
+ M: reiserfs-dev@namesys.com
+--- linux-ixp4xx.orig/drivers/i2c/chips/x1205.c 2006-03-08 01:59:09.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,698 +0,0 @@
-/*
@@ -1790,8 +2292,8 @@
-
-module_init(x1205_init);
-module_exit(x1205_exit);
---- linux-rtc.orig/drivers/i2c/chips/Makefile 2006-02-21 00:34:27.000000000 +0100
-+++ linux-rtc/drivers/i2c/chips/Makefile 2006-02-21 00:36:43.000000000 +0100
+--- linux-ixp4xx.orig/drivers/i2c/chips/Makefile 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/drivers/i2c/chips/Makefile 2006-03-08 01:59:26.000000000 +0100
@@ -10,10 +10,8 @@ obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
@@ -1803,7 +2305,7 @@
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
EXTRA_CFLAGS += -DDEBUG
---- linux-rtc.orig/drivers/i2c/chips/rtc8564.c 2006-02-21 00:34:27.000000000 +0100
+--- linux-ixp4xx.orig/drivers/i2c/chips/rtc8564.c 2006-03-08 01:59:09.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,385 +0,0 @@
-/*
@@ -2191,7 +2693,7 @@
-
-module_init(rtc8564_init);
-module_exit(rtc8564_exit);
---- linux-rtc.orig/drivers/i2c/chips/rtc8564.h 2006-02-21 00:34:27.000000000 +0100
+--- linux-ixp4xx.orig/drivers/i2c/chips/rtc8564.h 2006-03-08 01:59:09.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,78 +0,0 @@
-/*
@@ -2272,7 +2774,7 @@
-#define RTC8564_TD_1_60HZ (0x3)
-
-#define I2C_DRIVERID_RTC8564 0xf000
---- linux-rtc.orig/include/linux/x1205.h 2006-02-21 00:34:27.000000000 +0100
+--- linux-ixp4xx.orig/include/linux/x1205.h 2006-03-08 01:59:09.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-/*
@@ -2306,9 +2808,9 @@
- struct i2c_client_address_data *address_data);
-
-#endif /* __LINUX_X1205_H__ */
---- linux-rtc.orig/drivers/i2c/chips/Kconfig 2006-02-21 00:34:27.000000000 +0100
-+++ linux-rtc/drivers/i2c/chips/Kconfig 2006-02-21 00:36:43.000000000 +0100
-@@ -65,15 +65,6 @@ config SENSORS_PCF8591
+--- linux-ixp4xx.orig/drivers/i2c/chips/Kconfig 2006-03-08 01:59:09.000000000 +0100
+1+++ linux-ixp4xx/drivers/i2c/chips/Kconfig 2006-03-08 01:59:26.000000000 +0100
+@@ -74,15 +74,6 @@ config SENSORS_RTC8564
This driver can also be built as a module. If so, the module
will be called pcf8591.
@@ -2324,7 +2826,7 @@
config ISP1301_OMAP
tristate "Philips ISP1301 with OMAP OTG"
depends on I2C && ARCH_OMAP_OTG
-@@ -126,13 +117,4 @@ config SENSORS_MAX6875
+@@ -144,13 +135,4 @@ config RTC_X1205_I2C
This driver can also be built as a module. If so, the module
will be called max6875.
@@ -2339,8 +2841,8 @@
-
endmenu
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-sysfs.c 2006-02-21 00:36:43.000000000 +0100
-@@ -0,0 +1,120 @@
++++ linux-ixp4xx/drivers/rtc/rtc-sysfs.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,124 @@
+/*
+ * RTC subsystem, sysfs interface
+ *
@@ -2368,7 +2870,8 @@
+ ssize_t retval;
+ struct rtc_time tm;
+
-+ if ((retval = rtc_read_time(dev, &tm)) == 0) {
++ retval = rtc_read_time(dev, &tm);
++ if (retval == 0) {
+ retval = sprintf(buf, "%04d-%02d-%02d\n",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+ }
@@ -2382,7 +2885,8 @@
+ ssize_t retval;
+ struct rtc_time tm;
+
-+ if ((retval = rtc_read_time(dev, &tm)) == 0) {
++ retval = rtc_read_time(dev, &tm);
++ if (retval == 0) {
+ retval = sprintf(buf, "%02d:%02d:%02d\n",
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ }
@@ -2396,7 +2900,8 @@
+ ssize_t retval;
+ struct rtc_time tm;
+
-+ if ((retval = rtc_read_time(dev, &tm)) == 0) {
++ retval = rtc_read_time(dev, &tm);
++ if (retval == 0) {
+ unsigned long time;
+ rtc_tm_to_time(&tm, &time);
+ retval = sprintf(buf, "%lu\n", time);
@@ -2407,25 +2912,26 @@
+static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL);
+
+static struct attribute *rtc_attrs[] = {
-+ &class_device_attr_name.attr,
-+ &class_device_attr_date.attr,
-+ &class_device_attr_time.attr,
-+ &class_device_attr_since_epoch.attr,
-+ NULL,
++ &class_device_attr_name.attr,
++ &class_device_attr_date.attr,
++ &class_device_attr_time.attr,
++ &class_device_attr_since_epoch.attr,
++ NULL,
+};
+
+static struct attribute_group rtc_attr_group = {
-+ .attrs = rtc_attrs,
++ .attrs = rtc_attrs,
+};
+
+static int __devinit rtc_sysfs_add_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
++ struct class_interface *class_intf)
+{
+ int err;
+
+ dev_info(class_dev->dev, "rtc intf: sysfs\n");
+
-+ if ((err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group)) != 0)
++ err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
++ if (err)
+ dev_err(class_dev->dev,
+ "failed to create sysfs attributes\n");
+
@@ -2433,14 +2939,14 @@
+}
+
+static void rtc_sysfs_remove_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
++ struct class_interface *class_intf)
+{
+ sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
+}
+
+/* interface registration */
+
-+struct class_interface rtc_sysfs_interface = {
++static struct class_interface rtc_sysfs_interface = {
+ .add = &rtc_sysfs_add_device,
+ .remove = &rtc_sysfs_remove_device,
+};
@@ -2462,12 +2968,12 @@
+MODULE_DESCRIPTION("RTC class sysfs interface");
+MODULE_LICENSE("GPL");
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-proc.c 2006-02-21 00:36:43.000000000 +0100
-@@ -0,0 +1,158 @@
++++ linux-ixp4xx/drivers/rtc/rtc-proc.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,162 @@
+/*
+ * RTC subsystem, proc interface
+ *
-+ * Copyright (C) 2005 Tower Technologies
++ * Copyright (C) 2005-06 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based on arch/arm/common/rtctime.c
@@ -2487,12 +2993,14 @@
+
+static int rtc_proc_show(struct seq_file *seq, void *offset)
+{
++ int err;
+ 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) {
++ err = rtc_read_time(class_dev, &tm);
++ if (err == 0) {
+ seq_printf(seq,
+ "rtc_time\t: %02d:%02d:%02d\n"
+ "rtc_date\t: %04d-%02d-%02d\n",
@@ -2500,7 +3008,8 @@
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+ }
+
-+ if (rtc_read_alarm(class_dev, &alrm) == 0) {
++ err = rtc_read_alarm(class_dev, &alrm);
++ if (err == 0) {
+ seq_printf(seq, "alrm_time\t: ");
+ if ((unsigned int)alrm.time.tm_hour <= 24)
+ seq_printf(seq, "%02d:", alrm.time.tm_hour);
@@ -2529,9 +3038,9 @@
+ else
+ seq_printf(seq, "**\n");
+ seq_printf(seq, "alrm_wakeup\t: %s\n",
-+ alrm.enabled ? "yes" : "no");
++ alrm.enabled ? "yes" : "no");
+ seq_printf(seq, "alrm_pending\t: %s\n",
-+ alrm.pending ? "yes" : "no");
++ alrm.pending ? "yes" : "no");
+ }
+
+ if (ops->proc)
@@ -2565,7 +3074,7 @@
+};
+
+static int rtc_proc_add_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
++ struct class_interface *class_intf)
+{
+ mutex_lock(&rtc_lock);
+ if (rtc_dev == NULL) {
@@ -2573,7 +3082,8 @@
+
+ rtc_dev = class_dev;
+
-+ if ((ent = create_proc_entry("driver/rtc", 0, NULL))) {
++ ent = create_proc_entry("driver/rtc", 0, NULL);
++ if (ent) {
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
+ ent->proc_fops = &rtc_proc_fops;
@@ -2591,7 +3101,7 @@
+}
+
+static void rtc_proc_remove_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
++ struct class_interface *class_intf)
+{
+ mutex_lock(&rtc_lock);
+ if (rtc_dev == class_dev) {
@@ -2601,7 +3111,7 @@
+ mutex_unlock(&rtc_lock);
+}
+
-+struct class_interface rtc_proc_interface = {
++static struct class_interface rtc_proc_interface = {
+ .add = &rtc_proc_add_device,
+ .remove = &rtc_proc_remove_device,
+};
@@ -2623,8 +3133,8 @@
+MODULE_DESCRIPTION("RTC class proc interface");
+MODULE_LICENSE("GPL");
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-dev.c 2006-02-21 00:36:43.000000000 +0100
-@@ -0,0 +1,370 @@
++++ linux-ixp4xx/drivers/rtc/rtc-dev.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,382 @@
+/*
+ * RTC subsystem, dev interface
+ *
@@ -2641,6 +3151,7 @@
+#include <linux/module.h>
+#include <linux/rtc.h>
+
++static struct class *rtc_dev_class;
+static dev_t rtc_devt;
+
+#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
@@ -2662,7 +3173,6 @@
+
+ err = ops->open ? ops->open(rtc->class_dev.dev) : 0;
+ if (err == 0) {
-+
+ spin_lock_irq(&rtc->irq_lock);
+ rtc->irq_data = 0;
+ spin_unlock_irq(&rtc->irq_lock);
@@ -2738,8 +3248,8 @@
+ return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
+}
+
-+static int rtc_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-+ unsigned long arg)
++static int rtc_dev_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ struct class_device *class_dev = file->private_data;
@@ -2774,15 +3284,16 @@
+
+ switch (cmd) {
+ case RTC_ALM_READ:
-+ if ((err = rtc_read_alarm(class_dev, &alarm)) < 0)
++ err = rtc_read_alarm(class_dev, &alarm);
++ if (err < 0)
+ return err;
+
-+ if ((err = copy_to_user(uarg, &alarm.time, sizeof(tm))))
++ if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
+ return -EFAULT;
+ break;
+
+ case RTC_ALM_SET:
-+ if ((err = copy_from_user(&alarm.time, uarg, sizeof(tm))))
++ if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
+ return -EFAULT;
+
+ alarm.enabled = 0;
@@ -2797,10 +3308,11 @@
+ break;
+
+ case RTC_RD_TIME:
-+ if ((err = rtc_read_time(class_dev, &tm)) < 0)
++ err = rtc_read_time(class_dev, &tm);
++ if (err < 0)
+ return err;
+
-+ if ((err = copy_to_user(uarg, &tm, sizeof(tm))))
++ if (copy_to_user(uarg, &tm, sizeof(tm)))
+ return -EFAULT;
+ break;
+
@@ -2808,7 +3320,7 @@
+ if (!capable(CAP_SYS_TIME))
+ return -EACCES;
+
-+ if ((err = copy_from_user(&tm, uarg, sizeof(tm))))
++ if (copy_from_user(&tm, uarg, sizeof(tm)))
+ return -EFAULT;
+
+ err = rtc_set_time(class_dev, &tm);
@@ -2837,17 +3349,18 @@
+ break;
+#endif
+ case RTC_WKALM_SET:
-+ if ((err = copy_from_user(&alarm, uarg, sizeof(alarm))))
++ if (copy_from_user(&alarm, uarg, sizeof(alarm)))
+ return -EFAULT;
+
+ err = rtc_set_alarm(class_dev, &alarm);
+ break;
+
+ case RTC_WKALM_RD:
-+ if ((err = rtc_read_alarm(class_dev, &alarm)) < 0)
++ err = rtc_read_alarm(class_dev, &alarm);
++ if (err < 0)
+ return err;
+
-+ if ((err = copy_to_user(uarg, &alarm, sizeof(alarm))))
++ if (copy_to_user(uarg, &alarm, sizeof(alarm)))
+ return -EFAULT;
+ break;
+
@@ -2887,17 +3400,12 @@
+ .fasync = rtc_dev_fasync,
+};
+
-+static ssize_t rtc_dev_show_dev(struct class_device *class_dev, char *buf)
-+{
-+ return print_dev_t(buf, class_dev->devt);
-+}
-+static CLASS_DEVICE_ATTR(dev, S_IRUGO, rtc_dev_show_dev, NULL);
-+
+/* insertion/removal hooks */
+
+static int rtc_dev_add_device(struct class_device *class_dev,
+ struct class_interface *class_intf)
+{
++ int err = 0;
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
+ if (rtc->id >= RTC_DEV_MAX) {
@@ -2911,29 +3419,34 @@
+
+ cdev_init(&rtc->char_dev, &rtc_dev_fops);
+ rtc->char_dev.owner = rtc->owner;
-+ class_dev->devt = MKDEV(MAJOR(rtc_devt), rtc->id);
+
-+ if (cdev_add(&rtc->char_dev, class_dev->devt, 1)) {
++ if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) {
+ cdev_del(&rtc->char_dev);
-+
+ dev_err(class_dev->dev,
+ "failed to add char device %d:%d\n",
-+ MAJOR(class_dev->devt),
-+ MINOR(class_dev->devt));
-+
-+ class_dev->devt = MKDEV(0, 0);
++ MAJOR(rtc_devt), rtc->id);
+ return -ENODEV;
+ }
+
-+ class_device_create_file(class_dev, &class_device_attr_dev);
++ rtc->rtc_dev = class_device_create(rtc_dev_class, NULL,
++ MKDEV(MAJOR(rtc_devt), rtc->id),
++ class_dev->dev, "rtc%d", rtc->id);
++ if (IS_ERR(rtc->rtc_dev)) {
++ dev_err(class_dev->dev, "cannot create rtc_dev device\n");
++ err = PTR_ERR(rtc->rtc_dev);
++ goto err_cdev_del;
++ }
+
+ dev_info(class_dev->dev, "rtc intf: dev (%d:%d)\n",
-+ MAJOR(class_dev->devt),
-+ MINOR(class_dev->devt));
-+
-+ kobject_uevent(&class_dev->kobj, KOBJ_ADD);
++ MAJOR(rtc->rtc_dev->devt),
++ MINOR(rtc->rtc_dev->devt));
+
+ return 0;
++
++err_cdev_del:
++
++ cdev_del(&rtc->char_dev);
++ return err;
+}
+
+static void rtc_dev_remove_device(struct class_device *class_dev,
@@ -2941,23 +3454,19 @@
+{
+ struct rtc_device *rtc = to_rtc_device(class_dev);
+
-+ class_device_remove_file(class_dev, &class_device_attr_dev);
-+
-+ if (MAJOR(class_dev->devt)) {
++ if (rtc->rtc_dev) {
+ dev_dbg(class_dev->dev, "removing char %d:%d\n",
-+ MAJOR(class_dev->devt),
-+ MINOR(class_dev->devt));
-+ cdev_del(&rtc->char_dev);
-+
-+ kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
++ MAJOR(rtc->rtc_dev->devt),
++ MINOR(rtc->rtc_dev->devt));
+
-+ class_dev->devt = MKDEV(0, 0);
++ class_device_unregister(rtc->rtc_dev);
++ cdev_del(&rtc->char_dev);
+ }
+}
+
+/* interface registration */
+
-+struct class_interface rtc_dev_interface = {
++static struct class_interface rtc_dev_interface = {
+ .add = &rtc_dev_add_device,
+ .remove = &rtc_dev_remove_device,
+};
@@ -2966,26 +3475,39 @@
+{
+ int err;
+
-+ if ((err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc")) < 0) {
++ rtc_dev_class = class_create(THIS_MODULE, "rtc-dev");
++ if (IS_ERR(rtc_dev_class))
++ return PTR_ERR(rtc_dev_class);
++
++ err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");
++ if (err < 0) {
+ printk(KERN_ERR "%s: failed to allocate char dev region\n",
+ __FILE__);
-+ return err;
++ goto err_destroy_class;
+ }
+
-+ if ((err = rtc_interface_register(&rtc_dev_interface)) < 0) {
++ err = rtc_interface_register(&rtc_dev_interface);
++ if (err < 0) {
+ printk(KERN_ERR "%s: failed to register the interface\n",
+ __FILE__);
-+ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
-+ return err;
++ goto err_unregister_chrdev;
+ }
+
+ return 0;
++
++err_unregister_chrdev:
++ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
++
++err_destroy_class:
++ class_destroy(rtc_dev_class);
++
++ return err;
+}
+
+static void __exit rtc_dev_exit(void)
+{
+ class_interface_unregister(&rtc_dev_interface);
-+
++ class_destroy(rtc_dev_class);
+ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
+}
+
@@ -2996,7 +3518,7 @@
+MODULE_DESCRIPTION("RTC class dev interface");
+MODULE_LICENSE("GPL");
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-x1205.c 2006-02-21 00:36:43.000000000 +0100
++++ linux-ixp4xx/drivers/rtc/rtc-x1205.c 2006-03-08 01:59:26.000000000 +0100
@@ -0,0 +1,619 @@
+/*
+ * An i2c driver for the Xicor/Intersil X1205 RTC
@@ -3374,7 +3896,7 @@
+ if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
+ dev_err(&client->adapter->dev,
+ "%s: could not read register %x\n",
-+ __FUNCTION__, probe_zero_pattern[i]);
++ __FUNCTION__, probe_zero_pattern[i]);
+
+ return -EIO;
+ }
@@ -3618,8 +4140,8 @@
+module_init(x1205_init);
+module_exit(x1205_exit);
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-test.c 2006-02-21 00:36:43.000000000 +0100
-@@ -0,0 +1,206 @@
++++ linux-ixp4xx/drivers/rtc/rtc-test.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,205 @@
+/*
+ * An RTC test device/driver
+ * Copyright (C) 2005 Tower Technologies
@@ -3636,8 +4158,7 @@
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
-+struct platform_device *test0 = NULL, *test1 = NULL;
-+
++static struct platform_device *test0 = NULL, *test1 = NULL;
+
+static int test_rtc_read_alarm(struct device *dev,
+ struct rtc_wkalrm *alrm)
@@ -3827,7 +4348,7 @@
+module_init(test_init);
+module_exit(test_exit);
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-ds1672.c 2006-02-21 00:36:43.000000000 +0100
++++ linux-ixp4xx/drivers/rtc/rtc-ds1672.c 2006-03-08 01:59:26.000000000 +0100
@@ -0,0 +1,233 @@
+/*
+ * An rtc/i2c driver for the Dallas DS1672
@@ -3877,11 +4398,11 @@
+ { client->addr, I2C_M_RD, 4, buf }, /* read date */
+ };
+
-+ /* read date registers */
-+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
-+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-+ return -EIO;
-+ }
++ /* read date registers */
++ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
++ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
++ return -EIO;
++ }
+
+ dev_dbg(&client->dev,
+ "%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
@@ -4063,7 +4584,7 @@
+module_init(ds1672_init);
+module_exit(ds1672_exit);
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-pcf8563.c 2006-02-21 00:36:43.000000000 +0100
++++ linux-ixp4xx/drivers/rtc/rtc-pcf8563.c 2006-03-08 01:59:26.000000000 +0100
@@ -0,0 +1,355 @@
+/*
+ * An I2C driver for the Philips PCF8563 RTC
@@ -4421,7 +4942,7 @@
+module_init(pcf8563_init);
+module_exit(pcf8563_exit);
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-rtc/drivers/rtc/rtc-rs5c372.c 2006-02-21 00:36:43.000000000 +0100
++++ linux-ixp4xx/drivers/rtc/rtc-rs5c372.c 2006-03-08 01:59:26.000000000 +0100
@@ -0,0 +1,295 @@
+/*
+ * An I2C driver for the Ricoh RS5C372 RTC
@@ -4718,3 +5239,608 @@
+MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-ixp4xx/drivers/rtc/rtc-ep93xx.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,163 @@
++/*
++ * A driver for the RTC embedded in the Cirrus Logic EP93XX processors
++ * Copyright (c) 2006 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; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/module.h>
++#include <linux/rtc.h>
++#include <linux/platform_device.h>
++#include <asm/hardware.h>
++
++#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x))
++#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000)
++#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C)
++#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108)
++
++#define DRV_VERSION "0.2"
++
++static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload,
++ unsigned short *delete)
++{
++ unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP);
++
++ if (preload)
++ *preload = comp & 0xffff;
++
++ if (delete)
++ *delete = (comp >> 16) & 0x1f;
++
++ return 0;
++}
++
++static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
++{
++ unsigned long time = __raw_readl(EP93XX_RTC_DATA);
++
++ rtc_time_to_tm(time, tm);
++ return 0;
++}
++
++static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs)
++{
++ __raw_writel(secs + 1, EP93XX_RTC_LOAD);
++ return 0;
++}
++
++static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm)
++{
++ int err;
++ unsigned long secs;
++
++ err = rtc_tm_to_time(tm, &secs);
++ if (err != 0)
++ return err;
++
++ return ep93xx_rtc_set_mmss(dev, secs);
++}
++
++static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)
++{
++ unsigned short preload, delete;
++
++ ep93xx_get_swcomp(dev, &preload, &delete);
++
++ seq_printf(seq, "24hr\t\t: yes\n");
++ seq_printf(seq, "preload\t\t: %d\n", preload);
++ seq_printf(seq, "delete\t\t: %d\n", delete);
++
++ return 0;
++}
++
++static struct rtc_class_ops ep93xx_rtc_ops = {
++ .read_time = ep93xx_rtc_read_time,
++ .set_time = ep93xx_rtc_set_time,
++ .set_mmss = ep93xx_rtc_set_mmss,
++ .proc = ep93xx_rtc_proc,
++};
++
++static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ unsigned short preload;
++
++ ep93xx_get_swcomp(dev, &preload, NULL);
++
++ return sprintf(buf, "%d\n", preload);
++}
++static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL);
++
++static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ unsigned short delete;
++
++ ep93xx_get_swcomp(dev, NULL, &delete);
++
++ return sprintf(buf, "%d\n", delete);
++}
++static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL);
++
++
++static int __devinit ep93xx_rtc_probe(struct platform_device *dev)
++{
++ struct rtc_device *rtc = rtc_device_register("ep93xx",
++ &dev->dev, &ep93xx_rtc_ops, THIS_MODULE);
++
++ if (IS_ERR(rtc)) {
++ dev_err(&dev->dev, "unable to register\n");
++ return PTR_ERR(rtc);
++ }
++
++ platform_set_drvdata(dev, rtc);
++
++ device_create_file(&dev->dev, &dev_attr_comp_preload);
++ device_create_file(&dev->dev, &dev_attr_comp_delete);
++
++ return 0;
++}
++
++static int __devexit ep93xx_rtc_remove(struct platform_device *dev)
++{
++ struct rtc_device *rtc = platform_get_drvdata(dev);
++
++ if (rtc)
++ rtc_device_unregister(rtc);
++
++ platform_set_drvdata(dev, NULL);
++
++ return 0;
++}
++
++static struct platform_driver ep93xx_rtc_platform_driver = {
++ .driver = {
++ .name = "ep93xx-rtc",
++ .owner = THIS_MODULE,
++ },
++ .probe = ep93xx_rtc_probe,
++ .remove = __devexit_p(ep93xx_rtc_remove),
++};
++
++static int __init ep93xx_rtc_init(void)
++{
++ return platform_driver_register(&ep93xx_rtc_platform_driver);
++}
++
++static void __exit ep93xx_rtc_exit(void)
++{
++ platform_driver_unregister(&ep93xx_rtc_platform_driver);
++}
++
++MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
++MODULE_DESCRIPTION("EP93XX RTC driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++module_init(ep93xx_rtc_init);
++module_exit(ep93xx_rtc_exit);
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-ixp4xx/drivers/rtc/rtc-sa1100.c 2006-03-08 01:59:26.000000000 +0100
+@@ -0,0 +1,392 @@
++/*
++ * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx
++ *
++ * Copyright (c) 2000 Nils Faerber
++ *
++ * Based on rtc.c by Paul Gortmaker
++ *
++ * Original Driver by Nils Faerber <nils@kernelconcepts.de>
++ *
++ * Modifications from:
++ * CIH <cih@coventive.com>
++ * Nicolas Pitre <nico@cam.org>
++ * Andrew Christian <andrew.christian@hp.com>
++ *
++ * Converted to the RTC subsystem and Driver Model
++ * by Richard Purdie <rpurdie@rpsys.net>
++ *
++ * 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; either version
++ * 2 of the License, or (at your option) any later version. *
++ * 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; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/rtc.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/interrupt.h>
++#include <linux/string.h>
++#include <linux/pm.h>
++
++#include <asm/bitops.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/rtc.h>
++
++#ifdef CONFIG_ARCH_PXA
++#include <asm/arch/pxa-regs.h>
++#endif
++
++#define TIMER_FREQ CLOCK_TICK_RATE
++#define RTC_DEF_DIVIDER 32768 - 1
++#define RTC_DEF_TRIM 0
++
++static unsigned long rtc_freq = 1024;
++static struct rtc_time rtc_alarm;
++static spinlock_t sa1100_rtc_lock = SPIN_LOCK_UNLOCKED;
++
++static int rtc_update_alarm(struct rtc_time *alrm)
++{
++ struct rtc_time alarm_tm, now_tm;
++ unsigned long now, time;
++ int ret;
++
++ do {
++ now = RCNR;
++ rtc_time_to_tm(now, &now_tm);
++ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
++ ret = rtc_tm_to_time(&alarm_tm, &time);
++ if (ret != 0)
++ break;
++
++ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
++ RTAR = time;
++ } while (now != RCNR);
++
++ return ret;
++}
++
++static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id,
++ struct pt_regs *regs)
++{
++ struct platform_device *pdev = to_platform_device(dev_id);
++ struct rtc_device *rtc = platform_get_drvdata(pdev);
++ unsigned int rtsr;
++ unsigned long events = 0;
++
++ spin_lock(&sa1100_rtc_lock);
++
++ rtsr = RTSR;
++ /* clear interrupt sources */
++ RTSR = 0;
++ RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
++
++ /* clear alarm interrupt if it has occurred */
++ if (rtsr & RTSR_AL)
++ rtsr &= ~RTSR_ALE;
++ RTSR = rtsr & (RTSR_ALE | RTSR_HZE);
++
++ /* update irq data & counter */
++ if (rtsr & RTSR_AL)
++ events |= RTC_AF | RTC_IRQF;
++ if (rtsr & RTSR_HZ)
++ events |= RTC_UF | RTC_IRQF;
++
++ rtc_update_irq(&rtc->class_dev, 1, events);
++
++ if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
++ rtc_update_alarm(&rtc_alarm);
++
++ spin_unlock(&sa1100_rtc_lock);
++
++ return IRQ_HANDLED;
++}
++
++static int rtc_timer1_count;
++
++static irqreturn_t timer1_interrupt(int irq, void *dev_id,
++ struct pt_regs *regs)
++{
++ struct platform_device *pdev = to_platform_device(dev_id);
++ struct rtc_device *rtc = platform_get_drvdata(pdev);
++
++ /*
++ * If we match for the first time, rtc_timer1_count will be 1.
++ * Otherwise, we wrapped around (very unlikely but
++ * still possible) so compute the amount of missed periods.
++ * The match reg is updated only when the data is actually retrieved
++ * to avoid unnecessary interrupts.
++ */
++ OSSR = OSSR_M1; /* clear match on timer1 */
++
++ rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF);
++
++ if (rtc_timer1_count == 1)
++ rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));
++
++ return IRQ_HANDLED;
++}
++
++static int sa1100_rtc_read_callback(struct device *dev, int data)
++{
++ if (data & RTC_PF) {
++ /* interpolate missed periods and set match for the next */
++ unsigned long period = TIMER_FREQ/rtc_freq;
++ unsigned long oscr = OSCR;
++ unsigned long osmr1 = OSMR1;
++ unsigned long missed = (oscr - osmr1)/period;
++ data += missed << 8;
++ OSSR = OSSR_M1; /* clear match on timer 1 */
++ OSMR1 = osmr1 + (missed + 1)*period;
++ /* Ensure we didn't miss another match in the mean time.
++ * Here we compare (match - OSCR) 8 instead of 0 --
++ * see comment in pxa_timer_interrupt() for explanation.
++ */
++ while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) {
++ data += 0x100;
++ OSSR = OSSR_M1; /* clear match on timer 1 */
++ OSMR1 = osmr1 + period;
++ }
++ }
++ return data;
++}
++
++static int sa1100_rtc_open(struct device *dev)
++{
++ int ret;
++
++ ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT,
++ "rtc 1Hz", dev);
++ if (ret) {
++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
++ goto fail_ui;
++ }
++ ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT,
++ "rtc Alrm", dev);
++ if (ret) {
++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
++ goto fail_ai;
++ }
++ ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT,
++ "rtc timer", dev);
++ if (ret) {
++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1);
++ goto fail_pi;
++ }
++ return 0;
++
++ fail_pi:
++ free_irq(IRQ_RTCAlrm, NULL);
++ fail_ai:
++ free_irq(IRQ_RTC1Hz, NULL);
++ fail_ui:
++ return ret;
++}
++
++static void sa1100_rtc_release(struct device *dev)
++{
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR = 0;
++ OIER &= ~OIER_E1;
++ OSSR = OSSR_M1;
++ spin_unlock_irq(&sa1100_rtc_lock);
++
++ free_irq(IRQ_OST1, dev);
++ free_irq(IRQ_RTCAlrm, dev);
++ free_irq(IRQ_RTC1Hz, dev);
++}
++
++
++static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
++ unsigned long arg)
++{
++ switch(cmd) {
++ case RTC_AIE_OFF:
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR &= ~RTSR_ALE;
++ spin_unlock_irq(&sa1100_rtc_lock);
++ return 0;
++ case RTC_AIE_ON:
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR |= RTSR_ALE;
++ spin_unlock_irq(&sa1100_rtc_lock);
++ return 0;
++ case RTC_UIE_OFF:
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR &= ~RTSR_HZE;
++ spin_unlock_irq(&sa1100_rtc_lock);
++ return 0;
++ case RTC_UIE_ON:
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR |= RTSR_HZE;
++ spin_unlock_irq(&sa1100_rtc_lock);
++ return 0;
++ case RTC_PIE_OFF:
++ spin_lock_irq(&sa1100_rtc_lock);
++ OIER &= ~OIER_E1;
++ spin_unlock_irq(&sa1100_rtc_lock);
++ return 0;
++ case RTC_PIE_ON:
++ if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
++ return -EACCES;
++ spin_lock_irq(&sa1100_rtc_lock);
++ OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
++ OIER |= OIER_E1;
++ rtc_timer1_count = 1;
++ spin_unlock_irq(&sa1100_rtc_lock);
++ return 0;
++ case RTC_IRQP_READ:
++ return put_user(rtc_freq, (unsigned long *)arg);
++ case RTC_IRQP_SET:
++ if (arg < 1 || arg > TIMER_FREQ)
++ return -EINVAL;
++ if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
++ return -EACCES;
++ rtc_freq = arg;
++ return 0;
++ }
++ return -EINVAL;
++}
++
++static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
++{
++ rtc_time_to_tm(RCNR, tm);
++ return 0;
++}
++
++static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm)
++{
++ unsigned long time;
++ int ret;
++
++ ret = rtc_tm_to_time(tm, &time);
++ if (ret == 0)
++ RCNR = time;
++ return ret;
++}
++
++static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
++ alrm->pending = RTSR & RTSR_AL ? 1 : 0;
++ return 0;
++}
++
++static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++ int ret;
++
++ spin_lock_irq(&sa1100_rtc_lock);
++ ret = rtc_update_alarm(&alrm->time);
++ if (ret == 0) {
++ memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time));
++
++ if (alrm->enabled)
++ enable_irq_wake(IRQ_RTCAlrm);
++ else
++ disable_irq_wake(IRQ_RTCAlrm);
++ }
++ spin_unlock_irq(&sa1100_rtc_lock);
++
++ return ret;
++}
++
++static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
++{
++ seq_printf(seq, "trim/divider\t: 0x%08x\n", RTTR);
++ seq_printf(seq, "alarm_IRQ\t: %s\n",
++ (RTSR & RTSR_ALE) ? "yes" : "no" );
++ seq_printf(seq, "update_IRQ\t: %s\n",
++ (RTSR & RTSR_HZE) ? "yes" : "no");
++ seq_printf(seq, "periodic_IRQ\t: %s\n",
++ (OIER & OIER_E1) ? "yes" : "no");
++ seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq);
++
++ return 0;
++}
++
++static struct rtc_class_ops sa1100_rtc_ops = {
++ .open = sa1100_rtc_open,
++ .read_callback = sa1100_rtc_read_callback,
++ .release = sa1100_rtc_release,
++ .ioctl = sa1100_rtc_ioctl,
++ .read_time = sa1100_rtc_read_time,
++ .set_time = sa1100_rtc_set_time,
++ .read_alarm = sa1100_rtc_read_alarm,
++ .set_alarm = sa1100_rtc_set_alarm,
++ .proc = sa1100_rtc_proc,
++};
++
++static int sa1100_rtc_probe(struct platform_device *pdev)
++{
++ struct rtc_device *rtc;
++
++ /*
++ * According to the manual we should be able to let RTTR be zero
++ * and then a default diviser for a 32.768KHz clock is used.
++ * Apparently this doesn't work, at least for my SA1110 rev 5.
++ * If the clock divider is uninitialized then reset it to the
++ * default value to get the 1Hz clock.
++ */
++ if (RTTR == 0) {
++ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
++ printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
++ /* The current RTC value probably doesn't make sense either */
++ RCNR = 0;
++ }
++
++ rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
++ THIS_MODULE);
++
++ if (IS_ERR(rtc)) {
++ dev_err(&pdev->dev, "Unable to register the RTC device\n");
++ return PTR_ERR(rtc);
++ }
++
++ platform_set_drvdata(pdev, rtc);
++
++ dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n");
++
++ return 0;
++}
++
++static int sa1100_rtc_remove(struct platform_device *pdev)
++{
++ struct rtc_device *rtc = platform_get_drvdata(pdev);
++
++ if (rtc)
++ rtc_device_unregister(rtc);
++
++ return 0;
++}
++
++static struct platform_driver sa1100_rtc_driver = {
++ .probe = sa1100_rtc_probe,
++ .remove = sa1100_rtc_remove,
++ .driver = {
++ .name = "sa1100-rtc",
++ },
++};
++
++static int __init sa1100_rtc_init(void)
++{
++ return platform_driver_register(&sa1100_rtc_driver);
++}
++
++static void __exit sa1100_rtc_exit(void)
++{
++ platform_driver_unregister(&sa1100_rtc_driver);
++}
++
++module_init(sa1100_rtc_init);
++module_exit(sa1100_rtc_exit);
++
++MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
++MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
++MODULE_LICENSE("GPL");
+--- linux-ixp4xx.orig/arch/arm/mach-pxa/generic.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/arm/mach-pxa/generic.c 2006-03-08 01:59:26.000000000 +0100
+@@ -319,6 +319,11 @@ void __init pxa_set_ficp_info(struct pxa
+ pxaficp_device.dev.platform_data = info;
+ }
+
++static struct platform_device pxartc_device = {
++ .name = "sa1100-rtc",
++ .id = -1,
++};
++
+ static struct platform_device *devices[] __initdata = {
+ &pxamci_device,
+ &udc_device,
+@@ -329,6 +334,7 @@ static struct platform_device *devices[]
+ &pxaficp_device,
+ &i2c_device,
+ &i2s_device,
++ &pxartc_device,
+ };
+
+ static int __init pxa_init(void)
+--- linux-ixp4xx.orig/arch/arm/mach-sa1100/generic.c 2006-03-08 01:59:09.000000000 +0100
++++ linux-ixp4xx/arch/arm/mach-sa1100/generic.c 2006-03-08 01:59:26.000000000 +0100
+@@ -324,6 +324,11 @@ void sa11x0_set_irda_data(struct irda_pl
+ sa11x0ir_device.dev.platform_data = irda;
+ }
+
++static struct platform_device sa11x0rtc_device = {
++ .name = "sa1100-rtc",
++ .id = -1,
++};
++
+ static struct platform_device *sa11x0_devices[] __initdata = {
+ &sa11x0udc_device,
+ &sa11x0uart1_device,
+@@ -333,6 +338,7 @@ static struct platform_device *sa11x0_de
+ &sa11x0pcmcia_device,
+ &sa11x0fb_device,
+ &sa11x0mtd_device,
++ &sa11x0rtc_device,
+ };
+
+ static int __init sa1100_init(void)