Commit 38e0e8c0 authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Linus Torvalds
Browse files

[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: default avatarMaciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: default avatarMartin Michlmayr <tbm@cyrius.com>
Cc: Paul Gortmaker <penguin@muskoka.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 06c67bef
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -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))
	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);
		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
	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);
+2 −0
Original line number Diff line number Diff line
@@ -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
+7 −0
Original line number Diff line number Diff line
@@ -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 */