patch-2.4.25 linux-2.4.25/drivers/char/rtc.c
Next file: linux-2.4.25/drivers/char/sb1250_duart.c
Previous file: linux-2.4.25/drivers/char/random.c
Back to the patch index
Back to the overall index
- Lines: 126
- Date:
2004-02-18 05:36:31.000000000 -0800
- Orig file:
linux-2.4.24/drivers/char/rtc.c
- Orig date:
2004-01-05 05:53:56.000000000 -0800
diff -urN linux-2.4.24/drivers/char/rtc.c linux-2.4.25/drivers/char/rtc.c
@@ -35,17 +35,16 @@
* 1.09a Pete Zaitcev: Sun SPARC
* 1.09b Jeff Garzik: Modularize, init cleanup
* 1.09c Jeff Garzik: SMP cleanup
- * 1.10 Paul Barton-Davis: add support for async I/O
+ * 1.10 Paul Barton-Davis: add support for async I/O
* 1.10a Andrea Arcangeli: Alpha updates
* 1.10b Andrew Morton: SMP lock fix
* 1.10c Cesar Barros: SMP locking fixes and cleanup
* 1.10d Paul Gortmaker: delete paranoia check in rtc_exit
* 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness.
+ * 1.10f Maciej W. Rozycki: Handle memory-mapped chips properly.
*/
-#define RTC_VERSION "1.10e"
-
-#define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */
+#define RTC_VERSION "1.10f"
/*
* Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
@@ -84,7 +83,9 @@
static int rtc_irq = PCI_IRQ_NONE;
#endif
+#if RTC_IRQ
static int rtc_has_irq = 1;
+#endif
/*
* We sponge a minor off of the misc major. No need slurping
@@ -97,7 +98,9 @@
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
+#if RTC_IRQ
static struct timer_list rtc_irq_timer;
+#endif
static ssize_t rtc_read(struct file *file, char *buf,
size_t count, loff_t *ppos);
@@ -238,7 +241,15 @@
if (rtc_has_irq == 0)
return -EIO;
- if (count < sizeof(unsigned long))
+ /*
+ * 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);
@@ -268,9 +279,12 @@
schedule();
} while (1);
- retval = put_user(data, (unsigned long *)buf);
+ if (count == sizeof(unsigned int))
+ retval = put_user(data, (unsigned int *)buf);
+ else
+ retval = put_user(data, (unsigned long *)buf);
if (!retval)
- retval = sizeof(unsigned long);
+ retval = count;
out:
current->state = TASK_RUNNING;
remove_wait_queue(&rtc_wait, &wait);
@@ -707,6 +721,9 @@
struct isa_device *isa_dev;
#endif
#endif
+#ifndef __sparc__
+ void *r;
+#endif
#ifdef __sparc__
for_each_ebus(ebus) {
@@ -753,18 +770,24 @@
}
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;
}
#if RTC_IRQ
- if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
- {
+ if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "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;
}
#endif
@@ -848,7 +871,10 @@
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);
#if RTC_IRQ
if (rtc_has_irq)
free_irq (RTC_IRQ, NULL);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)