aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/rtc.c41
-rw-r--r--include/asm-mips/mach-dec/mc146818rtc.h2
-rw-r--r--include/linux/mc146818rtc.h7
3 files changed, 41 insertions, 9 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index cc7bd1a3095b..6ccc364c08df 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -46,13 +46,12 @@
46 * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init 46 * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
47 * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer 47 * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
48 * CONFIG_HPET_EMULATE_RTC 48 * CONFIG_HPET_EMULATE_RTC
49 * 1.12a Maciej W. Rozycki: Handle memory-mapped chips properly.
49 * 1.12ac Alan Cox: Allow read access to the day of week register 50 * 1.12ac Alan Cox: Allow read access to the day of week register
50 */ 51 */
51 52
52#define RTC_VERSION "1.12ac" 53#define RTC_VERSION "1.12ac"
53 54
54#define RTC_IO_EXTENT 0x8
55
56/* 55/*
57 * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with 56 * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
58 * interrupts disabled. Due to the index-port/data-port (0x70/0x71) 57 * interrupts disabled. Due to the index-port/data-port (0x70/0x71)
@@ -337,7 +336,15 @@ static ssize_t rtc_read(struct file *file, char __user *buf,
337 if (rtc_has_irq == 0) 336 if (rtc_has_irq == 0)
338 return -EIO; 337 return -EIO;
339 338
340 if (count < sizeof(unsigned)) 339 /*
340 * Historically this function used to assume that sizeof(unsigned long)
341 * is the same in userspace and kernelspace. This lead to problems
342 * for configurations with multiple ABIs such a the MIPS o32 and 64
343 * ABIs supported on the same kernel. So now we support read of both
344 * 4 and 8 bytes and assume that's the sizeof(unsigned long) in the
345 * userspace ABI.
346 */
347 if (count != sizeof(unsigned int) && count != sizeof(unsigned long))
341 return -EINVAL; 348 return -EINVAL;
342 349
343 add_wait_queue(&rtc_wait, &wait); 350 add_wait_queue(&rtc_wait, &wait);
@@ -368,10 +375,12 @@ static ssize_t rtc_read(struct file *file, char __user *buf,
368 schedule(); 375 schedule();
369 } while (1); 376 } while (1);
370 377
371 if (count < sizeof(unsigned long)) 378 if (count == sizeof(unsigned int))
372 retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); 379 retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int);
373 else 380 else
374 retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long); 381 retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long);
382 if (!retval)
383 retval = count;
375 out: 384 out:
376 current->state = TASK_RUNNING; 385 current->state = TASK_RUNNING;
377 remove_wait_queue(&rtc_wait, &wait); 386 remove_wait_queue(&rtc_wait, &wait);
@@ -923,6 +932,9 @@ static int __init rtc_init(void)
923 struct sparc_isa_device *isa_dev; 932 struct sparc_isa_device *isa_dev;
924#endif 933#endif
925#endif 934#endif
935#ifndef __sparc__
936 void *r;
937#endif
926 938
927#ifdef __sparc__ 939#ifdef __sparc__
928 for_each_ebus(ebus) { 940 for_each_ebus(ebus) {
@@ -964,8 +976,13 @@ found:
964 } 976 }
965no_irq: 977no_irq:
966#else 978#else
967 if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) { 979 if (RTC_IOMAPPED)
968 printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0)); 980 r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
981 else
982 r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
983 if (!r) {
984 printk(KERN_ERR "rtc: I/O resource %lx is not free.\n",
985 (long)(RTC_PORT(0)));
969 return -EIO; 986 return -EIO;
970 } 987 }
971 988
@@ -979,7 +996,10 @@ no_irq:
979 if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) { 996 if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) {
980 /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ 997 /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
981 printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); 998 printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
982 release_region(RTC_PORT(0), RTC_IO_EXTENT); 999 if (RTC_IOMAPPED)
1000 release_region(RTC_PORT(0), RTC_IO_EXTENT);
1001 else
1002 release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
983 return -EIO; 1003 return -EIO;
984 } 1004 }
985 hpet_rtc_timer_init(); 1005 hpet_rtc_timer_init();
@@ -1079,7 +1099,10 @@ static void __exit rtc_exit (void)
1079 if (rtc_has_irq) 1099 if (rtc_has_irq)
1080 free_irq (rtc_irq, &rtc_port); 1100 free_irq (rtc_irq, &rtc_port);
1081#else 1101#else
1082 release_region (RTC_PORT (0), RTC_IO_EXTENT); 1102 if (RTC_IOMAPPED)
1103 release_region(RTC_PORT(0), RTC_IO_EXTENT);
1104 else
1105 release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
1083#ifdef RTC_IRQ 1106#ifdef RTC_IRQ
1084 if (rtc_has_irq) 1107 if (rtc_has_irq)
1085 free_irq (RTC_IRQ, NULL); 1108 free_irq (RTC_IRQ, NULL);
diff --git a/include/asm-mips/mach-dec/mc146818rtc.h b/include/asm-mips/mach-dec/mc146818rtc.h
index 6d37a5675803..6724e99e43e1 100644
--- a/include/asm-mips/mach-dec/mc146818rtc.h
+++ b/include/asm-mips/mach-dec/mc146818rtc.h
@@ -19,6 +19,8 @@
19 19
20extern volatile u8 *dec_rtc_base; 20extern volatile u8 *dec_rtc_base;
21 21
22#define ARCH_RTC_LOCATION
23
22#define RTC_PORT(x) CPHYSADDR((long)dec_rtc_base) 24#define RTC_PORT(x) CPHYSADDR((long)dec_rtc_base)
23#define RTC_IO_EXTENT dec_kn_slot_size 25#define RTC_IO_EXTENT dec_kn_slot_size
24#define RTC_IOMAPPED 0 26#define RTC_IOMAPPED 0
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
index bbc93ae217e1..432b2fa24929 100644
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -89,4 +89,11 @@ extern spinlock_t rtc_lock; /* serialize CMOS RAM access */
89# define RTC_VRT 0x80 /* valid RAM and time */ 89# define RTC_VRT 0x80 /* valid RAM and time */
90/**********************************************************************/ 90/**********************************************************************/
91 91
92#ifndef ARCH_RTC_LOCATION /* Override by <asm/mc146818rtc.h>? */
93
94#define RTC_IO_EXTENT 0x8
95#define RTC_IOMAPPED 1 /* Default to I/O mapping. */
96
97#endif /* ARCH_RTC_LOCATION */
98
92#endif /* _MC146818RTC_H */ 99#endif /* _MC146818RTC_H */