diff options
Diffstat (limited to 'drivers/char/rtc.c')
| -rw-r--r-- | drivers/char/rtc.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index cc7bd1a3095b..6e6a7c7a7eff 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 | } |
| 965 | no_irq: | 977 | no_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); |
| @@ -1222,7 +1245,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file) | |||
| 1222 | 1245 | ||
| 1223 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) | 1246 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) |
| 1224 | { | 1247 | { |
| 1225 | unsigned long uip_watchdog = jiffies; | 1248 | unsigned long uip_watchdog = jiffies, flags; |
| 1226 | unsigned char ctrl; | 1249 | unsigned char ctrl; |
| 1227 | #ifdef CONFIG_MACH_DECSTATION | 1250 | #ifdef CONFIG_MACH_DECSTATION |
| 1228 | unsigned int real_year; | 1251 | unsigned int real_year; |
| @@ -1249,7 +1272,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
| 1249 | * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is | 1272 | * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is |
| 1250 | * only updated by the RTC when initially set to a non-zero value. | 1273 | * only updated by the RTC when initially set to a non-zero value. |
| 1251 | */ | 1274 | */ |
| 1252 | spin_lock_irq(&rtc_lock); | 1275 | spin_lock_irqsave(&rtc_lock, flags); |
| 1253 | rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); | 1276 | rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); |
| 1254 | rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); | 1277 | rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); |
| 1255 | rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); | 1278 | rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); |
| @@ -1263,7 +1286,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
| 1263 | real_year = CMOS_READ(RTC_DEC_YEAR); | 1286 | real_year = CMOS_READ(RTC_DEC_YEAR); |
| 1264 | #endif | 1287 | #endif |
| 1265 | ctrl = CMOS_READ(RTC_CONTROL); | 1288 | ctrl = CMOS_READ(RTC_CONTROL); |
| 1266 | spin_unlock_irq(&rtc_lock); | 1289 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 1267 | 1290 | ||
| 1268 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1291 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
| 1269 | { | 1292 | { |
