Miata: RTC stopping

Kurt Garloff <[email protected]> Mon, 30 Jun 2003 14:01:13 +0200
Newsgroups gmane.linux.suse.axp
Organization SuSE(DE), TU/e(NL)
Message-ID <[email protected]>
Hi,

I wanted to share the code for a module that I need on my Digital
Personal Workstation 600 au (Miata, PYXIS).

From time to time, the real time clock stops generating the timer
interrupts. The effects are rather funny: The system clock stands 
still. Some things just continue to work, where others (relying on
timers etc.) just stop. The machine stays usable enough to load a 
module that reinitializes the RTC settings. Then everything goes
back to normal.

I have no clue what triggers the the problem. It seems to happen, when
PCI busmastering takes place (access to IDE or SCSI harddisks).
I can't find anyhting suspicious in the kernel, so my current theory
is that it's yet another PYXIS chipset bug (the 21174 is full of rather
strange bugs, some in relation to PCI DMA ...). An undocumented one,
though ...

Anyway, find attached the code. Maybe it's useful for somebody else.
I made insmod fail on the module on purpose, so it does not need to 
be unloaded. It works anyway.

Regards,
-- 
Kurt Garloff  <[email protected]>                          Eindhoven, NL
GPG key: See mail header, key servers                 SuSE Labs (Head)
SuSE Linux AG, Nuernberg, DE                            SCSI, Security
init_rtc.c (text/plain, 1.4 KB)
/* Compile with
 gcc -O2 -Wall -fno-strict-aliasing -fno-common -fomit-frame-pointer   \
 -pipe -mno-fp-regs -ffixed-8 -finline-limit-1000 -mcpu=ev56 -Wa,-mev6 \
 -DMODULE -D__KERNEL__ -I/usr/src/linux/include -c init_rtc.c
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
#include <asm/system.h>
#include <asm/machvec.h>
#include <linux/mc146818rtc.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("Miata: (Re)Set the RTC freq to 1024/s");

void init_rtc_manually(void)
{
	unsigned char x;
	
	/* Reset periodic interrupt frequency.  */
	x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
	if (x != 0x26 && x != 0x19 && x != 0x06) {
		printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x);
		CMOS_WRITE(0x26, RTC_FREQ_SELECT);
	}
	
	/* Turn on periodic interrupts.  */
	x = CMOS_READ(RTC_CONTROL);
	if (!(x & RTC_PIE)) {
		printk("Turning on RTC interrupts.\n");
		x |= RTC_PIE;
		x &= ~(RTC_AIE | RTC_UIE);
		CMOS_WRITE(x, RTC_CONTROL);
	}
	(void) CMOS_READ(RTC_INTR_FLAGS);
	
	outb(0x36, 0x43);       /* pit counter 0: system timer */
	outb(0x00, 0x40);
	outb(0x00, 0x40);
	
	outb(0xb6, 0x43);       /* pit counter 2: speaker */
	outb(0x31, 0x42);
	outb(0x13, 0x42);
}

int __init init_rtc(void)
{
	init_rtc_manually();
	//alpha_mv.init_rtc();
	return 1;
}

void __exit exit_module(void)
{
	return;
}

module_init(init_rtc);
module_exit(exit_module);
signature.asc (application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)

iD8DBQE/ACaJxmLh6hyYd04RAtN2AJ97VcII4zHvkF6mj4gmNUWsIFoDwACePjbB
bhf8ZrWdMgum5XSAFTf4vQ8=
=Z3UB
-----END PGP SIGNATURE-----