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>2007-06-30 13:19:16 +0000
committerRod Whitby <rod@whitby.id.au>2007-06-30 13:19:16 +0000
commit9dfa73e4fc85c0c33f921974d011ede59aba0276 (patch)
treec81ac5404ed31f408a9b9a84eea77c5c95fc8112 /packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
parent331675b53d9fe807c30c9adb703f711b61d923b5 (diff)
ixp4xx-kernel: Removed obsolete kernel versions
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.patch5846
1 files changed, 0 insertions, 5846 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
deleted file mode 100644
index 044bd3abc1..0000000000
--- a/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch
+++ /dev/null
@@ -1,5846 +0,0 @@
----
- 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 */
-
-+/* 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__
-
-+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 *);
-+ 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);
-+ int (*read_callback)(struct device *, int data);
-+};
-+
-+#define RTC_DEVICE_NAME_SIZE 20
-+struct rtc_task;
-+
-+struct rtc_device
-+{
-+ struct class_device class_dev;
-+ struct module *owner;
-+
-+ int id;
-+ char name[RTC_DEVICE_NAME_SIZE];
-+
-+ struct rtc_class_ops *ops;
-+ struct mutex ops_lock;
-+
-+ struct class_device *rtc_dev;
-+ struct cdev char_dev;
-+ struct mutex char_lock;
-+
-+ unsigned long irq_data;
-+ spinlock_t irq_lock;
-+ wait_queue_head_t irq_queue;
-+ struct fasync_struct *async_queue;
-+
-+ struct rtc_task *irq_task;
-+ spinlock_t irq_task_lock;
-+ int irq_freq;
-+};
-+#define to_rtc_device(d) container_of(d, struct rtc_device, class_dev)
-+
-+extern struct rtc_device *rtc_device_register(const 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_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);
-+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);
-+
-+extern struct class_device *rtc_class_open(char *name);
-+extern void rtc_class_close(struct class_device *class_dev);
-+
-+extern int rtc_irq_register(struct class_device *class_dev,
-+ struct rtc_task *task);
-+extern void rtc_irq_unregister(struct class_device *class_dev,
-+ struct rtc_task *task);
-+extern int rtc_irq_set_state(struct class_device *class_dev,
-+ struct rtc_task *task, int enabled);
-+extern int rtc_irq_set_freq(struct class_device *class_dev,
-+ struct rtc_task *task, int freq);
-+
- typedef struct rtc_task {
- void (*func)(void *private_data);
- void *private_data;
---- 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>
-
- #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
-
- 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-ixp4xx/drivers/rtc/class.c 2006-03-08 01:59:26.000000000 +0100
-@@ -0,0 +1,145 @@
-+/*
-+ * 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 DEFINE_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);
-+ mutex_lock(&idr_lock);
-+ idr_remove(&rtc_idr, rtc->id);
-+ mutex_unlock(&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(const 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;
-+ }
-+
-+
-+ mutex_lock(&idr_lock);
-+ err = idr_get_new(&rtc_idr, NULL, &id);
-+ mutex_unlock(&idr_lock);
-+
-+ if (err < 0)
-+ goto exit;
-+
-+ id = id & MAX_ID_MASK;
-+
-+ rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
-+ if (rtc == 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;
-+
-+ mutex_init(&rtc->ops_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);
-+
-+ err = class_device_register(&rtc->class_dev);
-+ if (err)
-+ 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)
-+{
-+ mutex_lock(&rtc->ops_lock);
-+ rtc->ops = NULL;
-+ mutex_unlock(&rtc->ops_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-ixp4xx/drivers/rtc/interface.c 2006-03-08 01:59:26.000000000 +0100
-@@ -0,0 +1,277 @@
-+/*
-+ * 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>
-+
-+int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
-+{
-+ int err;
-+ struct rtc_device *rtc = to_rtc_device(class_dev);
-+
-+ err = mutex_lock_interruptible(&rtc->ops_lock);
-+ if (err)
-+ return -EBUSY;
-+
-+ if (!rtc->ops)
-+ err = -ENODEV;
-+ else if (!rtc->ops->read_time)
-+ err = -EINVAL;
-+ else {
-+ memset(tm, 0, sizeof(struct rtc_time));
-+ err = rtc->ops->read_time(class_dev->dev, tm);
-+ }
-+
-+ mutex_unlock(&rtc->ops_lock);
-+ return err;
-+}
-+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);
-+
-+ err = rtc_valid_tm(tm);
-+ if (err != 0)
-+ return err;
-+
-+ err = mutex_lock_interruptible(&rtc->ops_lock);
-+ if (err)
-+ return -EBUSY;
-+
-+ if (!rtc->ops)
-+ err = -ENODEV;
-+ else if (!rtc->ops->set_time)
-+ err = -EINVAL;
-+ else
-+ err = rtc->ops->set_time(class_dev->dev, tm);
-+
-+ mutex_unlock(&rtc->ops_lock);
-+ return err;
-+}
-+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);
-+
-+ err = mutex_lock_interruptible(&rtc->ops_lock);
-+ if (err)
-+ return -EBUSY;
-+
-+ if (!rtc->ops)
-+ err = -ENODEV;
-+ 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)))
-+ err = rtc->ops->set_time(class_dev->dev, &new);
-+ }
-+ }
-+ else
-+ err = -EINVAL;
-+
-+ mutex_unlock(&rtc->ops_lock);
-+
-+ return err;
-+}
-+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);
-+
-+ err = mutex_lock_interruptible(&rtc->ops_lock);
-+ if (err)
-+ return -EBUSY;
-+
-+ if (rtc->ops == NULL)
-+ err = -ENODEV;
-+ else if (!rtc->ops->read_alarm)
-+ err = -EINVAL;
-+ else {
-+ memset(alarm, 0, sizeof(struct rtc_wkalrm));
-+ err = rtc->ops->read_alarm(class_dev->dev, alarm);
-+ }
-+
-+ mutex_unlock(&rtc->ops_lock);
-+ return err;
-+}
-+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);
-+
-+ err = mutex_lock_interruptible(&rtc->ops_lock);
-+ if (err)
-+ return -EBUSY;
-+
-+ if (!rtc->ops)
-+ err = -ENODEV;
-+ else if (!rtc->ops->set_alarm)
-+ err = -EINVAL;
-+ else
-+ err = rtc->ops->set_alarm(class_dev->dev, alarm);
-+
-+ mutex_unlock(&rtc->ops_lock);
-+ return err;
-+}
-+EXPORT_SYMBOL_GPL(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_GPL(rtc_update_irq);
-+
-+struct class_device *rtc_class_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;
-+ }
-+ }
-+
-+ if (class_dev) {
-+ if (!try_module_get(to_rtc_device(class_dev)->owner))
-+ class_dev = NULL;
-+ }
-+ up(&rtc_class->sem);
-+
-+ return class_dev;
-+}
-+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_GPL(rtc_class_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_GPL(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_GPL(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_GPL(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;
-+/*
-+ 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 */
-+ 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) {
-+ 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-ixp4xx/drivers/rtc/hctosys.c 2006-03-08 01:59:26.000000000 +0100
-@@ -0,0 +1,69 @@
-+/*
-+ * RTC subsystem, initialize system time on startup
-+ *
-+ * 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/rtc.h>
-+
-+/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
-+ * whether it stores the most close value or the value with partial
-+ * seconds truncated. However, it is important that we use it to store
-+ * the truncated value. This is because otherwise it is necessary,
-+ * in an rtc sync function, to read both xtime.tv_sec and
-+ * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
-+ * of >32bits is not possible. So storing the most close value would
-+ * slow down the sync API. So here we have the truncated value and
-+ * the best guess is to add 0.5s.
-+ */
-+
-+static int __init rtc_hctosys(void)
-+{
-+ int err;
-+ struct rtc_time tm;
-+ struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-+
-+ if (class_dev == NULL) {
-+ printk("%s: unable to open rtc device (%s)\n",
-+ __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
-+ return -ENODEV;
-+ }
-+
-+ 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;
-+
-+ rtc_tm_to_time(&tm, &tv.tv_sec);
-+
-+ do_settimeofday(&tv);
-+
-+ dev_info(class_dev->dev,
-+ "setting the system clock to "
-+ "%d-%02d-%02d %02d:%02d:%02d (%u)\n",
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ (unsigned int) tv.tv_sec);
-+ }
-+ else
-+ dev_err(class_dev->dev,
-+ "hctosys: invalid date/time\n");
-+ }
-+ else
-+ dev_err(class_dev->dev,
-+ "hctosys: unable to read the hardware clock\n");
-+
-+ rtc_class_close(class_dev);
-+
-+ return 0;
-+}
-+
-+late_initcall(rtc_hctosys);
---- 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
-
- 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
-
- 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
-
-+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 @@
--/*
-- * x1205.c - An i2c driver for the Xicor X1205 RTC
-- * Copyright 2004 Karen Spearel
-- * Copyright 2005 Alessandro Zummo
-- *
-- * please send all reports to:
-- * kas11 at tampabay dot rr dot com
-- * a dot zummo at towertech dot it
-- *
-- * based on the other drivers in this same directory.
-- *
-- * 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/init.h>
--#include <linux/slab.h>
--#include <linux/i2c.h>
--#include <linux/string.h>
--#include <linux/bcd.h>
--#include <linux/rtc.h>
--#include <linux/list.h>
--
--#include <linux/x1205.h>
--
--#define DRV_VERSION "0.9.9"
--
--/* Addresses to scan: none. This chip is located at
-- * 0x6f and uses a two bytes register addressing.
-- * Two bytes need to be written to read a single register,
-- * while most other chips just require one and take the second
-- * one as the data to be written. To prevent corrupting
-- * unknown chips, the user must explicitely set the probe parameter.
-- */
--
--static unsigned short normal_i2c[] = { I2C_CLIENT_END };
--
--/* Insmod parameters */
--I2C_CLIENT_INSMOD;
--I2C_CLIENT_MODULE_PARM(hctosys,
-- "Set the system time from the hardware clock upon initialization");
--
--/* offsets into CCR area */
--
--#define CCR_SEC 0
--#define CCR_MIN 1
--#define CCR_HOUR 2
--#define CCR_MDAY 3
--#define CCR_MONTH 4
--#define CCR_YEAR 5
--#define CCR_WDAY 6
--#define CCR_Y2K 7
--
--#define X1205_REG_SR 0x3F /* status register */
--#define X1205_REG_Y2K 0x37
--#define X1205_REG_DW 0x36
--#define X1205_REG_YR 0x35
--#define X1205_REG_MO 0x34
--#define X1205_REG_DT 0x33
--#define X1205_REG_HR 0x32
--#define X1205_REG_MN 0x31
--#define X1205_REG_SC 0x30
--#define X1205_REG_DTR 0x13
--#define X1205_REG_ATR 0x12
--#define X1205_REG_INT 0x11
--#define X1205_REG_0 0x10
--#define X1205_REG_Y2K1 0x0F
--#define X1205_REG_DWA1 0x0E
--#define X1205_REG_YRA1 0x0D
--#define X1205_REG_MOA1 0x0C
--#define X1205_REG_DTA1 0x0B
--#define X1205_REG_HRA1 0x0A
--#define X1205_REG_MNA1 0x09
--#define X1205_REG_SCA1 0x08
--#define X1205_REG_Y2K0 0x07
--#define X1205_REG_DWA0 0x06
--#define X1205_REG_YRA0 0x05
--#define X1205_REG_MOA0 0x04
--#define X1205_REG_DTA0 0x03
--#define X1205_REG_HRA0 0x02
--#define X1205_REG_MNA0 0x01
--#define X1205_REG_SCA0 0x00
--
--#define X1205_CCR_BASE 0x30 /* Base address of CCR */
--#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */
--
--#define X1205_SR_RTCF 0x01 /* Clock failure */
--#define X1205_SR_WEL 0x02 /* Write Enable Latch */
--#define X1205_SR_RWEL 0x04 /* Register Write Enable */
--
--#define X1205_DTR_DTR0 0x01
--#define X1205_DTR_DTR1 0x02
--#define X1205_DTR_DTR2 0x04
--
--#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */
--
--/* Prototypes */
--static int x1205_attach(struct i2c_adapter *adapter);
--static int x1205_detach(struct i2c_client *client);
--static int x1205_probe(struct i2c_adapter *adapter, int address, int kind);
--static int x1205_command(struct i2c_client *client, unsigned int cmd,
-- void *arg);
--
--static struct i2c_driver x1205_driver = {
-- .driver = {
-- .name = "x1205",
-- },
-- .attach_adapter = &x1205_attach,
-- .detach_client = &x1205_detach,
--};
--
--struct x1205_data {
-- struct i2c_client client;
-- struct list_head list;
-- unsigned int epoch;
--};
--
--static const unsigned char days_in_mo[] =
-- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
--
--static LIST_HEAD(x1205_clients);
--
--/* Workaround until the I2C subsytem will allow to send
-- * commands to a specific client. This function will send the command
-- * to the first client.
-- */
--int x1205_do_command(unsigned int cmd, void *arg)
--{
-- struct list_head *walk;
-- struct list_head *tmp;
-- struct x1205_data *data;
--
-- list_for_each_safe(walk, tmp, &x1205_clients) {
-- data = list_entry(walk, struct x1205_data, list);
-- return x1205_command(&data->client, cmd, arg);
-- }
--
-- return -ENODEV;
--}
--
--#define is_leap(year) \
-- ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
--
--/* make sure the rtc_time values are in bounds */
--static int x1205_validate_tm(struct rtc_time *tm)
--{
-- int year = tm->tm_year + 1900;
--
-- if ((tm->tm_year < 70) || (tm->tm_year > 255))
-- return -EINVAL;
--
-- if ((tm->tm_mon > 11) || (tm->tm_mday == 0))
-- return -EINVAL;
--
-- if (tm->tm_mday > days_in_mo[tm->tm_mon]
-- + ((tm->tm_mon == 1) && is_leap(year)))
-- return -EINVAL;
--
-- if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60))
-- return -EINVAL;
--
-- return 0;
--}
--
--/*
-- * In the routines that deal directly with the x1205 hardware, we use
-- * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
-- * Epoch is initialized as 2000. Time is set to UTC.
-- */
--static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
-- u8 reg_base)
--{
-- unsigned char dt_addr[2] = { 0, reg_base };
-- static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
--
-- unsigned char buf[8], sr;
--
-- struct i2c_msg msgs[] = {
-- { client->addr, 0, 2, sr_addr }, /* setup read ptr */
-- { client->addr, I2C_M_RD, 1, &sr }, /* read status */
-- { client->addr, 0, 2, dt_addr }, /* setup read ptr */
-- { client->addr, I2C_M_RD, 8, buf }, /* read date */
-- };
--
-- struct x1205_data *data = i2c_get_clientdata(client);
--
-- /* read status register */
-- if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
-- dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-- return -EIO;
-- }
--
-- /* check for battery failure */
-- if (sr & X1205_SR_RTCF) {
-- dev_warn(&client->dev,
-- "Clock had a power failure, you must set the date.\n");
-- return -EINVAL;
-- }
--
-- /* read date registers */
-- if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) {
-- dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-- return -EIO;
-- }
--
-- dev_dbg(&client->dev,
-- "%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
-- "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
-- __FUNCTION__,
-- buf[0], buf[1], buf[2], buf[3],
-- buf[4], buf[5], buf[6], buf[7]);
--
-- tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
-- tm->tm_min = BCD2BIN(buf[CCR_MIN]);
-- tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
-- tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
-- tm->tm_mon = BCD2BIN(buf[CCR_MONTH]);
-- data->epoch = BCD2BIN(buf[CCR_Y2K]) * 100;
-- tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + data->epoch - 1900;
-- tm->tm_wday = buf[CCR_WDAY];
--
-- dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
-- "mday=%d, mon=%d, year=%d, wday=%d\n",
-- __FUNCTION__,
-- tm->tm_sec, tm->tm_min, tm->tm_hour,
-- tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
--
-- return 0;
--}
--
--static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
-- int datetoo, u8 reg_base)
--{
-- int i, err, xfer;
--
-- unsigned char buf[8];
--
-- static const unsigned char wel[3] = { 0, X1205_REG_SR,
-- X1205_SR_WEL };
--
-- static const unsigned char rwel[3] = { 0, X1205_REG_SR,
-- X1205_SR_WEL | X1205_SR_RWEL };
--
-- static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
--
-- struct x1205_data *data = i2c_get_clientdata(client);
--
-- /* check if all values in the tm struct are correct */
-- if ((err = x1205_validate_tm(tm)) < 0)
-- return err;
--
-- dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
-- "mday=%d, mon=%d, year=%d, wday=%d\n",
-- __FUNCTION__,
-- tm->tm_sec, tm->tm_min, tm->tm_hour,
-- tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
--
-- buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
-- buf[CCR_MIN] = BIN2BCD(tm->tm_min);
--
-- /* set hour and 24hr bit */
-- buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;
--
-- /* should we also set the date? */
-- if (datetoo) {
-- buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
--
-- /* month, 0 - 11 */
-- buf[CCR_MONTH] = BIN2BCD(tm->tm_mon);
--
-- /* year, since 1900 */
-- buf[CCR_YEAR] = BIN2BCD(tm->tm_year + 1900 - data->epoch);
-- buf[CCR_WDAY] = tm->tm_wday & 0x07;
-- buf[CCR_Y2K] = BIN2BCD(data->epoch / 100);
-- }
--
-- /* this sequence is required to unlock the chip */
-- xfer = i2c_master_send(client, wel, 3);
-- if (xfer != 3) {
-- dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer);
-- return -EIO;
-- }
--
-- xfer = i2c_master_send(client, rwel, 3);
-- if (xfer != 3) {
-- dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer);
-- return -EIO;
-- }
--
-- /* write register's data */
-- for (i = 0; i < (datetoo ? 8 : 3); i++) {
-- unsigned char rdata[3] = { 0, reg_base + i, buf[i] };
--
-- xfer = i2c_master_send(client, rdata, 3);
-- if (xfer != 3) {
-- dev_err(&client->dev,
-- "%s: xfer=%d addr=%02x, data=%02x\n",
-- __FUNCTION__,
-- xfer, rdata[1], rdata[2]);
-- return -EIO;
-- }
-- };
--
-- /* disable further writes */
-- xfer = i2c_master_send(client, diswe, 3);
-- if (xfer != 3) {
-- dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer);
-- return -EIO;
-- }
--
-- return 0;
--}
--
--static int x1205_get_dtrim(struct i2c_client *client, int *trim)
--{
-- unsigned char dtr;
-- static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
--
-- struct i2c_msg msgs[] = {
-- { client->addr, 0, 2, dtr_addr }, /* setup read ptr */
-- { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */
-- };
--
-- /* read dtr register */
-- 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 dtr=%x\n", __FUNCTION__, dtr);
--
-- *trim = 0;
--
-- if (dtr & X1205_DTR_DTR0)
-- *trim += 20;
--
-- if (dtr & X1205_DTR_DTR1)
-- *trim += 10;
--
-- if (dtr & X1205_DTR_DTR2)
-- *trim = -*trim;
--
-- return 0;
--}
--
--static int x1205_get_atrim(struct i2c_client *client, int *trim)
--{
-- s8 atr;
-- static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
--
-- struct i2c_msg msgs[] = {
-- { client->addr, 0, 2, atr_addr }, /* setup read ptr */
-- { client->addr, I2C_M_RD, 1, &atr }, /* read atr */
-- };
--
-- /* read atr register */
-- 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 atr=%x\n", __FUNCTION__, atr);
--
-- /* atr is a two's complement value on 6 bits,
-- * perform sign extension. The formula is
-- * Catr = (atr * 0.25pF) + 11.00pF.
-- */
-- if (atr & 0x20)
-- atr |= 0xC0;
--
-- dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr);
--
-- *trim = (atr * 250) + 11000;
--
-- dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim);
--
-- return 0;
--}
--
--static int x1205_hctosys(struct i2c_client *client)
--{
-- int err;
--
-- struct rtc_time tm;
-- struct timespec tv;
--
-- err = x1205_command(client, X1205_CMD_GETDATETIME, &tm);
--
-- if (err) {
-- dev_err(&client->dev,
-- "Unable to set the system clock\n");
-- return err;
-- }
--
-- /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
-- * whether it stores the most close value or the value with partial
-- * seconds truncated. However, it is important that we use it to store
-- * the truncated value. This is because otherwise it is necessary,
-- * in an rtc sync function, to read both xtime.tv_sec and
-- * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
-- * of >32bits is not possible. So storing the most close value would
-- * slow down the sync API. So here we have the truncated value and
-- * the best guess is to add 0.5s.
-- */
--
-- tv.tv_nsec = NSEC_PER_SEC >> 1;
--
-- /* WARNING: this is not the C library 'mktime' call, it is a built in
-- * inline function from include/linux/time.h. It expects (requires)
-- * the month to be in the range 1-12
-- */
--
-- tv.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1,
-- tm.tm_mday, tm.tm_hour,
-- tm.tm_min, tm.tm_sec);
--
-- do_settimeofday(&tv);
--
-- dev_info(&client->dev,
-- "setting the system clock to %d-%d-%d %d:%d:%d\n",
-- tm.tm_year + 1900, tm.tm_mon + 1,
-- tm.tm_mday, tm.tm_hour, tm.tm_min,
-- tm.tm_sec);
--
-- return 0;
--}
--
--struct x1205_limit
--{
-- unsigned char reg;
-- unsigned char mask;
-- unsigned char min;
-- unsigned char max;
--};
--
--static int x1205_validate_client(struct i2c_client *client)
--{
-- int i, xfer;
--
-- /* Probe array. We will read the register at the specified
-- * address and check if the given bits are zero.
-- */
-- static const unsigned char probe_zero_pattern[] = {
-- /* register, mask */
-- X1205_REG_SR, 0x18,
-- X1205_REG_DTR, 0xF8,
-- X1205_REG_ATR, 0xC0,
-- X1205_REG_INT, 0x18,
-- X1205_REG_0, 0xFF,
-- };
--
-- static const struct x1205_limit probe_limits_pattern[] = {
-- /* register, mask, min, max */
-- { X1205_REG_Y2K, 0xFF, 19, 20 },
-- { X1205_REG_DW, 0xFF, 0, 6 },
-- { X1205_REG_YR, 0xFF, 0, 99 },
-- { X1205_REG_MO, 0xFF, 0, 12 },
-- { X1205_REG_DT, 0xFF, 0, 31 },
-- { X1205_REG_HR, 0x7F, 0, 23 },
-- { X1205_REG_MN, 0xFF, 0, 59 },
-- { X1205_REG_SC, 0xFF, 0, 59 },
-- { X1205_REG_Y2K1, 0xFF, 19, 20 },
-- { X1205_REG_Y2K0, 0xFF, 19, 20 },
-- };
--
-- /* check that registers have bits a 0 where expected */
-- for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) {
-- unsigned char buf;
--
-- unsigned char addr[2] = { 0, probe_zero_pattern[i] };
--
-- struct i2c_msg msgs[2] = {
-- { client->addr, 0, 2, addr },
-- { client->addr, I2C_M_RD, 1, &buf },
-- };
--
-- xfer = i2c_transfer(client->adapter, msgs, 2);
-- if (xfer != 2) {
-- dev_err(&client->adapter->dev,
-- "%s: could not read register %x\n",
-- __FUNCTION__, addr[1]);
--
-- return -EIO;
-- }
--
-- if ((buf & probe_zero_pattern[i+1]) != 0) {
-- dev_err(&client->adapter->dev,
-- "%s: register=%02x, zero pattern=%d, value=%x\n",
-- __FUNCTION__, addr[1], i, buf);
--
-- return -ENODEV;
-- }
-- }
--
-- /* check limits (only registers with bcd values) */
-- for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) {
-- unsigned char reg, value;
--
-- unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
--
-- struct i2c_msg msgs[2] = {
-- { client->addr, 0, 2, addr },
-- { client->addr, I2C_M_RD, 1, &reg },
-- };
--
-- xfer = i2c_transfer(client->adapter, msgs, 2);
--
-- if (xfer != 2) {
-- dev_err(&client->adapter->dev,
-- "%s: could not read register %x\n",
-- __FUNCTION__, addr[1]);
--
-- return -EIO;
-- }
--
-- value = BCD2BIN(reg & probe_limits_pattern[i].mask);
--
-- if (value > probe_limits_pattern[i].max ||
-- value < probe_limits_pattern[i].min) {
-- dev_dbg(&client->adapter->dev,
-- "%s: register=%x, lim pattern=%d, value=%d\n",
-- __FUNCTION__, addr[1], i, value);
--
-- return -ENODEV;
-- }
-- }
--
-- return 0;
--}
--
--static int x1205_attach(struct i2c_adapter *adapter)
--{
-- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
--
-- return i2c_probe(adapter, &addr_data, x1205_probe);
--}
--
--int x1205_direct_attach(int adapter_id,
-- struct i2c_client_address_data *address_data)
--{
-- int err;
-- struct i2c_adapter *adapter = i2c_get_adapter(adapter_id);
--
-- if (adapter) {
-- err = i2c_probe(adapter,
-- address_data, x1205_probe);
--
-- i2c_put_adapter(adapter);
--
-- return err;
-- }
--
-- return -ENODEV;
--}
--
--static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
--{
-- struct i2c_client *client;
-- struct x1205_data *data;
--
-- int err = 0;
--
-- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
--
-- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-- err = -ENODEV;
-- goto exit;
-- }
--
-- if (!(data = kzalloc(sizeof(struct x1205_data), GFP_KERNEL))) {
-- err = -ENOMEM;
-- goto exit;
-- }
--
-- /* Initialize our structures */
-- data->epoch = 2000;
--
-- client = &data->client;
-- client->addr = address;
-- client->driver = &x1205_driver;
-- client->adapter = adapter;
--
-- strlcpy(client->name, "x1205", I2C_NAME_SIZE);
--
-- i2c_set_clientdata(client, data);
--
-- /* Verify the chip is really an X1205 */
-- if (kind < 0) {
-- if (x1205_validate_client(client) < 0) {
-- err = -ENODEV;
-- goto exit_kfree;
-- }
-- }
--
-- /* Inform the i2c layer */
-- if ((err = i2c_attach_client(client)))
-- goto exit_kfree;
--
-- list_add(&data->list, &x1205_clients);
--
-- dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
--
-- /* If requested, set the system time */
-- if (hctosys)
-- x1205_hctosys(client);
--
-- return 0;
--
--exit_kfree:
-- kfree(data);
--
--exit:
-- return err;
--}
--
--static int x1205_detach(struct i2c_client *client)
--{
-- int err;
-- struct x1205_data *data = i2c_get_clientdata(client);
--
-- dev_dbg(&client->dev, "%s\n", __FUNCTION__);
--
-- if ((err = i2c_detach_client(client)))
-- return err;
--
-- list_del(&data->list);
--
-- kfree(data);
--
-- return 0;
--}
--
--static int x1205_command(struct i2c_client *client, unsigned int cmd,
-- void *param)
--{
-- if (param == NULL)
-- return -EINVAL;
--
-- if (!capable(CAP_SYS_TIME))
-- return -EACCES;
--
-- dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
--
-- switch (cmd) {
-- case X1205_CMD_GETDATETIME:
-- return x1205_get_datetime(client, param, X1205_CCR_BASE);
--
-- case X1205_CMD_SETTIME:
-- return x1205_set_datetime(client, param, 0,
-- X1205_CCR_BASE);
--
-- case X1205_CMD_SETDATETIME:
-- return x1205_set_datetime(client, param, 1,
-- X1205_CCR_BASE);
--
-- case X1205_CMD_GETALARM:
-- return x1205_get_datetime(client, param, X1205_ALM0_BASE);
--
-- case X1205_CMD_SETALARM:
-- return x1205_set_datetime(client, param, 1,
-- X1205_ALM0_BASE);
--
-- case X1205_CMD_GETDTRIM:
-- return x1205_get_dtrim(client, param);
--
-- case X1205_CMD_GETATRIM:
-- return x1205_get_atrim(client, param);
--
-- default:
-- return -EINVAL;
-- }
--}
--
--static int __init x1205_init(void)
--{
-- return i2c_add_driver(&x1205_driver);
--}
--
--static void __exit x1205_exit(void)
--{
-- i2c_del_driver(&x1205_driver);
--}
--
--MODULE_AUTHOR(
-- "Karen Spearel <kas11@tampabay.rr.com>, "
-- "Alessandro Zummo <a.zummo@towertech.it>");
--MODULE_DESCRIPTION("Xicor X1205 RTC driver");
--MODULE_LICENSE("GPL");
--MODULE_VERSION(DRV_VERSION);
--
--EXPORT_SYMBOL_GPL(x1205_do_command);
--EXPORT_SYMBOL_GPL(x1205_direct_attach);
--
--module_init(x1205_init);
--module_exit(x1205_exit);
---- 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
- obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
--obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
- obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
- obj-$(CONFIG_TPS65010) += tps65010.o
--obj-$(CONFIG_RTC_X1205_I2C) += x1205.o
-
- ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
- EXTRA_CFLAGS += -DDEBUG
---- 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 @@
--/*
-- * linux/drivers/i2c/chips/rtc8564.c
-- *
-- * Copyright (C) 2002-2004 Stefan Eletzhofer
-- *
-- * based on linux/drivers/acron/char/pcf8583.c
-- * Copyright (C) 2000 Russell King
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- *
-- * Driver for system3's EPSON RTC 8564 chip
-- */
--#include <linux/module.h>
--#include <linux/kernel.h>
--#include <linux/bcd.h>
--#include <linux/i2c.h>
--#include <linux/slab.h>
--#include <linux/string.h>
--#include <linux/rtc.h> /* get the user-level API */
--#include <linux/init.h>
--
--#include "rtc8564.h"
--
--#ifdef DEBUG
--# define _DBG(x, fmt, args...) do{ if (debug>=x) printk(KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
--#else
--# define _DBG(x, fmt, args...) do { } while(0);
--#endif
--
--#define _DBGRTCTM(x, rtctm) if (debug>=x) printk("%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
-- "mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \
-- (rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \
-- (rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl);
--
--struct rtc8564_data {
-- struct i2c_client client;
-- u16 ctrl;
--};
--
--static inline u8 _rtc8564_ctrl1(struct i2c_client *client)
--{
-- struct rtc8564_data *data = i2c_get_clientdata(client);
-- return data->ctrl & 0xff;
--}
--static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
--{
-- struct rtc8564_data *data = i2c_get_clientdata(client);
-- return (data->ctrl & 0xff00) >> 8;
--}
--
--#define CTRL1(c) _rtc8564_ctrl1(c)
--#define CTRL2(c) _rtc8564_ctrl2(c)
--
--static int debug;;
--module_param(debug, int, S_IRUGO | S_IWUSR);
--
--static struct i2c_driver rtc8564_driver;
--
--static unsigned short ignore[] = { I2C_CLIENT_END };
--static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END };
--
--static struct i2c_client_address_data addr_data = {
-- .normal_i2c = normal_addr,
-- .probe = ignore,
-- .ignore = ignore,
--};
--
--static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem);
--static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem);
--
--static int rtc8564_read(struct i2c_client *client, unsigned char adr,
-- unsigned char *buf, unsigned char len)
--{
-- int ret = -EIO;
-- unsigned char addr[1] = { adr };
-- struct i2c_msg msgs[2] = {
-- {client->addr, 0, 1, addr},
-- {client->addr, I2C_M_RD, len, buf}
-- };
--
-- _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len);
--
-- if (!buf) {
-- ret = -EINVAL;
-- goto done;
-- }
--
-- ret = i2c_transfer(client->adapter, msgs, 2);
-- if (ret == 2) {
-- ret = 0;
-- }
--
--done:
-- return ret;
--}
--
--static int rtc8564_write(struct i2c_client *client, unsigned char adr,
-- unsigned char *data, unsigned char len)
--{
-- int ret = 0;
-- unsigned char _data[16];
-- struct i2c_msg wr;
-- int i;
--
-- if (!data || len > 15) {
-- ret = -EINVAL;
-- goto done;
-- }
--
-- _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len);
--
-- _data[0] = adr;
-- for (i = 0; i < len; i++) {
-- _data[i + 1] = data[i];
-- _DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]);
-- }
--
-- wr.addr = client->addr;
-- wr.flags = 0;
-- wr.len = len + 1;
-- wr.buf = _data;
--
-- ret = i2c_transfer(client->adapter, &wr, 1);
-- if (ret == 1) {
-- ret = 0;
-- }
--
--done:
-- return ret;
--}
--
--static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
--{
-- int ret;
-- struct i2c_client *new_client;
-- struct rtc8564_data *d;
-- unsigned char data[10];
-- unsigned char ad[1] = { 0 };
-- struct i2c_msg ctrl_wr[1] = {
-- {addr, 0, 2, data}
-- };
-- struct i2c_msg ctrl_rd[2] = {
-- {addr, 0, 1, ad},
-- {addr, I2C_M_RD, 2, data}
-- };
--
-- d = kzalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
-- if (!d) {
-- ret = -ENOMEM;
-- goto done;
-- }
-- new_client = &d->client;
--
-- strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
-- i2c_set_clientdata(new_client, d);
-- new_client->addr = addr;
-- new_client->adapter = adap;
-- new_client->driver = &rtc8564_driver;
--
-- _DBG(1, "client=%p", new_client);
--
-- /* init ctrl1 reg */
-- data[0] = 0;
-- data[1] = 0;
-- ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
-- if (ret != 1) {
-- printk(KERN_INFO "rtc8564: cant init ctrl1\n");
-- ret = -ENODEV;
-- goto done;
-- }
--
-- /* read back ctrl1 and ctrl2 */
-- ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
-- if (ret != 2) {
-- printk(KERN_INFO "rtc8564: cant read ctrl\n");
-- ret = -ENODEV;
-- goto done;
-- }
--
-- d->ctrl = data[0] | (data[1] << 8);
--
-- _DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
-- data[0], data[1]);
--
-- ret = i2c_attach_client(new_client);
--done:
-- if (ret) {
-- kfree(d);
-- }
-- return ret;
--}
--
--static int rtc8564_probe(struct i2c_adapter *adap)
--{
-- return i2c_probe(adap, &addr_data, rtc8564_attach);
--}
--
--static int rtc8564_detach(struct i2c_client *client)
--{
-- i2c_detach_client(client);
-- kfree(i2c_get_clientdata(client));
-- return 0;
--}
--
--static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
--{
-- int ret = -EIO;
-- unsigned char buf[15];
--
-- _DBG(1, "client=%p, dt=%p", client, dt);
--
-- if (!dt)
-- return -EINVAL;
--
-- memset(buf, 0, sizeof(buf));
--
-- ret = rtc8564_read(client, 0, buf, 15);
-- if (ret)
-- return ret;
--
-- /* century stored in minute alarm reg */
-- dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]);
-- dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
-- dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f);
-- dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7);
-- dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
--
-- dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f);
-- dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
-- dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f);
-- dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f);
--
-- _DBGRTCTM(2, *dt);
--
-- return 0;
--}
--
--static int
--rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
--{
-- int ret, len = 5;
-- unsigned char buf[15];
--
-- _DBG(1, "client=%p, dt=%p", client, dt);
--
-- if (!dt)
-- return -EINVAL;
--
-- _DBGRTCTM(2, *dt);
--
-- buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
-- buf[RTC8564_REG_CTRL2] = CTRL2(client);
-- buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs);
-- buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins);
-- buf[RTC8564_REG_HR] = BIN2BCD(dt->hours);
--
-- if (datetoo) {
-- len += 5;
-- buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday);
-- buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday);
-- buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f;
-- /* century stored in minute alarm reg */
-- buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100);
-- buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100);
-- }
--
-- ret = rtc8564_write(client, 0, buf, len);
-- if (ret) {
-- _DBG(1, "error writing data! %d", ret);
-- }
--
-- buf[RTC8564_REG_CTRL1] = CTRL1(client);
-- ret = rtc8564_write(client, 0, buf, 1);
-- if (ret) {
-- _DBG(1, "error writing data! %d", ret);
-- }
--
-- return ret;
--}
--
--static int rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
--{
-- struct rtc8564_data *data = i2c_get_clientdata(client);
--
-- if (!ctrl)
-- return -1;
--
-- *ctrl = data->ctrl;
-- return 0;
--}
--
--static int rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
--{
-- struct rtc8564_data *data = i2c_get_clientdata(client);
-- unsigned char buf[2];
--
-- if (!ctrl)
-- return -1;
--
-- buf[0] = *ctrl & 0xff;
-- buf[1] = (*ctrl & 0xff00) >> 8;
-- data->ctrl = *ctrl;
--
-- return rtc8564_write(client, 0, buf, 2);
--}
--
--static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem)
--{
--
-- if (!mem)
-- return -EINVAL;
--
-- return rtc8564_read(client, mem->loc, mem->data, mem->nr);
--}
--
--static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem)
--{
--
-- if (!mem)
-- return -EINVAL;
--
-- return rtc8564_write(client, mem->loc, mem->data, mem->nr);
--}
--
--static int
--rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
--{
--
-- _DBG(1, "cmd=%d", cmd);
--
-- switch (cmd) {
-- case RTC_GETDATETIME:
-- return rtc8564_get_datetime(client, arg);
--
-- case RTC_SETTIME:
-- return rtc8564_set_datetime(client, arg, 0);
--
-- case RTC_SETDATETIME:
-- return rtc8564_set_datetime(client, arg, 1);
--
-- case RTC_GETCTRL:
-- return rtc8564_get_ctrl(client, arg);
--
-- case RTC_SETCTRL:
-- return rtc8564_set_ctrl(client, arg);
--
-- case MEM_READ:
-- return rtc8564_read_mem(client, arg);
--
-- case MEM_WRITE:
-- return rtc8564_write_mem(client, arg);
--
-- default:
-- return -EINVAL;
-- }
--}
--
--static struct i2c_driver rtc8564_driver = {
-- .driver = {
-- .name = "RTC8564",
-- },
-- .id = I2C_DRIVERID_RTC8564,
-- .attach_adapter = rtc8564_probe,
-- .detach_client = rtc8564_detach,
-- .command = rtc8564_command
--};
--
--static __init int rtc8564_init(void)
--{
-- return i2c_add_driver(&rtc8564_driver);
--}
--
--static __exit void rtc8564_exit(void)
--{
-- i2c_del_driver(&rtc8564_driver);
--}
--
--MODULE_AUTHOR("Stefan Eletzhofer <Stefan.Eletzhofer@eletztrick.de>");
--MODULE_DESCRIPTION("EPSON RTC8564 Driver");
--MODULE_LICENSE("GPL");
--
--module_init(rtc8564_init);
--module_exit(rtc8564_exit);
---- 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 @@
--/*
-- * linux/drivers/i2c/chips/rtc8564.h
-- *
-- * Copyright (C) 2002-2004 Stefan Eletzhofer
-- *
-- * based on linux/drivers/acron/char/pcf8583.h
-- * Copyright (C) 2000 Russell King
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
--struct rtc_tm {
-- unsigned char secs;
-- unsigned char mins;
-- unsigned char hours;
-- unsigned char mday;
-- unsigned char mon;
-- unsigned short year; /* xxxx 4 digits :) */
-- unsigned char wday;
-- unsigned char vl;
--};
--
--struct mem {
-- unsigned int loc;
-- unsigned int nr;
-- unsigned char *data;
--};
--
--#define RTC_GETDATETIME 0
--#define RTC_SETTIME 1
--#define RTC_SETDATETIME 2
--#define RTC_GETCTRL 3
--#define RTC_SETCTRL 4
--#define MEM_READ 5
--#define MEM_WRITE 6
--
--#define RTC8564_REG_CTRL1 0x0 /* T 0 S 0 | T 0 0 0 */
--#define RTC8564_REG_CTRL2 0x1 /* 0 0 0 TI/TP | AF TF AIE TIE */
--#define RTC8564_REG_SEC 0x2 /* VL 4 2 1 | 8 4 2 1 */
--#define RTC8564_REG_MIN 0x3 /* x 4 2 1 | 8 4 2 1 */
--#define RTC8564_REG_HR 0x4 /* x x 2 1 | 8 4 2 1 */
--#define RTC8564_REG_DAY 0x5 /* x x 2 1 | 8 4 2 1 */
--#define RTC8564_REG_WDAY 0x6 /* x x x x | x 4 2 1 */
--#define RTC8564_REG_MON_CENT 0x7 /* C x x 1 | 8 4 2 1 */
--#define RTC8564_REG_YEAR 0x8 /* 8 4 2 1 | 8 4 2 1 */
--#define RTC8564_REG_AL_MIN 0x9 /* AE 4 2 1 | 8 4 2 1 */
--#define RTC8564_REG_AL_HR 0xa /* AE 4 2 1 | 8 4 2 1 */
--#define RTC8564_REG_AL_DAY 0xb /* AE x 2 1 | 8 4 2 1 */
--#define RTC8564_REG_AL_WDAY 0xc /* AE x x x | x 4 2 1 */
--#define RTC8564_REG_CLKOUT 0xd /* FE x x x | x x FD1 FD0 */
--#define RTC8564_REG_TCTL 0xe /* TE x x x | x x FD1 FD0 */
--#define RTC8564_REG_TIMER 0xf /* 8 bit binary */
--
--/* Control reg */
--#define RTC8564_CTRL1_TEST1 (1<<3)
--#define RTC8564_CTRL1_STOP (1<<5)
--#define RTC8564_CTRL1_TEST2 (1<<7)
--
--#define RTC8564_CTRL2_TIE (1<<0)
--#define RTC8564_CTRL2_AIE (1<<1)
--#define RTC8564_CTRL2_TF (1<<2)
--#define RTC8564_CTRL2_AF (1<<3)
--#define RTC8564_CTRL2_TI_TP (1<<4)
--
--/* CLKOUT frequencies */
--#define RTC8564_FD_32768HZ (0x0)
--#define RTC8564_FD_1024HZ (0x1)
--#define RTC8564_FD_32 (0x2)
--#define RTC8564_FD_1HZ (0x3)
--
--/* Timer CTRL */
--#define RTC8564_TD_4096HZ (0x0)
--#define RTC8564_TD_64HZ (0x1)
--#define RTC8564_TD_1HZ (0x2)
--#define RTC8564_TD_1_60HZ (0x3)
--
--#define I2C_DRIVERID_RTC8564 0xf000
---- 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 @@
--/*
-- * x1205.h - defines for drivers/i2c/chips/x1205.c
-- * Copyright 2004 Karen Spearel
-- * Copyright 2005 Alessandro Zummo
-- *
-- * 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.
-- */
--
--#ifndef __LINUX_X1205_H__
--#define __LINUX_X1205_H__
--
--/* commands */
--
--#define X1205_CMD_GETDATETIME 0
--#define X1205_CMD_SETTIME 1
--#define X1205_CMD_SETDATETIME 2
--#define X1205_CMD_GETALARM 3
--#define X1205_CMD_SETALARM 4
--#define X1205_CMD_GETDTRIM 5
--#define X1205_CMD_SETDTRIM 6
--#define X1205_CMD_GETATRIM 7
--#define X1205_CMD_SETATRIM 8
--
--extern int x1205_do_command(unsigned int cmd, void *arg);
--extern int x1205_direct_attach(int adapter_id,
-- struct i2c_client_address_data *address_data);
--
--#endif /* __LINUX_X1205_H__ */
---- 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.
-
--config SENSORS_RTC8564
-- tristate "Epson 8564 RTC chip"
-- depends on I2C && EXPERIMENTAL
-- help
-- If you say yes here you get support for the Epson 8564 RTC chip.
--
-- This driver can also be built as a module. If so, the module
-- will be called i2c-rtc8564.
--
- config ISP1301_OMAP
- tristate "Philips ISP1301 with OMAP OTG"
- depends on I2C && ARCH_OMAP_OTG
-@@ -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.
-
--config RTC_X1205_I2C
-- tristate "Xicor X1205 RTC chip"
-- depends on I2C && EXPERIMENTAL
-- help
-- If you say yes here you get support for the Xicor X1205 RTC chip.
--
-- This driver can also be built as a module. If so, the module
-- will be called x1205.
--
- endmenu
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-ixp4xx/drivers/rtc/rtc-sysfs.c 2006-03-08 01:59:26.000000000 +0100
-@@ -0,0 +1,124 @@
-+/*
-+ * 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;
-+ struct rtc_time tm;
-+
-+ 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);
-+ }
-+
-+ 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;
-+ struct rtc_time tm;
-+
-+ 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);
-+ }
-+
-+ 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;
-+ struct rtc_time tm;
-+
-+ retval = rtc_read_time(dev, &tm);
-+ if (retval == 0) {
-+ unsigned long time;
-+ rtc_tm_to_time(&tm, &time);
-+ retval = sprintf(buf, "%lu\n", time);
-+ }
-+
-+ return retval;
-+}
-+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,
-+};
-+
-+static struct attribute_group rtc_attr_group = {
-+ .attrs = rtc_attrs,
-+};
-+
-+static int __devinit rtc_sysfs_add_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
-+{
-+ int err;
-+
-+ dev_info(class_dev->dev, "rtc intf: sysfs\n");
-+
-+ err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
-+ if (err)
-+ dev_err(class_dev->dev,
-+ "failed to create sysfs attributes\n");
-+
-+ return err;
-+}
-+
-+static void rtc_sysfs_remove_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
-+{
-+ sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
-+}
-+
-+/* interface registration */
-+
-+static 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-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-06 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 DEFINE_MUTEX(rtc_lock);
-+
-+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;
-+
-+ 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",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
-+ }
-+
-+ 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);
-+ 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)
-+{
-+ mutex_lock(&rtc_lock);
-+ if (rtc_dev == NULL) {
-+ struct proc_dir_entry *ent;
-+
-+ rtc_dev = class_dev;
-+
-+ 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;
-+ ent->owner = rtc->owner;
-+ ent->data = class_dev;
-+
-+ dev_info(class_dev->dev, "rtc intf: proc\n");
-+ }
-+ else
-+ rtc_dev = NULL;
-+ }
-+ mutex_unlock(&rtc_lock);
-+
-+ return 0;
-+}
-+
-+static void rtc_proc_remove_device(struct class_device *class_dev,
-+ struct class_interface *class_intf)
-+{
-+ mutex_lock(&rtc_lock);
-+ if (rtc_dev == class_dev) {
-+ remove_proc_entry("driver/rtc", NULL);
-+ rtc_dev = NULL;
-+ }
-+ mutex_unlock(&rtc_lock);
-+}
-+
-+static 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);
-+}
-+
-+static void __exit rtc_proc_exit(void)
-+{
-+ class_interface_unregister(&rtc_proc_interface);
-+}
-+
-+module_init(rtc_proc_init);
-+module_exit(rtc_proc_exit);
-+
-+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-+MODULE_DESCRIPTION("RTC class proc interface");
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-ixp4xx/drivers/rtc/rtc-dev.c 2006-03-08 01:59:26.000000000 +0100
-@@ -0,0 +1,382 @@
-+/*
-+ * RTC subsystem, dev 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>
-+
-+static struct class *rtc_dev_class;
-+static dev_t rtc_devt;
-+
-+#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
-+
-+static int rtc_dev_open(struct inode *inode, struct file *file)
-+{
-+ int err;
-+ struct rtc_device *rtc = container_of(inode->i_cdev,
-+ struct rtc_device, char_dev);
-+ struct rtc_class_ops *ops = rtc->ops;
-+
-+ /* We keep the lock as long as the device is in use
-+ * and return immediately if busy
-+ */
-+ if (!(mutex_trylock(&rtc->char_lock)))
-+ return -EBUSY;
-+
-+ file->private_data = &rtc->class_dev;
-+
-+ 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);
-+
-+ return 0;
-+ }
-+
-+ /* something has gone wrong, release the lock */
-+ mutex_unlock(&rtc->char_lock);
-+ return err;
-+}
-+
-+
-+static ssize_t
-+rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-+{
-+ struct rtc_device *rtc = to_rtc_device(file->private_data);
-+
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long data;
-+ ssize_t ret;
-+
-+ if (count < sizeof(unsigned long))
-+ return -EINVAL;
-+
-+ add_wait_queue(&rtc->irq_queue, &wait);
-+ do {
-+ __set_current_state(TASK_INTERRUPTIBLE);
-+
-+ spin_lock_irq(&rtc->irq_lock);
-+ data = rtc->irq_data;
-+ rtc->irq_data = 0;
-+ spin_unlock_irq(&rtc->irq_lock);
-+
-+ if (data != 0) {
-+ ret = 0;
-+ break;
-+ }
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ break;
-+ }
-+ if (signal_pending(current)) {
-+ ret = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule();
-+ } while (1);
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&rtc->irq_queue, &wait);
-+
-+ if (ret == 0) {
-+ /* Check for any data updates */
-+ if (rtc->ops->read_callback)
-+ data = rtc->ops->read_callback(rtc->class_dev.dev, data);
-+
-+ ret = put_user(data, (unsigned long __user *)buf);
-+ if (ret == 0)
-+ ret = sizeof(unsigned long);
-+ }
-+ return ret;
-+}
-+
-+static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
-+{
-+ struct rtc_device *rtc = to_rtc_device(file->private_data);
-+ unsigned long data;
-+
-+ poll_wait(file, &rtc->irq_queue, wait);
-+
-+ data = rtc->irq_data;
-+
-+ return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
-+}
-+
-+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;
-+ struct rtc_device *rtc = to_rtc_device(class_dev);
-+ struct rtc_class_ops *ops = rtc->ops;
-+ struct rtc_time tm;
-+ struct rtc_wkalrm alarm;
-+ void __user *uarg = (void __user *) arg;
-+
-+ /* avoid conflicting IRQ users */
-+ if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
-+ spin_lock(&rtc->irq_task_lock);
-+ if (rtc->irq_task)
-+ err = -EBUSY;
-+ spin_unlock(&rtc->irq_task_lock);
-+
-+ if (err < 0)
-+ return err;
-+ }
-+
-+ /* try the driver's ioctl interface */
-+ if (ops->ioctl) {
-+ err = ops->ioctl(class_dev->dev, cmd, arg);
-+ if (err != -EINVAL)
-+ return err;
-+ }
-+
-+ /* if the driver does not provide the ioctl interface
-+ * or if that particular ioctl was not implemented
-+ * (-EINVAL), we will try to emulate here.
-+ */
-+
-+ switch (cmd) {
-+ case RTC_ALM_READ:
-+ err = rtc_read_alarm(class_dev, &alarm);
-+ if (err < 0)
-+ return err;
-+
-+ if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
-+ return -EFAULT;
-+ break;
-+
-+ case RTC_ALM_SET:
-+ if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
-+ return -EFAULT;
-+
-+ alarm.enabled = 0;
-+ alarm.pending = 0;
-+ alarm.time.tm_mday = -1;
-+ alarm.time.tm_mon = -1;
-+ alarm.time.tm_year = -1;
-+ alarm.time.tm_wday = -1;
-+ alarm.time.tm_yday = -1;
-+ alarm.time.tm_isdst = -1;
-+ err = rtc_set_alarm(class_dev, &alarm);
-+ break;
-+
-+ case RTC_RD_TIME:
-+ err = rtc_read_time(class_dev, &tm);
-+ if (err < 0)
-+ return err;
-+
-+ if (copy_to_user(uarg, &tm, sizeof(tm)))
-+ return -EFAULT;
-+ break;
-+
-+ case RTC_SET_TIME:
-+ if (!capable(CAP_SYS_TIME))
-+ return -EACCES;
-+
-+ if (copy_from_user(&tm, uarg, sizeof(tm)))
-+ return -EFAULT;
-+
-+ err = rtc_set_time(class_dev, &tm);
-+ break;
-+#if 0
-+ case RTC_EPOCH_SET:
-+#ifndef rtc_epoch
-+ /*
-+ * There were no RTC clocks before 1900.
-+ */
-+ if (arg < 1900) {
-+ err = -EINVAL;
-+ break;
-+ }
-+ if (!capable(CAP_SYS_TIME)) {
-+ err = -EACCES;
-+ break;
-+ }
-+ rtc_epoch = arg;
-+ err = 0;
-+#endif
-+ break;
-+
-+ case RTC_EPOCH_READ:
-+ err = put_user(rtc_epoch, (unsigned long __user *)uarg);
-+ break;
-+#endif
-+ case RTC_WKALM_SET:
-+ if (copy_from_user(&alarm, uarg, sizeof(alarm)))
-+ return -EFAULT;
-+
-+ err = rtc_set_alarm(class_dev, &alarm);
-+ break;
-+
-+ case RTC_WKALM_RD:
-+ err = rtc_read_alarm(class_dev, &alarm);
-+ if (err < 0)
-+ return err;
-+
-+ if (copy_to_user(uarg, &alarm, sizeof(alarm)))
-+ return -EFAULT;
-+ break;
-+
-+ default:
-+ err = -EINVAL;
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static int rtc_dev_release(struct inode *inode, struct file *file)
-+{
-+ struct rtc_device *rtc = to_rtc_device(file->private_data);
-+
-+ if (rtc->ops->release)
-+ rtc->ops->release(rtc->class_dev.dev);
-+
-+ mutex_unlock(&rtc->char_lock);
-+ return 0;
-+}
-+
-+static int rtc_dev_fasync(int fd, struct file *file, int on)
-+{
-+ struct rtc_device *rtc = to_rtc_device(file->private_data);
-+ return fasync_helper(fd, file, on, &rtc->async_queue);
-+}
-+
-+static struct file_operations rtc_dev_fops = {
-+ .owner = THIS_MODULE,
-+ .llseek = no_llseek,
-+ .read = rtc_dev_read,
-+ .poll = rtc_dev_poll,
-+ .ioctl = rtc_dev_ioctl,
-+ .open = rtc_dev_open,
-+ .release = rtc_dev_release,
-+ .fasync = rtc_dev_fasync,
-+};
-+
-+/* 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) {
-+ dev_err(class_dev->dev, "too many RTCs\n");
-+ return -EINVAL;
-+ }
-+
-+ mutex_init(&rtc->char_lock);
-+ spin_lock_init(&rtc->irq_lock);
-+ init_waitqueue_head(&rtc->irq_queue);
-+
-+ cdev_init(&rtc->char_dev, &rtc_dev_fops);
-+ rtc->char_dev.owner = rtc->owner;
-+
-+ 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(rtc_devt), rtc->id);
-+ return -ENODEV;
-+ }
-+
-+ 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(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,
-+ struct class_interface *class_intf)
-+{
-+ struct rtc_device *rtc = to_rtc_device(class_dev);
-+
-+ if (rtc->rtc_dev) {
-+ dev_dbg(class_dev->dev, "removing char %d:%d\n",
-+ MAJOR(rtc->rtc_dev->devt),
-+ MINOR(rtc->rtc_dev->devt));
-+
-+ class_device_unregister(rtc->rtc_dev);
-+ cdev_del(&rtc->char_dev);
-+ }
-+}
-+
-+/* interface registration */
-+
-+static struct class_interface rtc_dev_interface = {
-+ .add = &rtc_dev_add_device,
-+ .remove = &rtc_dev_remove_device,
-+};
-+
-+static int __init rtc_dev_init(void)
-+{
-+ int err;
-+
-+ 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__);
-+ goto err_destroy_class;
-+ }
-+
-+ err = rtc_interface_register(&rtc_dev_interface);
-+ if (err < 0) {
-+ printk(KERN_ERR "%s: failed to register the interface\n",
-+ __FILE__);
-+ 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);
-+}
-+
-+module_init(rtc_dev_init);
-+module_exit(rtc_dev_exit);
-+
-+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-+MODULE_DESCRIPTION("RTC class dev interface");
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ 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
-+ * Copyright 2004 Karen Spearel
-+ * Copyright 2005 Alessandro Zummo
-+ *
-+ * please send all reports to:
-+ * Karen Spearel <kas111 at gmail dot com>
-+ * Alessandro Zummo <a.zummo@towertech.it>
-+ *
-+ * based on a lot of other RTC drivers.
-+ *
-+ * 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/i2c.h>
-+#include <linux/bcd.h>
-+#include <linux/rtc.h>
-+#include <linux/delay.h>
-+
-+#define DRV_VERSION "1.0.6"
-+
-+/* Addresses to scan: none. This chip is located at
-+ * 0x6f and uses a two bytes register addressing.
-+ * Two bytes need to be written to read a single register,
-+ * while most other chips just require one and take the second
-+ * one as the data to be written. To prevent corrupting
-+ * unknown chips, the user must explicitely set the probe parameter.
-+ */
-+
-+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-+
-+/* Insmod parameters */
-+I2C_CLIENT_INSMOD;
-+
-+/* offsets into CCR area */
-+
-+#define CCR_SEC 0
-+#define CCR_MIN 1
-+#define CCR_HOUR 2
-+#define CCR_MDAY 3
-+#define CCR_MONTH 4
-+#define CCR_YEAR 5
-+#define CCR_WDAY 6
-+#define CCR_Y2K 7
-+
-+#define X1205_REG_SR 0x3F /* status register */
-+#define X1205_REG_Y2K 0x37
-+#define X1205_REG_DW 0x36
-+#define X1205_REG_YR 0x35
-+#define X1205_REG_MO 0x34
-+#define X1205_REG_DT 0x33
-+#define X1205_REG_HR 0x32
-+#define X1205_REG_MN 0x31
-+#define X1205_REG_SC 0x30
-+#define X1205_REG_DTR 0x13
-+#define X1205_REG_ATR 0x12
-+#define X1205_REG_INT 0x11
-+#define X1205_REG_0 0x10
-+#define X1205_REG_Y2K1 0x0F
-+#define X1205_REG_DWA1 0x0E
-+#define X1205_REG_YRA1 0x0D
-+#define X1205_REG_MOA1 0x0C
-+#define X1205_REG_DTA1 0x0B
-+#define X1205_REG_HRA1 0x0A
-+#define X1205_REG_MNA1 0x09
-+#define X1205_REG_SCA1 0x08
-+#define X1205_REG_Y2K0 0x07
-+#define X1205_REG_DWA0 0x06
-+#define X1205_REG_YRA0 0x05
-+#define X1205_REG_MOA0 0x04
-+#define X1205_REG_DTA0 0x03
-+#define X1205_REG_HRA0 0x02
-+#define X1205_REG_MNA0 0x01
-+#define X1205_REG_SCA0 0x00
-+
-+#define X1205_CCR_BASE 0x30 /* Base address of CCR */
-+#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */
-+
-+#define X1205_SR_RTCF 0x01 /* Clock failure */
-+#define X1205_SR_WEL 0x02 /* Write Enable Latch */
-+#define X1205_SR_RWEL 0x04 /* Register Write Enable */
-+
-+#define X1205_DTR_DTR0 0x01
-+#define X1205_DTR_DTR1 0x02
-+#define X1205_DTR_DTR2 0x04
-+
-+#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */
-+
-+/* Prototypes */
-+static int x1205_attach(struct i2c_adapter *adapter);
-+static int x1205_detach(struct i2c_client *client);
-+static int x1205_probe(struct i2c_adapter *adapter, int address, int kind);
-+
-+static struct i2c_driver x1205_driver = {
-+ .driver = {
-+ .name = "x1205",
-+ },
-+ .attach_adapter = &x1205_attach,
-+ .detach_client = &x1205_detach,
-+};
-+
-+/*
-+ * In the routines that deal directly with the x1205 hardware, we use
-+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
-+ * Epoch is initialized as 2000. Time is set to UTC.
-+ */
-+static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
-+ unsigned char reg_base)
-+{
-+ unsigned char dt_addr[2] = { 0, reg_base };
-+
-+ unsigned char buf[8];
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 2, dt_addr }, /* setup read ptr */
-+ { client->addr, I2C_M_RD, 8, 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;
-+ }
-+
-+ dev_dbg(&client->dev,
-+ "%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
-+ "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
-+ __FUNCTION__,
-+ buf[0], buf[1], buf[2], buf[3],
-+ buf[4], buf[5], buf[6], buf[7]);
-+
-+ tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
-+ tm->tm_min = BCD2BIN(buf[CCR_MIN]);
-+ tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
-+ tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
-+ tm->tm_mon = BCD2BIN(buf[CCR_MONTH]) - 1; /* mon is 0-11 */
-+ tm->tm_year = BCD2BIN(buf[CCR_YEAR])
-+ + (BCD2BIN(buf[CCR_Y2K]) * 100) - 1900;
-+ tm->tm_wday = buf[CCR_WDAY];
-+
-+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ return 0;
-+}
-+
-+static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
-+{
-+ static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 2, sr_addr }, /* setup read ptr */
-+ { client->addr, I2C_M_RD, 1, sr }, /* read status */
-+ };
-+
-+ /* read status register */
-+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
-+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
-+ int datetoo, u8 reg_base)
-+{
-+ int i, xfer;
-+ unsigned char buf[8];
-+
-+ static const unsigned char wel[3] = { 0, X1205_REG_SR,
-+ X1205_SR_WEL };
-+
-+ static const unsigned char rwel[3] = { 0, X1205_REG_SR,
-+ X1205_SR_WEL | X1205_SR_RWEL };
-+
-+ static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
-+
-+ dev_dbg(&client->dev,
-+ "%s: secs=%d, mins=%d, hours=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour);
-+
-+ buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
-+ buf[CCR_MIN] = BIN2BCD(tm->tm_min);
-+
-+ /* set hour and 24hr bit */
-+ buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;
-+
-+ /* should we also set the date? */
-+ if (datetoo) {
-+ dev_dbg(&client->dev,
-+ "%s: mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
-+
-+ /* month, 1 - 12 */
-+ buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1);
-+
-+ /* year, since the rtc epoch*/
-+ buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100);
-+ buf[CCR_WDAY] = tm->tm_wday & 0x07;
-+ buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100);
-+ }
-+
-+ /* this sequence is required to unlock the chip */
-+ if ((xfer = i2c_master_send(client, wel, 3)) != 3) {
-+ dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer);
-+ return -EIO;
-+ }
-+
-+ if ((xfer = i2c_master_send(client, rwel, 3)) != 3) {
-+ dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer);
-+ return -EIO;
-+ }
-+
-+ /* write register's data */
-+ for (i = 0; i < (datetoo ? 8 : 3); i++) {
-+ unsigned char rdata[3] = { 0, reg_base + i, buf[i] };
-+
-+ xfer = i2c_master_send(client, rdata, 3);
-+ if (xfer != 3) {
-+ dev_err(&client->dev,
-+ "%s: xfer=%d addr=%02x, data=%02x\n",
-+ __FUNCTION__,
-+ xfer, rdata[1], rdata[2]);
-+ return -EIO;
-+ }
-+ };
-+
-+ /* disable further writes */
-+ if ((xfer = i2c_master_send(client, diswe, 3)) != 3) {
-+ dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int x1205_fix_osc(struct i2c_client *client)
-+{
-+ int err;
-+ struct rtc_time tm;
-+
-+ tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
-+
-+ if ((err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE)) < 0)
-+ dev_err(&client->dev,
-+ "unable to restart the oscillator\n");
-+
-+ return err;
-+}
-+
-+static int x1205_get_dtrim(struct i2c_client *client, int *trim)
-+{
-+ unsigned char dtr;
-+ static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 2, dtr_addr }, /* setup read ptr */
-+ { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */
-+ };
-+
-+ /* read dtr register */
-+ 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 dtr=%x\n", __FUNCTION__, dtr);
-+
-+ *trim = 0;
-+
-+ if (dtr & X1205_DTR_DTR0)
-+ *trim += 20;
-+
-+ if (dtr & X1205_DTR_DTR1)
-+ *trim += 10;
-+
-+ if (dtr & X1205_DTR_DTR2)
-+ *trim = -*trim;
-+
-+ return 0;
-+}
-+
-+static int x1205_get_atrim(struct i2c_client *client, int *trim)
-+{
-+ s8 atr;
-+ static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 2, atr_addr }, /* setup read ptr */
-+ { client->addr, I2C_M_RD, 1, &atr }, /* read atr */
-+ };
-+
-+ /* read atr register */
-+ 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 atr=%x\n", __FUNCTION__, atr);
-+
-+ /* atr is a two's complement value on 6 bits,
-+ * perform sign extension. The formula is
-+ * Catr = (atr * 0.25pF) + 11.00pF.
-+ */
-+ if (atr & 0x20)
-+ atr |= 0xC0;
-+
-+ dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr);
-+
-+ *trim = (atr * 250) + 11000;
-+
-+ dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim);
-+
-+ return 0;
-+}
-+
-+struct x1205_limit
-+{
-+ unsigned char reg, mask, min, max;
-+};
-+
-+static int x1205_validate_client(struct i2c_client *client)
-+{
-+ int i, xfer;
-+
-+ /* Probe array. We will read the register at the specified
-+ * address and check if the given bits are zero.
-+ */
-+ static const unsigned char probe_zero_pattern[] = {
-+ /* register, mask */
-+ X1205_REG_SR, 0x18,
-+ X1205_REG_DTR, 0xF8,
-+ X1205_REG_ATR, 0xC0,
-+ X1205_REG_INT, 0x18,
-+ X1205_REG_0, 0xFF,
-+ };
-+
-+ static const struct x1205_limit probe_limits_pattern[] = {
-+ /* register, mask, min, max */
-+ { X1205_REG_Y2K, 0xFF, 19, 20 },
-+ { X1205_REG_DW, 0xFF, 0, 6 },
-+ { X1205_REG_YR, 0xFF, 0, 99 },
-+ { X1205_REG_MO, 0xFF, 0, 12 },
-+ { X1205_REG_DT, 0xFF, 0, 31 },
-+ { X1205_REG_HR, 0x7F, 0, 23 },
-+ { X1205_REG_MN, 0xFF, 0, 59 },
-+ { X1205_REG_SC, 0xFF, 0, 59 },
-+ { X1205_REG_Y2K1, 0xFF, 19, 20 },
-+ { X1205_REG_Y2K0, 0xFF, 19, 20 },
-+ };
-+
-+ /* check that registers have bits a 0 where expected */
-+ for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) {
-+ unsigned char buf;
-+
-+ unsigned char addr[2] = { 0, probe_zero_pattern[i] };
-+
-+ struct i2c_msg msgs[2] = {
-+ { client->addr, 0, 2, addr },
-+ { client->addr, I2C_M_RD, 1, &buf },
-+ };
-+
-+ 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]);
-+
-+ return -EIO;
-+ }
-+
-+ if ((buf & probe_zero_pattern[i+1]) != 0) {
-+ dev_err(&client->adapter->dev,
-+ "%s: register=%02x, zero pattern=%d, value=%x\n",
-+ __FUNCTION__, probe_zero_pattern[i], i, buf);
-+
-+ return -ENODEV;
-+ }
-+ }
-+
-+ /* check limits (only registers with bcd values) */
-+ for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) {
-+ unsigned char reg, value;
-+
-+ unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
-+
-+ struct i2c_msg msgs[2] = {
-+ { client->addr, 0, 2, addr },
-+ { client->addr, I2C_M_RD, 1, &reg },
-+ };
-+
-+ if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
-+ dev_err(&client->adapter->dev,
-+ "%s: could not read register %x\n",
-+ __FUNCTION__, probe_limits_pattern[i].reg);
-+
-+ return -EIO;
-+ }
-+
-+ value = BCD2BIN(reg & probe_limits_pattern[i].mask);
-+
-+ if (value > probe_limits_pattern[i].max ||
-+ value < probe_limits_pattern[i].min) {
-+ dev_dbg(&client->adapter->dev,
-+ "%s: register=%x, lim pattern=%d, value=%d\n",
-+ __FUNCTION__, probe_limits_pattern[i].reg,
-+ i, value);
-+
-+ return -ENODEV;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-+{
-+ return x1205_get_datetime(to_i2c_client(dev),
-+ &alrm->time, X1205_ALM0_BASE);
-+}
-+
-+static int x1205_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-+{
-+ return x1205_set_datetime(to_i2c_client(dev),
-+ &alrm->time, 1, X1205_ALM0_BASE);
-+}
-+
-+static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return x1205_get_datetime(to_i2c_client(dev),
-+ tm, X1205_CCR_BASE);
-+}
-+
-+static int x1205_rtc_set_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return x1205_set_datetime(to_i2c_client(dev),
-+ tm, 1, X1205_CCR_BASE);
-+}
-+
-+static int x1205_rtc_proc(struct device *dev, struct seq_file *seq)
-+{
-+ int err, dtrim, atrim;
-+
-+ seq_printf(seq, "24hr\t\t: yes\n");
-+
-+ if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0)
-+ seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim);
-+
-+ if ((err = x1205_get_atrim(to_i2c_client(dev), &atrim)) == 0)
-+ seq_printf(seq, "analog_trim\t: %d.%02d pF\n",
-+ atrim / 1000, atrim % 1000);
-+ return 0;
-+}
-+
-+static struct rtc_class_ops x1205_rtc_ops = {
-+ .proc = x1205_rtc_proc,
-+ .read_time = x1205_rtc_read_time,
-+ .set_time = x1205_rtc_set_time,
-+ .read_alarm = x1205_rtc_read_alarm,
-+ .set_alarm = x1205_rtc_set_alarm,
-+};
-+
-+static ssize_t x1205_sysfs_show_atrim(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ int atrim;
-+
-+ if (x1205_get_atrim(to_i2c_client(dev), &atrim) == 0)
-+ return sprintf(buf, "%d.%02d pF\n",
-+ atrim / 1000, atrim % 1000);
-+ return 0;
-+}
-+static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL);
-+
-+static ssize_t x1205_sysfs_show_dtrim(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ int dtrim;
-+
-+ if (x1205_get_dtrim(to_i2c_client(dev), &dtrim) == 0)
-+ return sprintf(buf, "%d ppm\n", dtrim);
-+
-+ return 0;
-+}
-+static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL);
-+
-+static int x1205_attach(struct i2c_adapter *adapter)
-+{
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+ return i2c_probe(adapter, &addr_data, x1205_probe);
-+}
-+
-+static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
-+{
-+ int err = 0;
-+ unsigned char sr;
-+ struct i2c_client *client;
-+ struct rtc_device *rtc;
-+
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-+ err = -ENODEV;
-+ goto exit;
-+ }
-+
-+ if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ /* I2C client */
-+ client->addr = address;
-+ client->driver = &x1205_driver;
-+ client->adapter = adapter;
-+
-+ strlcpy(client->name, x1205_driver.driver.name, I2C_NAME_SIZE);
-+
-+ /* Verify the chip is really an X1205 */
-+ if (kind < 0) {
-+ if (x1205_validate_client(client) < 0) {
-+ err = -ENODEV;
-+ goto exit_kfree;
-+ }
-+ }
-+
-+ /* Inform the i2c layer */
-+ if ((err = i2c_attach_client(client)))
-+ goto exit_kfree;
-+
-+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-+
-+ rtc = rtc_device_register(x1205_driver.driver.name, &client->dev,
-+ &x1205_rtc_ops, THIS_MODULE);
-+
-+ if (IS_ERR(rtc)) {
-+ err = PTR_ERR(rtc);
-+ dev_err(&client->dev,
-+ "unable to register the class device\n");
-+ goto exit_detach;
-+ }
-+
-+ i2c_set_clientdata(client, rtc);
-+
-+ /* Check for power failures and eventualy enable the osc */
-+ if ((err = x1205_get_status(client, &sr)) == 0) {
-+ if (sr & X1205_SR_RTCF) {
-+ dev_err(&client->dev,
-+ "power failure detected, "
-+ "please set the clock\n");
-+ udelay(50);
-+ x1205_fix_osc(client);
-+ }
-+ }
-+ else
-+ dev_err(&client->dev, "couldn't read status\n");
-+
-+ device_create_file(&client->dev, &dev_attr_atrim);
-+ device_create_file(&client->dev, &dev_attr_dtrim);
-+
-+ return 0;
-+
-+exit_detach:
-+ i2c_detach_client(client);
-+
-+exit_kfree:
-+ kfree(client);
-+
-+exit:
-+ return err;
-+}
-+
-+static int x1205_detach(struct i2c_client *client)
-+{
-+ int err;
-+ struct rtc_device *rtc = i2c_get_clientdata(client);
-+
-+ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-+
-+ if (rtc)
-+ rtc_device_unregister(rtc);
-+
-+ if ((err = i2c_detach_client(client)))
-+ return err;
-+
-+ kfree(client);
-+
-+ return 0;
-+}
-+
-+static int __init x1205_init(void)
-+{
-+ return i2c_add_driver(&x1205_driver);
-+}
-+
-+static void __exit x1205_exit(void)
-+{
-+ i2c_del_driver(&x1205_driver);
-+}
-+
-+MODULE_AUTHOR(
-+ "Karen Spearel <kas111 at gmail dot com>, "
-+ "Alessandro Zummo <a.zummo@towertech.it>");
-+MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-+
-+module_init(x1205_init);
-+module_exit(x1205_exit);
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ 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
-+ * 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/err.h>
-+#include <linux/rtc.h>
-+#include <linux/platform_device.h>
-+
-+static struct platform_device *test0 = NULL, *test1 = NULL;
-+
-+static int test_rtc_read_alarm(struct device *dev,
-+ struct rtc_wkalrm *alrm)
-+{
-+ return 0;
-+}
-+
-+static int test_rtc_set_alarm(struct device *dev,
-+ struct rtc_wkalrm *alrm)
-+{
-+ return 0;
-+}
-+
-+static int test_rtc_read_time(struct device *dev,
-+ struct rtc_time *tm)
-+{
-+ rtc_time_to_tm(get_seconds(), tm);
-+ return 0;
-+}
-+
-+static int test_rtc_set_time(struct device *dev,
-+ struct rtc_time *tm)
-+{
-+ return 0;
-+}
-+
-+static int test_rtc_set_mmss(struct device *dev, unsigned long secs)
-+{
-+ return 0;
-+}
-+
-+static int test_rtc_proc(struct device *dev, struct seq_file *seq)
-+{
-+ struct platform_device *plat_dev = to_platform_device(dev);
-+
-+ seq_printf(seq, "24hr\t\t: yes\n");
-+ seq_printf(seq, "test\t\t: yes\n");
-+ seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
-+
-+ return 0;
-+}
-+
-+static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ /* We do support interrupts, they're generated
-+ * using the sysfs interface.
-+ */
-+ switch (cmd) {
-+ case RTC_PIE_ON:
-+ case RTC_PIE_OFF:
-+ case RTC_UIE_ON:
-+ case RTC_UIE_OFF:
-+ case RTC_AIE_ON:
-+ case RTC_AIE_OFF:
-+ return 0;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static struct rtc_class_ops test_rtc_ops = {
-+ .proc = test_rtc_proc,
-+ .read_time = test_rtc_read_time,
-+ .set_time = test_rtc_set_time,
-+ .read_alarm = test_rtc_read_alarm,
-+ .set_alarm = test_rtc_set_alarm,
-+ .set_mmss = test_rtc_set_mmss,
-+ .ioctl = test_rtc_ioctl,
-+};
-+
-+static ssize_t test_irq_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ return sprintf(buf, "%d\n", 42);
-+}
-+static ssize_t test_irq_store(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int retval;
-+ struct platform_device *plat_dev = to_platform_device(dev);
-+ struct rtc_device *rtc = platform_get_drvdata(plat_dev);
-+
-+ retval = count;
-+ if (strncmp(buf, "tick", 4) == 0)
-+ rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
-+ else if (strncmp(buf, "alarm", 5) == 0)
-+ rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF);
-+ else if (strncmp(buf, "update", 6) == 0)
-+ rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
-+ else
-+ retval = -EINVAL;
-+
-+ return retval;
-+}
-+static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
-+
-+static int test_probe(struct platform_device *plat_dev)
-+{
-+ int err;
-+ struct rtc_device *rtc = rtc_device_register("test", &plat_dev->dev,
-+ &test_rtc_ops, THIS_MODULE);
-+ if (IS_ERR(rtc)) {
-+ err = PTR_ERR(rtc);
-+ dev_err(&plat_dev->dev,
-+ "unable to register the class device\n");
-+ return err;
-+ }
-+ device_create_file(&plat_dev->dev, &dev_attr_irq);
-+
-+ platform_set_drvdata(plat_dev, rtc);
-+
-+ return 0;
-+}
-+
-+static int __devexit test_remove(struct platform_device *plat_dev)
-+{
-+ struct rtc_device *rtc = platform_get_drvdata(plat_dev);
-+
-+ rtc_device_unregister(rtc);
-+ device_remove_file(&plat_dev->dev, &dev_attr_irq);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver test_drv = {
-+ .probe = test_probe,
-+ .remove = __devexit_p(test_remove),
-+ .driver = {
-+ .name = "rtc-test",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init test_init(void)
-+{
-+ int err;
-+
-+ if ((err = platform_driver_register(&test_drv)))
-+ return err;
-+
-+ if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) {
-+ err = -ENOMEM;
-+ goto exit_driver_unregister;
-+ }
-+
-+ if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) {
-+ err = -ENOMEM;
-+ goto exit_free_test0;
-+ }
-+
-+ if ((err = platform_device_add(test0)))
-+ goto exit_free_test1;
-+
-+ if ((err = platform_device_add(test1)))
-+ goto exit_device_unregister;
-+
-+ return 0;
-+
-+exit_device_unregister:
-+ platform_device_unregister(test0);
-+
-+exit_free_test1:
-+ platform_device_put(test1);
-+
-+exit_free_test0:
-+ platform_device_put(test0);
-+
-+exit_driver_unregister:
-+ platform_driver_unregister(&test_drv);
-+ return err;
-+}
-+
-+static void __exit test_exit(void)
-+{
-+ platform_device_unregister(test0);
-+ platform_device_unregister(test1);
-+ platform_driver_unregister(&test_drv);
-+}
-+
-+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-+MODULE_DESCRIPTION("RTC test driver/device");
-+MODULE_LICENSE("GPL");
-+
-+module_init(test_init);
-+module_exit(test_exit);
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ 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
-+ * Copyright 2005 Alessandro Zummo
-+ *
-+ * 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/i2c.h>
-+#include <linux/rtc.h>
-+
-+#define DRV_VERSION "0.2"
-+
-+/* Addresses to scan: none. This chip cannot be detected. */
-+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-+
-+/* Insmod parameters */
-+I2C_CLIENT_INSMOD;
-+
-+/* Registers */
-+
-+#define DS1672_REG_CNT_BASE 0
-+#define DS1672_REG_CONTROL 4
-+#define DS1672_REG_TRICKLE 5
-+
-+
-+/* Prototypes */
-+static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind);
-+
-+/*
-+ * In the routines that deal directly with the ds1672 hardware, we use
-+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
-+ * Epoch is initialized as 2000. Time is set to UTC.
-+ */
-+static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
-+{
-+ unsigned long time;
-+ unsigned char addr = DS1672_REG_CNT_BASE;
-+ unsigned char buf[4];
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 1, &addr }, /* setup read ptr */
-+ { 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;
-+ }
-+
-+ dev_dbg(&client->dev,
-+ "%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
-+ __FUNCTION__,
-+ buf[0], buf[1], buf[2], buf[3]);
-+
-+ time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
-+
-+ rtc_time_to_tm(time, tm);
-+
-+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ return 0;
-+}
-+
-+static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
-+{
-+ int xfer;
-+ unsigned char buf[5];
-+
-+ buf[0] = DS1672_REG_CNT_BASE;
-+ buf[1] = secs & 0x000000FF;
-+ buf[2] = (secs & 0x0000FF00) >> 8;
-+ buf[3] = (secs & 0x00FF0000) >> 16;
-+ buf[4] = (secs & 0xFF000000) >> 24;
-+
-+ xfer = i2c_master_send(client, buf, 5);
-+ if (xfer != 5) {
-+ dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm)
-+{
-+ unsigned long secs;
-+
-+ dev_dbg(&client->dev,
-+ "%s: secs=%d, mins=%d, hours=%d, ",
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ rtc_tm_to_time(tm, &secs);
-+
-+ return ds1672_set_mmss(client, secs);
-+}
-+
-+static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return ds1672_get_datetime(to_i2c_client(dev), tm);
-+}
-+
-+static int ds1672_rtc_set_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return ds1672_set_datetime(to_i2c_client(dev), tm);
-+}
-+
-+static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs)
-+{
-+ return ds1672_set_mmss(to_i2c_client(dev), secs);
-+}
-+
-+static struct rtc_class_ops ds1672_rtc_ops = {
-+ .read_time = ds1672_rtc_read_time,
-+ .set_time = ds1672_rtc_set_time,
-+ .set_mmss = ds1672_rtc_set_mmss,
-+};
-+
-+static int ds1672_attach(struct i2c_adapter *adapter)
-+{
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+ return i2c_probe(adapter, &addr_data, ds1672_probe);
-+}
-+
-+static int ds1672_detach(struct i2c_client *client)
-+{
-+ int err;
-+ struct rtc_device *rtc = i2c_get_clientdata(client);
-+
-+ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-+
-+ if (rtc)
-+ rtc_device_unregister(rtc);
-+
-+ if ((err = i2c_detach_client(client)))
-+ return err;
-+
-+ kfree(client);
-+
-+ return 0;
-+}
-+
-+static struct i2c_driver ds1672_driver = {
-+ .driver = {
-+ .name = "ds1672",
-+ },
-+ .attach_adapter = &ds1672_attach,
-+ .detach_client = &ds1672_detach,
-+};
-+
-+static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
-+{
-+ int err = 0;
-+ struct i2c_client *client;
-+ struct rtc_device *rtc;
-+
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-+ err = -ENODEV;
-+ goto exit;
-+ }
-+
-+ if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ /* I2C client */
-+ client->addr = address;
-+ client->driver = &ds1672_driver;
-+ client->adapter = adapter;
-+
-+ strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE);
-+
-+ /* Inform the i2c layer */
-+ if ((err = i2c_attach_client(client)))
-+ goto exit_kfree;
-+
-+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-+
-+ rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
-+ &ds1672_rtc_ops, THIS_MODULE);
-+
-+ if (IS_ERR(rtc)) {
-+ err = PTR_ERR(rtc);
-+ dev_err(&client->dev,
-+ "unable to register the class device\n");
-+ goto exit_detach;
-+ }
-+
-+ i2c_set_clientdata(client, rtc);
-+
-+ return 0;
-+
-+exit_detach:
-+ i2c_detach_client(client);
-+
-+exit_kfree:
-+ kfree(client);
-+
-+exit:
-+ return err;
-+}
-+
-+static int __init ds1672_init(void)
-+{
-+ return i2c_add_driver(&ds1672_driver);
-+}
-+
-+static void __exit ds1672_exit(void)
-+{
-+ i2c_del_driver(&ds1672_driver);
-+}
-+
-+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-+MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-+
-+module_init(ds1672_init);
-+module_exit(ds1672_exit);
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ 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
-+ * Copyright 2005-06 Tower Technologies
-+ *
-+ * Author: Alessandro Zummo <a.zummo@towertech.it>
-+ * Maintainers: http://www.nslu2-linux.org/
-+ *
-+ * based on the other drivers in this same directory.
-+ *
-+ * http://www.semiconductors.philips.com/acrobat/datasheets/PCF8563-04.pdf
-+ *
-+ * 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/i2c.h>
-+#include <linux/bcd.h>
-+#include <linux/rtc.h>
-+
-+#define DRV_VERSION "0.4.2"
-+
-+/* Addresses to scan: none
-+ * This chip cannot be reliably autodetected. An empty eeprom
-+ * located at 0x51 will pass the validation routine due to
-+ * the way the registers are implemented.
-+ */
-+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-+
-+/* Module parameters */
-+I2C_CLIENT_INSMOD;
-+
-+#define PCF8563_REG_ST1 0x00 /* status */
-+#define PCF8563_REG_ST2 0x01
-+
-+#define PCF8563_REG_SC 0x02 /* datetime */
-+#define PCF8563_REG_MN 0x03
-+#define PCF8563_REG_HR 0x04
-+#define PCF8563_REG_DM 0x05
-+#define PCF8563_REG_DW 0x06
-+#define PCF8563_REG_MO 0x07
-+#define PCF8563_REG_YR 0x08
-+
-+#define PCF8563_REG_AMN 0x09 /* alarm */
-+#define PCF8563_REG_AHR 0x0A
-+#define PCF8563_REG_ADM 0x0B
-+#define PCF8563_REG_ADW 0x0C
-+
-+#define PCF8563_REG_CLKO 0x0D /* clock out */
-+#define PCF8563_REG_TMRC 0x0E /* timer control */
-+#define PCF8563_REG_TMR 0x0F /* timer */
-+
-+#define PCF8563_SC_LV 0x80 /* low voltage */
-+#define PCF8563_MO_C 0x80 /* century */
-+
-+/* Prototypes */
-+static int pcf8563_attach(struct i2c_adapter *adapter);
-+static int pcf8563_detach(struct i2c_client *client);
-+static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
-+
-+static struct i2c_driver pcf8563_driver = {
-+ .driver = {
-+ .name = "pcf8563",
-+ },
-+ .attach_adapter = &pcf8563_attach,
-+ .detach_client = &pcf8563_detach,
-+};
-+
-+/*
-+ * In the routines that deal directly with the pcf8563 hardware, we use
-+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
-+ */
-+static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
-+{
-+ unsigned char buf[13] = { PCF8563_REG_ST1 };
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 1, buf }, /* setup read ptr */
-+ { client->addr, I2C_M_RD, 13, buf }, /* read status + date */
-+ };
-+
-+ /* read registers */
-+ if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
-+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-+ return -EIO;
-+ }
-+
-+ if (buf[PCF8563_REG_SC] & PCF8563_SC_LV)
-+ dev_info(&client->dev,
-+ "low voltage detected, date/time is not reliable.\n");
-+
-+ dev_dbg(&client->dev,
-+ "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, "
-+ "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
-+ __FUNCTION__,
-+ buf[0], buf[1], buf[2], buf[3],
-+ buf[4], buf[5], buf[6], buf[7],
-+ buf[8]);
-+
-+
-+ tm->tm_sec = BCD2BIN(buf[PCF8563_REG_SC] & 0x7F);
-+ tm->tm_min = BCD2BIN(buf[PCF8563_REG_MN] & 0x7F);
-+ tm->tm_hour = BCD2BIN(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
-+ tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
-+ tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
-+ tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
-+ tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
-+ + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0);
-+
-+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ /* the clock can give out invalid datetime, but we cannot return
-+ * -EINVAL otherwise hwclock will refuse to set the time on bootup.
-+ */
-+ if (rtc_valid_tm(tm) < 0)
-+ dev_err(&client->dev, "retrieved date/time is not valid.\n");
-+
-+ return 0;
-+}
-+
-+static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
-+{
-+ int i, err;
-+ unsigned char buf[9];
-+
-+ dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ /* hours, minutes and seconds */
-+ buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec);
-+ buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min);
-+ buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour);
-+
-+ buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday);
-+
-+ /* month, 1 - 12 */
-+ buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1);
-+
-+ /* year and century */
-+ buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
-+ if (tm->tm_year / 100)
-+ buf[PCF8563_REG_MO] |= PCF8563_MO_C;
-+
-+ buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
-+
-+ /* write register's data */
-+ for (i = 0; i < 7; i++) {
-+ unsigned char data[2] = { PCF8563_REG_SC + i,
-+ buf[PCF8563_REG_SC + i] };
-+
-+ err = i2c_master_send(client, data, sizeof(data));
-+ if (err != sizeof(data)) {
-+ dev_err(&client->dev,
-+ "%s: err=%d addr=%02x, data=%02x\n",
-+ __FUNCTION__, err, data[0], data[1]);
-+ return -EIO;
-+ }
-+ };
-+
-+ return 0;
-+}
-+
-+struct pcf8563_limit
-+{
-+ unsigned char reg;
-+ unsigned char mask;
-+ unsigned char min;
-+ unsigned char max;
-+};
-+
-+static int pcf8563_validate_client(struct i2c_client *client)
-+{
-+ int i;
-+
-+ static const struct pcf8563_limit pattern[] = {
-+ /* register, mask, min, max */
-+ { PCF8563_REG_SC, 0x7F, 0, 59 },
-+ { PCF8563_REG_MN, 0x7F, 0, 59 },
-+ { PCF8563_REG_HR, 0x3F, 0, 23 },
-+ { PCF8563_REG_DM, 0x3F, 0, 31 },
-+ { PCF8563_REG_MO, 0x1F, 0, 12 },
-+ };
-+
-+ /* check limits (only registers with bcd values) */
-+ for (i = 0; i < ARRAY_SIZE(pattern); i++) {
-+ int xfer;
-+ unsigned char value;
-+ unsigned char buf = pattern[i].reg;
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 1, &buf },
-+ { client->addr, I2C_M_RD, 1, &buf },
-+ };
-+
-+ xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-+
-+ if (xfer != ARRAY_SIZE(msgs)) {
-+ dev_err(&client->adapter->dev,
-+ "%s: could not read register 0x%02X\n",
-+ __FUNCTION__, pattern[i].reg);
-+
-+ return -EIO;
-+ }
-+
-+ value = BCD2BIN(buf & pattern[i].mask);
-+
-+ if (value > pattern[i].max ||
-+ value < pattern[i].min) {
-+ dev_dbg(&client->adapter->dev,
-+ "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, "
-+ "max=%d, value=%d, raw=0x%02X\n",
-+ __FUNCTION__, i, pattern[i].reg, pattern[i].mask,
-+ pattern[i].min, pattern[i].max,
-+ value, buf);
-+
-+ return -ENODEV;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return pcf8563_get_datetime(to_i2c_client(dev), tm);
-+}
-+
-+static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return pcf8563_set_datetime(to_i2c_client(dev), tm);
-+}
-+
-+static int pcf8563_rtc_proc(struct device *dev, struct seq_file *seq)
-+{
-+ seq_printf(seq, "24hr\t\t: yes\n");
-+ return 0;
-+}
-+
-+static struct rtc_class_ops pcf8563_rtc_ops = {
-+ .proc = pcf8563_rtc_proc,
-+ .read_time = pcf8563_rtc_read_time,
-+ .set_time = pcf8563_rtc_set_time,
-+};
-+
-+static int pcf8563_attach(struct i2c_adapter *adapter)
-+{
-+ return i2c_probe(adapter, &addr_data, pcf8563_probe);
-+}
-+
-+static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
-+{
-+ struct i2c_client *client;
-+ struct rtc_device *rtc;
-+
-+ int err = 0;
-+
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-+ err = -ENODEV;
-+ goto exit;
-+ }
-+
-+ if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ client->addr = address;
-+ client->driver = &pcf8563_driver;
-+ client->adapter = adapter;
-+
-+ strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
-+
-+ /* Verify the chip is really an PCF8563 */
-+ if (kind < 0) {
-+ if (pcf8563_validate_client(client) < 0) {
-+ err = -ENODEV;
-+ goto exit_kfree;
-+ }
-+ }
-+
-+ /* Inform the i2c layer */
-+ if ((err = i2c_attach_client(client)))
-+ goto exit_kfree;
-+
-+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-+
-+ rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
-+ &pcf8563_rtc_ops, THIS_MODULE);
-+
-+ if (IS_ERR(rtc)) {
-+ err = PTR_ERR(rtc);
-+ dev_err(&client->dev,
-+ "unable to register the class device\n");
-+ goto exit_detach;
-+ }
-+
-+ i2c_set_clientdata(client, rtc);
-+
-+ return 0;
-+
-+exit_detach:
-+ i2c_detach_client(client);
-+
-+exit_kfree:
-+ kfree(client);
-+
-+exit:
-+ return err;
-+}
-+
-+static int pcf8563_detach(struct i2c_client *client)
-+{
-+ int err;
-+ struct rtc_device *rtc = i2c_get_clientdata(client);
-+
-+ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-+
-+ if (rtc)
-+ rtc_device_unregister(rtc);
-+
-+ if ((err = i2c_detach_client(client)))
-+ return err;
-+
-+ kfree(client);
-+
-+ return 0;
-+}
-+
-+static int __init pcf8563_init(void)
-+{
-+ return i2c_add_driver(&pcf8563_driver);
-+}
-+
-+static void __exit pcf8563_exit(void)
-+{
-+ i2c_del_driver(&pcf8563_driver);
-+}
-+
-+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-+MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-+
-+module_init(pcf8563_init);
-+module_exit(pcf8563_exit);
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ 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
-+ *
-+ * Copyright (C) 2005 Pavel Mironchik pmironchik@optifacio.net
-+ * Copyright (C) 2006 Tower Technologies
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/i2c.h>
-+#include <linux/rtc.h>
-+#include <linux/bcd.h>
-+
-+#define DRV_VERSION "0.2"
-+
-+/* Addresses to scan */
-+static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END };
-+
-+/* Insmod parameters */
-+I2C_CLIENT_INSMOD;
-+
-+#define RS5C372_REG_SECS 0
-+#define RS5C372_REG_MINS 1
-+#define RS5C372_REG_HOURS 2
-+#define RS5C372_REG_WDAY 3
-+#define RS5C372_REG_DAY 4
-+#define RS5C372_REG_MONTH 5
-+#define RS5C372_REG_YEAR 6
-+#define RS5C372_REG_TRIM 7
-+
-+#define RS5C372_TRIM_XSL 0x80
-+#define RS5C372_TRIM_MASK 0x7F
-+
-+#define RS5C372_REG_BASE 0
-+
-+static int rs5c372_attach(struct i2c_adapter *adapter);
-+static int rs5c372_detach(struct i2c_client *client);
-+static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind);
-+
-+static struct i2c_driver rs5c372_driver = {
-+ .driver = {
-+ .name = "rs5c372",
-+ },
-+ .attach_adapter = &rs5c372_attach,
-+ .detach_client = &rs5c372_detach,
-+};
-+
-+static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
-+{
-+ unsigned char buf[7] = { RS5C372_REG_BASE };
-+
-+ /* this implements the 1st reading method, according
-+ * to the datasheet. buf[0] is initialized with
-+ * address ptr and transmission format register.
-+ */
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 1, buf },
-+ { client->addr, I2C_M_RD, 7, buf },
-+ };
-+
-+ if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
-+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-+ return -EIO;
-+ }
-+
-+ tm->tm_sec = BCD2BIN(buf[RS5C372_REG_SECS] & 0x7f);
-+ tm->tm_min = BCD2BIN(buf[RS5C372_REG_MINS] & 0x7f);
-+ tm->tm_hour = BCD2BIN(buf[RS5C372_REG_HOURS] & 0x3f);
-+ tm->tm_wday = BCD2BIN(buf[RS5C372_REG_WDAY] & 0x07);
-+ tm->tm_mday = BCD2BIN(buf[RS5C372_REG_DAY] & 0x3f);
-+
-+ /* tm->tm_mon is zero-based */
-+ tm->tm_mon = BCD2BIN(buf[RS5C372_REG_MONTH] & 0x1f) - 1;
-+
-+ /* year is 1900 + tm->tm_year */
-+ tm->tm_year = BCD2BIN(buf[RS5C372_REG_YEAR]) + 100;
-+
-+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ return 0;
-+}
-+
-+static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
-+{
-+ unsigned char buf[8] = { RS5C372_REG_BASE };
-+
-+ dev_dbg(&client->dev,
-+ "%s: secs=%d, mins=%d, hours=%d ",
-+ "mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ buf[1] = BIN2BCD(tm->tm_sec);
-+ buf[2] = BIN2BCD(tm->tm_min);
-+ buf[3] = BIN2BCD(tm->tm_hour);
-+ buf[4] = BIN2BCD(tm->tm_wday);
-+ buf[5] = BIN2BCD(tm->tm_mday);
-+ buf[6] = BIN2BCD(tm->tm_mon + 1);
-+ buf[7] = BIN2BCD(tm->tm_year - 100);
-+
-+ if ((i2c_master_send(client, buf, 8)) != 8) {
-+ dev_err(&client->dev, "%s: write error\n", __FUNCTION__);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
-+{
-+ unsigned char buf = RS5C372_REG_TRIM;
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 1, &buf },
-+ { client->addr, I2C_M_RD, 1, &buf },
-+ };
-+
-+ if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
-+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-+ return -EIO;
-+ }
-+
-+ dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, trim);
-+
-+ if (osc)
-+ *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
-+
-+ if (trim)
-+ *trim = buf & RS5C372_TRIM_MASK;
-+
-+ return 0;
-+}
-+
-+static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return rs5c372_get_datetime(to_i2c_client(dev), tm);
-+}
-+
-+static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return rs5c372_set_datetime(to_i2c_client(dev), tm);
-+}
-+
-+static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
-+{
-+ int err, osc, trim;
-+
-+ seq_printf(seq, "24hr\t\t: yes\n");
-+
-+ if ((err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim)) == 0) {
-+ seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000);
-+ seq_printf(seq, "trim\t: %d\n", trim);
-+ }
-+
-+ return 0;
-+}
-+
-+static struct rtc_class_ops rs5c372_rtc_ops = {
-+ .proc = rs5c372_rtc_proc,
-+ .read_time = rs5c372_rtc_read_time,
-+ .set_time = rs5c372_rtc_set_time,
-+};
-+
-+static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ int trim;
-+
-+ if (rs5c372_get_trim(to_i2c_client(dev), NULL, &trim) == 0)
-+ return sprintf(buf, "0x%2x\n", trim);
-+
-+ return 0;
-+}
-+static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL);
-+
-+static ssize_t rs5c372_sysfs_show_osc(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ int osc;
-+
-+ if (rs5c372_get_trim(to_i2c_client(dev), &osc, NULL) == 0)
-+ return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000);
-+
-+ return 0;
-+}
-+static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL);
-+
-+static int rs5c372_attach(struct i2c_adapter *adapter)
-+{
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+ return i2c_probe(adapter, &addr_data, rs5c372_probe);
-+}
-+
-+static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
-+{
-+ int err = 0;
-+ struct i2c_client *client;
-+ struct rtc_device *rtc;
-+
-+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-+ err = -ENODEV;
-+ goto exit;
-+ }
-+
-+ if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ /* I2C client */
-+ client->addr = address;
-+ client->driver = &rs5c372_driver;
-+ client->adapter = adapter;
-+
-+ strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE);
-+
-+ /* Inform the i2c layer */
-+ if ((err = i2c_attach_client(client)))
-+ goto exit_kfree;
-+
-+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-+
-+ rtc = rtc_device_register(rs5c372_driver.driver.name, &client->dev,
-+ &rs5c372_rtc_ops, THIS_MODULE);
-+
-+ if (IS_ERR(rtc)) {
-+ err = PTR_ERR(rtc);
-+ dev_err(&client->dev,
-+ "unable to register the class device\n");
-+ goto exit_detach;
-+ }
-+
-+ i2c_set_clientdata(client, rtc);
-+
-+ device_create_file(&client->dev, &dev_attr_trim);
-+ device_create_file(&client->dev, &dev_attr_osc);
-+
-+ return 0;
-+
-+exit_detach:
-+ i2c_detach_client(client);
-+
-+exit_kfree:
-+ kfree(client);
-+
-+exit:
-+ return err;
-+}
-+
-+static int rs5c372_detach(struct i2c_client *client)
-+{
-+ int err;
-+ struct rtc_device *rtc = i2c_get_clientdata(client);
-+
-+ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-+
-+ if (rtc)
-+ rtc_device_unregister(rtc);
-+
-+ if ((err = i2c_detach_client(client)))
-+ return err;
-+
-+ kfree(client);
-+
-+ return 0;
-+}
-+
-+static __init int rs5c372_init(void)
-+{
-+ return i2c_add_driver(&rs5c372_driver);
-+}
-+
-+static __exit void rs5c372_exit(void)
-+{
-+ i2c_del_driver(&rs5c372_driver);
-+}
-+
-+module_init(rs5c372_init);
-+module_exit(rs5c372_exit);
-+
-+MODULE_AUTHOR(
-+ "Pavel Mironchik <pmironchik@optifacio.net>, "
-+ "Alessandro Zummo <a.zummo@towertech.it>");
-+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)