diff --exclude .depend --exclude .hdepend -ur kernel-8.0/arch/mips/vr41xx/rtc.c.orig kernel-8.0-w1/arch/mips/vr41xx/rtc.c.orig
--- kernel-8.0/arch/mips/vr41xx/rtc.c.orig	Thu Nov 15 21:52:00 2001
+++ kernel-8.0-w1/arch/mips/vr41xx/rtc.c.orig	Sun Sep 15 15:52:04 2002
@@ -35,6 +35,8 @@
 
 #define RTC_VERSION		"1.0"
 
+// #define EXPORT_SYMTAB 1
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -45,6 +47,8 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/rtc.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -87,6 +91,7 @@
 
 static int rtc_read_proc(char *page, char **start, off_t off,
                          int count, int *eof, void *data);
+static int rtc_process_waiting=0;
 
 /*
  *	Bits in rtc_status. (6 bits of room for future expansion)
@@ -139,12 +144,17 @@
 	/* ack the interrupt(s), but only the ones we reported */
 	*VR41XX_RTCINTREG = intreg;
 	rtc_irq_data |= intreg;
+	if(rtc_process_waiting==1)
+	  intreg=1;
+	else
+	  intreg=0;
 	spin_unlock (&rtc_lock);
-
-	wake_up_interruptible(&rtc_wait);	
-
-	if (rtc_async_queue)
-		kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
+	if(intreg==1) {
+	  wake_up_interruptible(&rtc_wait);	
+	  
+	  if (rtc_async_queue)
+	    kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
+	}
 }
 
 /*
@@ -165,7 +175,9 @@
 	
 	if (count < sizeof(unsigned long))
 		return -EINVAL;
-
+	spin_lock_irq(&rtc_lock);
+	rtc_process_waiting=1;
+	spin_unlock_irq(&rtc_lock);
 	add_wait_queue(&rtc_wait, &wait);
 
 	current->state = TASK_INTERRUPTIBLE;
@@ -210,8 +222,9 @@
 	}
 	case RTC_PIE_OFF:	/* Mask periodic int. enab. bit	*/
 	{
-		mask_rtc_irq(VR41XX_IRQ_INT2, RTC_PIE_EN);
-		return 0;
+	  return -EACCES;
+	  mask_rtc_irq(VR41XX_IRQ_INT2, RTC_PIE_EN);
+	  return 0;
 	}
 	case RTC_PIE_ON:	/* Allow periodic ints		*/
 	{
@@ -220,9 +233,10 @@
 		 * We don't really want Joe User enabling more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
-			return -EACCES;
-		return set_rtc_irq(VR41XX_IRQ_INT2, RTC_PIE_EN);
+	  return -EACCES;
+	  if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
+	    return -EACCES;
+	  return set_rtc_irq(VR41XX_IRQ_INT2, RTC_PIE_EN);
 	}
 	case RTC_ALM_READ:	/* Read the present alarm time */
 	{
@@ -270,11 +284,13 @@
 	}
 	case RTC_IRQP_READ:	/* Read the periodic IRQ rate.	*/
 	{
+	  return -EACCES;
 		return put_user(rtc_freq, (unsigned long *)arg);
 	}
 	case RTC_IRQP_SET:	/* Set periodic IRQ rate.	*/
 	{
 		int quot;
+		return -EACCES;
 
 		if (arg < 1)
 			return -EINVAL;
@@ -304,7 +320,7 @@
 
 		spin_lock_irq(&rtc_lock);
 		*VR41XX_RTCL2LREG = quot;
-		*VR41XX_RTCL2LREG = 0;
+		*VR41XX_RTCL2HREG = 0;
 		spin_unlock_irq(&rtc_lock);
 		return 0;
 	}
@@ -366,9 +382,11 @@
 	 * Turn off any interrupts once the device is no longer
 	 * in use, and clear the data.
 	 */
-	mask_rtc_irq(VR41XX_IRQ_ETIMER, RTC_AIE_EN);
+  //	mask_rtc_irq(VR41XX_IRQ_ETIMER, RTC_AIE_EN);
 	mask_rtc_irq(VR41XX_IRQ_INT2, RTC_PIE_EN);
-
+	spin_lock_irq(&rtc_lock);
+	rtc_process_waiting=0;
+	spin_unlock_irq(&rtc_lock);
 	if (file->f_flags & FASYNC) {
 		rtc_fasync (-1, file, 0);
 	}
@@ -386,6 +404,7 @@
 	poll_wait(file, &rtc_wait, wait);
 
 	spin_lock_irq(&rtc_lock);
+	rtc_process_waiting=1;
 	l = rtc_irq_data;
 	spin_unlock_irq(&rtc_lock);
 
