[PATCH] char/rtc: Handle memory-mapped chips properly
Handle memory-mapped chips properly, needed for example on DECstations. This support was in Linux 2.4 but for some reason got lost in 2.6. This patch is taken directly from the linux-mips repository. [akpm@osdl.org: cleanup] Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Martin Michlmayr <tbm@cyrius.com> Cc: Paul Gortmaker <penguin@muskoka.com> Cc: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									06c67befee
								
							
						
					
					
						commit
						38e0e8c055
					
				| @ -46,13 +46,12 @@ | ||||
|  *      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) | ||||
| @ -337,7 +336,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); | ||||
| @ -368,10 +375,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); | ||||
| @ -923,6 +932,9 @@ 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) { | ||||
| @ -964,8 +976,13 @@ found: | ||||
| 	} | ||||
| 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; | ||||
| 	} | ||||
| 
 | ||||
| @ -979,7 +996,10 @@ no_irq: | ||||
| 	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(); | ||||
| @ -1079,7 +1099,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); | ||||
|  | ||||
| @ -19,6 +19,8 @@ | ||||
| 
 | ||||
| extern volatile u8 *dec_rtc_base; | ||||
| 
 | ||||
| #define ARCH_RTC_LOCATION | ||||
| 
 | ||||
| #define RTC_PORT(x)	CPHYSADDR((long)dec_rtc_base) | ||||
| #define RTC_IO_EXTENT	dec_kn_slot_size | ||||
| #define RTC_IOMAPPED	0 | ||||
|  | ||||
| @ -89,4 +89,11 @@ extern spinlock_t rtc_lock;		/* serialize CMOS RAM access */ | ||||
| # define RTC_VRT 0x80		/* valid RAM and time */ | ||||
| /**********************************************************************/ | ||||
| 
 | ||||
| #ifndef ARCH_RTC_LOCATION	/* Override by <asm/mc146818rtc.h>? */ | ||||
| 
 | ||||
| #define RTC_IO_EXTENT	0x8 | ||||
| #define RTC_IOMAPPED	1	/* Default to I/O mapping. */ | ||||
| 
 | ||||
| #endif /* ARCH_RTC_LOCATION */ | ||||
| 
 | ||||
| #endif /* _MC146818RTC_H */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user