diff options
Diffstat (limited to 'packages/linux/linux-ezx/sa1100_rtc.patch')
-rw-r--r-- | packages/linux/linux-ezx/sa1100_rtc.patch | 604 |
1 files changed, 0 insertions, 604 deletions
diff --git a/packages/linux/linux-ezx/sa1100_rtc.patch b/packages/linux/linux-ezx/sa1100_rtc.patch deleted file mode 100644 index 8b4ba95407..0000000000 --- a/packages/linux/linux-ezx/sa1100_rtc.patch +++ /dev/null @@ -1,604 +0,0 @@ -Support for the SA1100 / PXA RTC - -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/char/Kconfig linux-2.6.16.5-exz/drivers/char/Kconfig ---- linux-2.6.16.5/drivers/char/Kconfig 2006-04-12 22:27:57.000000000 +0200 -+++ linux-2.6.16.5-exz/drivers/char/Kconfig 2006-04-16 18:52:24.000000000 +0200 -@@ -696,7 +696,7 @@ - - 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 && !ARCH_PXA - ---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 -@@ -742,6 +742,19 @@ - via the file /proc/rtc and its behaviour is set by various ioctls on - /dev/rtc. - -+config SA1100_RTC -+ bool "SA11x0/PXA2xx RTC support" -+ depends on ARCH_SA1100 || ARCH_PXA -+ 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 -+ will get access to the real time clock built into your SA11x0 or -+ PXA2xx CPU. It reports status information via the file /proc/rtc -+ and its behaviour is set by various ioctls on /dev/rtc. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called sa1100-rtc. -+ - config GEN_RTC - tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/char/Makefile linux-2.6.16.5-exz/drivers/char/Makefile ---- linux-2.6.16.5/drivers/char/Makefile 2006-04-12 22:27:57.000000000 +0200 -+++ linux-2.6.16.5-exz/drivers/char/Makefile 2006-04-16 18:49:29.000000000 +0200 -@@ -61,6 +61,7 @@ - obj-$(CONFIG_HPET) += hpet.o - obj-$(CONFIG_GEN_RTC) += genrtc.o - obj-$(CONFIG_EFI_RTC) += efirtc.o -+obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o - obj-$(CONFIG_SGI_DS1286) += ds1286.o - obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o - obj-$(CONFIG_DS1302) += ds1302.o -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/char/sa1100-rtc.c linux-2.6.16.5-exz/drivers/char/sa1100-rtc.c ---- linux-2.6.16.5/drivers/char/sa1100-rtc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/char/sa1100-rtc.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,554 @@ -+/* -+ * linux/drivers/char/sa1100-rtc.c -+ * -+ * Real Time Clock interface for Linux on StrongARM SA1x00 -+ * (and XScale PXA2xx which shares the same RTC register definitions) -+ * -+ * Copyright (c) 2000 Nils Faerber -+ * -+ * Based on rtc.c by Paul Gortmaker -+ * -+ * 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. -+ * -+ * 1.02 2002-07-15 Andrew Christian <andrew.christian@hp.com> -+ * - added pm_ routines to shut off extraneous interrupts while asleep -+ * -+ * 1.01 2002-07-09 Nils Faerber <nils@kernelconcepts.de> -+ * - fixed rtc_poll() so that select() now works -+ * -+ * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org> -+ * - added periodic timer capability using OSMR1 -+ * - flag compatibility with other RTC chips -+ * - permission checks for ioctls -+ * - major cleanup, partial rewrite -+ * -+ * 0.03 2001-03-07 CIH <cih@coventive.com> -+ * - Modify the bug setups RTC clock. -+ * -+ * 0.02 2001-02-27 Nils Faerber <nils@kernelconcepts.de> -+ * - removed mktime(), added alarm irq clear -+ * -+ * 0.01 2000-10-01 Nils Faerber <nils@kernelconcepts.de> -+ * - initial release -+ */ -+ -+#include <linux/config.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <linux/miscdevice.h> -+#include <linux/interrupt.h> -+#include <linux/poll.h> -+#include <linux/proc_fs.h> -+#include <linux/string.h> -+#include <linux/rtc.h> -+#include <linux/pm.h> -+ -+#include <asm/bitops.h> -+#include <asm/hardware.h> -+#include <asm/irq.h> -+ -+#ifdef CONFIG_ARCH_PXA -+#include <asm/arch/pxa-regs.h> -+#endif -+ -+#define DRIVER_VERSION "1.02" -+ -+#define TIMER_FREQ CLOCK_TICK_RATE -+ -+#define RTC_DEF_DIVIDER 32768 - 1 -+#define RTC_DEF_TRIM 0 -+ -+/* Those are the bits from a classic RTC we want to mimic */ -+#define RTC_IRQF 0x80 /* any of the following 3 is active */ -+#define RTC_PF 0x40 -+#define RTC_AF 0x20 -+#define RTC_UF 0x10 -+ -+static unsigned long rtc_status; -+static unsigned long rtc_irq_data; -+static unsigned long rtc_freq = 1024; -+ -+static struct fasync_struct *rtc_async_queue; -+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); -+ -+extern spinlock_t rtc_lock; -+ -+static const unsigned char days_in_mo[] = -+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -+ -+#define is_leap(year) \ -+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) -+ -+/* Converts seconds since 1970-01-01 00:00:00 to Gregorian date. */ -+static void decodetime (unsigned long t, struct rtc_time *tval) -+{ -+ long days, month, year, rem; -+ -+ days = t / 86400; -+ rem = t % 86400; -+ tval->tm_hour = rem / 3600; -+ rem %= 3600; -+ tval->tm_min = rem / 60; -+ tval->tm_sec = rem % 60; -+ tval->tm_wday = (4 + days) % 7; -+ -+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -+ -+ 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 + is_leap(year); -+ } -+ tval->tm_year = year - 1900; -+ tval->tm_yday = days + 1; -+ -+ month = 0; -+ if (days >= 31) { -+ days -= 31; -+ month++; -+ if (days >= (28 + is_leap(year))) { -+ days -= (28 + is_leap(year)); -+ month++; -+ while (days >= days_in_mo[month]) { -+ days -= days_in_mo[month]; -+ month++; -+ } -+ } -+ } -+ tval->tm_mon = month; -+ tval->tm_mday = days + 1; -+} -+ -+static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ unsigned int rtsr = RTSR; -+ -+ /* clear interrupt sources */ -+ RTSR = 0; -+ RTSR = (RTSR_AL|RTSR_HZ); -+ -+ /* 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) -+ rtc_irq_data |= (RTC_AF|RTC_IRQF); -+ if (rtsr & RTSR_HZ) -+ rtc_irq_data |= (RTC_UF|RTC_IRQF); -+ rtc_irq_data += 0x100; -+ -+ /* wake up waiting process */ -+ wake_up_interruptible(&rtc_wait); -+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ /* -+ * If we match for the first time, the periodic interrupt flag won't -+ * be set. If it is, then we did wrap around (very unlikely but -+ * still possible) and 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 */ -+ if (rtc_irq_data & RTC_PF) { -+ rtc_irq_data += (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))) << 8; -+ } else { -+ rtc_irq_data += (0x100|RTC_PF|RTC_IRQF); -+ } -+ -+ wake_up_interruptible(&rtc_wait); -+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); -+ return IRQ_HANDLED; -+} -+ -+static int rtc_open(struct inode *inode, struct file *file) -+{ -+ if (test_and_set_bit (1, &rtc_status)) -+ return -EBUSY; -+ rtc_irq_data = 0; -+ return 0; -+} -+ -+static int rtc_release(struct inode *inode, struct file *file) -+{ -+ spin_lock_irq (&rtc_lock); -+ RTSR = 0; -+ RTSR = (RTSR_AL|RTSR_HZ); -+ OIER &= ~OIER_E1; -+ OSSR = OSSR_M1; -+ spin_unlock_irq (&rtc_lock); -+ rtc_status = 0; -+ return 0; -+} -+ -+static int rtc_fasync (int fd, struct file *filp, int on) -+{ -+ return fasync_helper (fd, filp, on, &rtc_async_queue); -+} -+ -+static unsigned int rtc_poll(struct file *file, poll_table *wait) -+{ -+ poll_wait (file, &rtc_wait, wait); -+ return (rtc_irq_data) ? POLLIN | POLLRDNORM : 0; -+} -+ -+ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned long data; -+ ssize_t retval; -+ -+ if (count < sizeof(unsigned long)) -+ return -EINVAL; -+ -+ add_wait_queue(&rtc_wait, &wait); -+ set_current_state(TASK_INTERRUPTIBLE); -+ for (;;) { -+ spin_lock_irq (&rtc_lock); -+ data = rtc_irq_data; -+ if (data != 0) { -+ rtc_irq_data = 0; -+ break; -+ } -+ spin_unlock_irq (&rtc_lock); -+ -+ if (file->f_flags & O_NONBLOCK) { -+ retval = -EAGAIN; -+ goto out; -+ } -+ -+ if (signal_pending(current)) { -+ retval = -ERESTARTSYS; -+ goto out; -+ } -+ -+ schedule(); -+ } -+ -+ if (data & RTC_PF) { -+ /* interpolate missed periods and set match for the next one */ -+ 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) against 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; -+ } -+ } -+ spin_unlock_irq (&rtc_lock); -+ -+ data -= 0x100; /* the first IRQ wasn't actually missed */ -+ -+ retval = put_user(data, (unsigned long *)buf); -+ if (!retval) -+ retval = sizeof(unsigned long); -+ -+out: -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&rtc_wait, &wait); -+ return retval; -+} -+ -+static int rtc_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct rtc_time tm, tm2; -+ -+ switch (cmd) { -+ case RTC_AIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ RTSR &= ~RTSR_ALE; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_AIE_ON: -+ spin_lock_irq(&rtc_lock); -+ RTSR |= RTSR_ALE; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_UIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ RTSR &= ~RTSR_HZE; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_UIE_ON: -+ spin_lock_irq(&rtc_lock); -+ RTSR |= RTSR_HZE; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_PIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ OIER &= ~OIER_E1; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_PIE_ON: -+ if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE)) -+ return -EACCES; -+ spin_lock_irq(&rtc_lock); -+ OSMR1 = TIMER_FREQ/rtc_freq + OSCR; -+ OIER |= OIER_E1; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_ALM_READ: -+ decodetime (RTAR, &tm); -+ break; -+ case RTC_ALM_SET: -+ if (copy_from_user (&tm2, (struct rtc_time*)arg, sizeof (tm2))) -+ return -EFAULT; -+ decodetime (RCNR, &tm); -+ if ((unsigned)tm2.tm_hour < 24) -+ tm.tm_hour = tm2.tm_hour; -+ if ((unsigned)tm2.tm_min < 60) -+ tm.tm_min = tm2.tm_min; -+ if ((unsigned)tm2.tm_sec < 60) -+ tm.tm_sec = tm2.tm_sec; -+ RTAR = mktime ( tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -+ tm.tm_hour, tm.tm_min, tm.tm_sec); -+ return 0; -+ case RTC_RD_TIME: -+ decodetime (RCNR, &tm); -+ break; -+ case RTC_SET_TIME: -+ if (!capable(CAP_SYS_TIME)) -+ return -EACCES; -+ if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) -+ return -EFAULT; -+ tm.tm_year += 1900; -+ if (tm.tm_year < 1970 || (unsigned)tm.tm_mon >= 12 || -+ tm.tm_mday < 1 || tm.tm_mday > (days_in_mo[tm.tm_mon] + -+ (tm.tm_mon == 1 && is_leap(tm.tm_year))) || -+ (unsigned)tm.tm_hour >= 24 || -+ (unsigned)tm.tm_min >= 60 || -+ (unsigned)tm.tm_sec >= 60) -+ return -EINVAL; -+ RCNR = mktime ( tm.tm_year, tm.tm_mon + 1, tm.tm_mday, -+ tm.tm_hour, tm.tm_min, tm.tm_sec); -+ 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; -+ case RTC_EPOCH_READ: -+ return put_user (1970, (unsigned long *)arg); -+ default: -+ return -EINVAL; -+ } -+ return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0; -+} -+ -+static struct file_operations rtc_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .read = rtc_read, -+ .poll = rtc_poll, -+ .ioctl = rtc_ioctl, -+ .open = rtc_open, -+ .release = rtc_release, -+ .fasync = rtc_fasync, -+}; -+ -+static struct miscdevice sa1100rtc_miscdev = { -+ .minor = RTC_MINOR, -+ .name = "rtc", -+ .fops = &rtc_fops -+}; -+ -+static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ char *p = page; -+ int len; -+ struct rtc_time tm; -+ -+ decodetime (RCNR, &tm); -+ p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n" -+ "rtc_date\t: %04d-%02d-%02d\n" -+ "rtc_epoch\t: %04d\n", -+ tm.tm_hour, tm.tm_min, tm.tm_sec, -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1970); -+ decodetime (RTAR, &tm); -+ p += sprintf(p, "alrm_time\t: %02d:%02d:%02d\n" -+ "alrm_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); -+ p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR); -+ p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" ); -+ p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no"); -+ p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no"); -+ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq); -+ -+ len = (p - page) - off; -+ if (len < 0) -+ len = 0; -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+/* let's use the write interface for modifying RTTR */ -+static int rtc_write_proc(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ if (count > 15) -+ return -EINVAL; -+ if (count > 0) { -+ char lbuf[16]; -+ if (copy_from_user(lbuf, buffer, count)) -+ return -EFAULT; -+ lbuf[count] = 0; -+ RTTR = simple_strtoul(lbuf, NULL, 0); -+ } -+ return count; -+} -+ -+static int rtc_setup_interrupts(void) -+{ -+ int ret; -+ -+ ret = request_irq (IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL); -+ if (ret) { -+ printk (KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_RTC1Hz); -+ goto IRQ_RTC1Hz_failed; -+ } -+ ret = request_irq (IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_RTCAlrm); -+ goto IRQ_RTCAlrm_failed; -+ } -+ ret = request_irq (IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_OST1); -+ goto IRQ_OST1_failed; -+ } -+ -+ return 0; -+ -+IRQ_OST1_failed: -+ free_irq (IRQ_RTCAlrm, NULL); -+IRQ_RTCAlrm_failed: -+ free_irq (IRQ_RTC1Hz, NULL); -+IRQ_RTC1Hz_failed: -+ return ret; -+} -+ -+static void rtc_free_interrupts(void) -+{ -+ free_irq (IRQ_OST1, NULL); -+ free_irq (IRQ_RTCAlrm, NULL); -+ free_irq (IRQ_RTC1Hz, NULL); -+} -+ -+static struct pm_dev *rtc_pm_dev; -+ -+static int rtc_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ static int suspended = 0; -+ switch (req) { -+ case PM_SUSPEND: /* Enter D1-D3 */ -+ disable_irq(IRQ_OST1); -+ disable_irq(IRQ_RTCAlrm); -+ disable_irq(IRQ_RTC1Hz); -+ suspended = 1; -+ break; -+ case PM_RESUME: /* Enter D0 */ -+ if ( suspended ) { -+ unsigned int rtsr = RTSR; -+ RTSR = 0; -+ RTSR = RTSR_HZ; -+ RTSR = rtsr & (RTSR_HZE|RTSR_ALE); -+ enable_irq(IRQ_OST1); -+ enable_irq(IRQ_RTCAlrm); -+ enable_irq(IRQ_RTC1Hz); -+ suspended = 0; -+ } -+ break; -+ } -+ return 0; -+} -+ -+static int __init rtc_init(void) -+{ -+ struct proc_dir_entry *entry; -+ int ret; -+ -+ misc_register (&sa1100rtc_miscdev); -+ entry = create_proc_entry ("driver/rtc", 0, 0); -+ if (entry) { -+ entry->read_proc = rtc_read_proc; -+ entry->write_proc = rtc_write_proc; -+ } -+ ret = rtc_setup_interrupts(); -+ if (ret) -+ goto IRQ_failed; -+ -+ printk (KERN_INFO "SA1100 Real Time Clock driver v" DRIVER_VERSION "\n"); -+ -+ /* -+ * 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_pm_dev = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, rtc_pm_callback); -+ return 0; -+ -+IRQ_failed: -+ remove_proc_entry ("driver/rtc", NULL); -+ misc_deregister (&sa1100rtc_miscdev); -+ return ret; -+} -+ -+static void __exit rtc_exit(void) -+{ -+ pm_unregister(rtc_pm_dev); -+ rtc_free_interrupts(); -+ remove_proc_entry ("driver/rtc", NULL); -+ misc_deregister (&sa1100rtc_miscdev); -+} -+ -+module_init(rtc_init); -+module_exit(rtc_exit); -+ -+MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>"); -+MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS_MISCDEV(RTC_MINOR); - |