@@ -417,12 +436,19 @@
 
 static int __init rtc_init(void)
 {
+	unsigned short* alrm=(unsigned short*) VR41XX_ECMPLREG;
 	misc_register(&rtc_dev);
+
 	create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
 
 	/* Initialize periodic freq. to what PC RTC driver uses, which is 1024Hz */
 	*VR41XX_RTCL2LREG = 32768 / 1024;
-	*VR41XX_RTCL2LREG = 0;
+	*VR41XX_RTCL2HREG = 0;
+	*VR41XX_RTCL2LREG=0;
+	*alrm=0; alrm++;
+	*alrm=0; alrm++;
+	*alrm=0;
+	
 	rtc_freq = 1024;
 	epoch = 1970;
 
@@ -531,7 +557,8 @@
 	spin_lock_irq(&rtc_lock);
 	if (!(atomic_read(&rtc_status) & bit)) {
 		atomic_set(&rtc_status, atomic_read(&rtc_status) | bit);
-		retval = request_irq(irq, rtc_interrupt, SA_INTERRUPT, "rtc", NULL);
+		retval = request_irq(irq, rtc_interrupt, SA_INTERRUPT | SA_SHIRQ, "rtc", NULL);
+		//		retval = request_irq(irq, rtc_interrupt, SA_INTERRUPT, "rtc", NULL);
 	}
 	rtc_irq_data = 0;
 	spin_unlock_irq(&rtc_lock);
@@ -616,3 +643,100 @@
 	set_rtc_time(timeval, reg);
 	return 0;
 }
+//* major hackery below that steals the PIE for nefarious purposes (buzzing)
+//* Note that it doesnt even put it back how it found it, so, uh, oh well.
+
+static int sound_calls = 0;
+
+static void 
+buzz_rtc_end(unsigned long sound_timer_cast) 
+{
+       struct timer_list *sound_timer = (struct timer_list *)sound_timer_cast;
+       sound_calls--;
+       if (sound_calls <= 0)  {
+               spin_lock_irq(&rtc_lock);
+               *VR41XX_RTCL2LREG = 0;
+               *VR41XX_RTCL2HREG = 0;
+               spin_unlock_irq(&rtc_lock);
+               free_irq(VR41XX_IRQ_INT2, &sound_calls);
+              *VR41XX_GPDATHREG &= ~(VR41XX_GPDATHREG_GPIO18); // make sure the buzzer ends up off    
+       }
+       kfree(sound_timer);
+}
+
+static void 
+buzz_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned short intreg;
+
+       /*
+       *      Can be an alarm interrupt, update complete interrupt,
+       *      or a periodic interrupt. We store the status in the
+       *      low byte and the number of interrupts received since
+       *      the last read in the remainder of rtc_irq_data.
+       */
+
+       spin_lock (&rtc_lock);
+       rtc_irq_data -= 0x100; // fix the interrupt counts
+       rtc_irq_data &= ~0xff;
+       intreg = *VR41XX_RTCINTREG & 0x04; // pay attention only to RTCLong2
+       barrier();
+       /* ack the interrupt(s), but only the ones we reported */
+       *VR41XX_RTCINTREG = intreg;
+       // rtc_irq_data |= intreg;
+       spin_unlock (&rtc_lock);
+   
+       *VR41XX_GPDATHREG ^= VR41XX_GPDATHREG_GPIO18; // buzzer toggle
+
+}
+
+void steal_rtcl2_and_buzz(unsigned int hz, unsigned int ticks) {
+
+  static struct timer_list *sound_timer;
+  unsigned int half_wave = 0;
+  int retval;
+  if((hz > 20) && (hz < 32767))
+    /*     
+     * derive hz->clocktick conversion from first principles:
+     * 32767 ticks / sec * sec / N  cycles =>  32767 / N
+     * ...and the halfwave is half of that, so 16384 / N */
+    half_wave = 16384 / hz;
+	
+  if (half_wave) {
+	  
+    // set the periodicity  
+    spin_lock_irq(&rtc_lock);
+    *VR41XX_RTCL2LREG = half_wave & 0xff;
+    *VR41XX_RTCL2HREG = (half_wave >> 16) & 0xff;
+    spin_unlock_irq(&rtc_lock);
+    
+    /* When we share IRQ we have to differentiate between two handlers
+       for the same IRQ, that's why we put the address of the wait queue
+       as last argument to request_irq. */
+    retval = request_irq(VR41XX_IRQ_INT2, buzz_rtc_interrupt, SA_INTERRUPT|SA_SHIRQ, 
+			 "buzzer_hack", &sound_calls);
+    if (retval) {
+      printk ("buzzer: unable to request_irq (%d)\n", retval);
+      return;
+    }
+    
+    if (ticks) {
+      sound_calls++;
+      sound_timer = (struct timer_list *)kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
+      init_timer(sound_timer);
+      sound_timer->data = (unsigned long int)sound_timer;
+      sound_timer->function = &buzz_rtc_end;
+      sound_timer->expires = jiffies + ticks;
+      add_timer(sound_timer);
+    }
+    printk("buzz %d hz %d ticks %d halfwave %d calls\n", hz, ticks, half_wave, sound_calls);
+    
+  } else {
+    // turn sound off
+    printk("unbuzz %d hz %d ticks\n", hz, ticks);
+    buzz_rtc_end(0);
+  } 
+}
+
+
+

