Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / char / rtc.c
index 7cac6d0..ab6429b 100644 (file)
  *      1.11a   Daniele Bellucci: Audit create_proc_read_entry in rtc_init
  *     1.12    Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
  *             CONFIG_HPET_EMULATE_RTC
+ *     1.12a   Maciej W. Rozycki: Handle memory-mapped chips properly.
  *     1.12ac  Alan Cox: Allow read access to the day of week register
  */
 
 #define RTC_VERSION            "1.12ac"
 
-#define RTC_IO_EXTENT  0x8
-
 /*
  *     Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
  *     interrupts disabled. Due to the index-port/data-port (0x70/0x71)
@@ -61,7 +60,6 @@
  *     this driver.)
  */
 
-#include <linux/config.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -211,17 +209,18 @@ static const unsigned char days_in_mo[] =
  */
 static inline unsigned char rtc_is_updating(void)
 {
+       unsigned long flags;
        unsigned char uip;
 
-       spin_lock_irq(&rtc_lock);
+       spin_lock_irqsave(&rtc_lock, flags);
        uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-       spin_unlock_irq(&rtc_lock);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        return uip;
 }
 
 #ifdef RTC_IRQ
 /*
- *     A very tiny interrupt handler. It runs with SA_INTERRUPT set,
+ *     A very tiny interrupt handler. It runs with IRQF_DISABLED set,
  *     but there is possibility of conflicting with the set_rtc_mmss()
  *     call (the rtc irq and the timer irq can easily run at the same
  *     time in two different CPUs). So we need to serialize
@@ -338,7 +337,15 @@ static ssize_t rtc_read(struct file *file, char __user *buf,
        if (rtc_has_irq == 0)
                return -EIO;
 
-       if (count < sizeof(unsigned))
+       /*
+        * Historically this function used to assume that sizeof(unsigned long)
+        * is the same in userspace and kernelspace.  This lead to problems
+        * for configurations with multiple ABIs such a the MIPS o32 and 64
+        * ABIs supported on the same kernel.  So now we support read of both
+        * 4 and 8 bytes and assume that's the sizeof(unsigned long) in the
+        * userspace ABI.
+        */
+       if (count != sizeof(unsigned int) && count !=  sizeof(unsigned long))
                return -EINVAL;
 
        add_wait_queue(&rtc_wait, &wait);
@@ -369,10 +376,12 @@ static ssize_t rtc_read(struct file *file, char __user *buf,
                schedule();
        } while (1);
 
-       if (count < sizeof(unsigned long))
-               retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); 
+       if (count == sizeof(unsigned int))
+               retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int);
        else
                retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long);
+       if (!retval)
+               retval = count;
  out:
        current->state = TASK_RUNNING;
        remove_wait_queue(&rtc_wait, &wait);
@@ -878,7 +887,7 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
  *     The various file operations we support.
  */
 
-static struct file_operations rtc_fops = {
+static const struct file_operations rtc_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .read           = rtc_read,
@@ -897,7 +906,7 @@ static struct miscdevice rtc_dev = {
        .fops           = &rtc_fops,
 };
 
-static struct file_operations rtc_proc_fops = {
+static const struct file_operations rtc_proc_fops = {
        .owner = THIS_MODULE,
        .open = rtc_proc_open,
        .read  = seq_read,
@@ -924,11 +933,14 @@ static int __init rtc_init(void)
        struct sparc_isa_device *isa_dev;
 #endif
 #endif
+#ifndef __sparc__
+       void *r;
+#endif
 
 #ifdef __sparc__
        for_each_ebus(ebus) {
                for_each_ebusdev(edev, ebus) {
-                       if(strcmp(edev->prom_name, "rtc") == 0) {
+                       if(strcmp(edev->prom_node->name, "rtc") == 0) {
                                rtc_port = edev->resource[0].start;
                                rtc_irq = edev->irqs[0];
                                goto found;
@@ -938,7 +950,7 @@ static int __init rtc_init(void)
 #ifdef __sparc_v9__
        for_each_isa(isa_br) {
                for_each_isadev(isa_dev, isa_br) {
-                       if (strcmp(isa_dev->prom_name, "rtc") == 0) {
+                       if (strcmp(isa_dev->prom_node->name, "rtc") == 0) {
                                rtc_port = isa_dev->resource.start;
                                rtc_irq = isa_dev->irq;
                                goto found;
@@ -959,18 +971,19 @@ found:
         * XXX Interrupt pin #7 in Espresso is shared between RTC and
         * PCI Slot 2 INTA# (and some INTx# in Slot 1).
         */
-       if (request_irq(rtc_irq, rtc_interrupt, SA_SHIRQ, "rtc", (void *)&rtc_port)) {
-               /*
-                * Standard way for sparc to print irq's is to use
-                * __irq_itoa(). I think for EBus it's ok to use %d.
-                */
+       if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", (void *)&rtc_port)) {
                printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq);
                return -EIO;
        }
 no_irq:
 #else
-       if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) {
-               printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0));
+       if (RTC_IOMAPPED)
+               r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+       else
+               r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+       if (!r) {
+               printk(KERN_ERR "rtc: I/O resource %lx is not free.\n",
+                      (long)(RTC_PORT(0)));
                return -EIO;
        }
 
@@ -981,10 +994,13 @@ no_irq:
                rtc_int_handler_ptr = rtc_interrupt;
        }
 
-       if(request_irq(RTC_IRQ, rtc_int_handler_ptr, SA_INTERRUPT, "rtc", NULL)) {
+       if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) {
                /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
                printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
-               release_region(RTC_PORT(0), RTC_IO_EXTENT);
+               if (RTC_IOMAPPED)
+                       release_region(RTC_PORT(0), RTC_IO_EXTENT);
+               else
+                       release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
                return -EIO;
        }
        hpet_rtc_timer_init();
@@ -1084,7 +1100,10 @@ static void __exit rtc_exit (void)
        if (rtc_has_irq)
                free_irq (rtc_irq, &rtc_port);
 #else
-       release_region (RTC_PORT (0), RTC_IO_EXTENT);
+       if (RTC_IOMAPPED)
+               release_region(RTC_PORT(0), RTC_IO_EXTENT);
+       else
+               release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
 #ifdef RTC_IRQ
        if (rtc_has_irq)
                free_irq (RTC_IRQ, NULL);
@@ -1227,7 +1246,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
 
 void rtc_get_rtc_time(struct rtc_time *rtc_tm)
 {
-       unsigned long uip_watchdog = jiffies;
+       unsigned long uip_watchdog = jiffies, flags;
        unsigned char ctrl;
 #ifdef CONFIG_MACH_DECSTATION
        unsigned int real_year;
@@ -1254,7 +1273,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
         * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is
         * only updated by the RTC when initially set to a non-zero value.
         */
-       spin_lock_irq(&rtc_lock);
+       spin_lock_irqsave(&rtc_lock, flags);
        rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
        rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
        rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
@@ -1268,7 +1287,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
        real_year = CMOS_READ(RTC_DEC_YEAR);
 #endif
        ctrl = CMOS_READ(RTC_CONTROL);
-       spin_unlock_irq(&rtc_lock);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
        {