diff -Naurp linux-2.4-ts11/arch/arm/config.in linux-2.4-ts11-hrt/arch/arm/config.in
--- linux-2.4-ts11/arch/arm/config.in	2006-02-09 23:58:57.000000000 +0100
+++ linux-2.4-ts11-hrt/arch/arm/config.in	2008-05-26 11:12:57.000000000 +0200
@@ -539,6 +539,7 @@ hex 'Compressed ROM boot loader base add
 hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
 
 if [ "$CONFIG_ARCH_SA1100" = "y" -o \
+     "$CONFIG_ARCH_EP9301" = "y" -o \
      "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
    dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
 fi
diff -Naurp linux-2.4-ts11/arch/arm/mach-ep93xx/Makefile linux-2.4-ts11-hrt/arch/arm/mach-ep93xx/Makefile
--- linux-2.4-ts11/arch/arm/mach-ep93xx/Makefile	2004-07-22 21:48:59.000000000 +0200
+++ linux-2.4-ts11-hrt/arch/arm/mach-ep93xx/Makefile	2008-05-26 11:12:35.000000000 +0200
@@ -18,6 +18,11 @@ obj-			:=
 
 export-objs		:= pcipool.o
 
+# We link the CPU support next, so that RAM timings can be tuned.
+ifeq ($(CONFIG_CPU_FREQ),y)
+obj-$(CONFIG_ARCH_EP9301) += cpu-ep93xx.o
+endif
+
 obj-$(CONFIG_EP93XX_DMA)+= dma_ep93xx.o
 
 
diff -Naurp linux-2.4-ts11/arch/arm/mach-ep93xx/cpu-ep93xx.c linux-2.4-ts11-hrt/arch/arm/mach-ep93xx/cpu-ep93xx.c
--- linux-2.4-ts11/arch/arm/mach-ep93xx/cpu-ep93xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4-ts11-hrt/arch/arm/mach-ep93xx/cpu-ep93xx.c	2008-05-26 11:12:35.000000000 +0200
@@ -0,0 +1,196 @@
+/*
+ * linux/arch/arm/mach-ep93xx/cpu-ep93xx.c
+ * clock scaling for the Cirrus EP93xx embedded chips
+ *
+ * Copyright (C) 2005 Diamond Consulting Services Ltd
+ *
+ * Authors: 
+ * - Bob Lees bob@diamond.demon.co.uk
+ *
+ * This software has been developed while working on the Technologics
+ * Ts72x0 (http://www.embeddedarm.com/)
+ *
+ * This code is loosely based on the cpu-sa1100.c code from mach-sa1100
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Theory of operations
+ * ====================
+ * 
+ * Clock scaling can be used to lower the power consumption of the CPU
+ * core. For this processor the major power saving is reducing the mem clk.
+ *
+ * The ep93xx has 2 registers to control the 2 PLLs of the ep93xx:
+ *   CLKSET1 controls the core processor clocks (PLL1); and
+ *   CLKSET2 controls the USB, MIR and a2d clocks (PLL2)
+ *
+ *   SYSCON_CLKSET1      0x8093_0020    PLL1 config
+ *   SYSCON_CLKSET2      0x8093_0024    PLL2 config
+ * 
+ * If you really want to understand what is going on
+ * then read the relevant sections in the ep9301 user guide
+ * (available for free from Cirrus).
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#define CLKSET1(p, pl, pd, h, f)   ( p | \
+                        ( pl << SYSCON_CLKSET1_PLL1_PS_SHIFT ) | \
+                        ( pd << SYSCON_CLKSET1_PCLK_DIV_SHIFT ) | \
+                        ( h << SYSCON_CLKSET1_HCLK_DIV_SHIFT ) | \
+                        ( f << SYSCON_CLKSET1_FCLK_DIV_SHIFT ) )
+
+#define INITIAL_SPEED    200000
+
+typedef struct {
+	int speed;
+	u32 preset;
+	u32 pll1_ps;  /* sets final divide from pll */
+	u32 pdiv;     /* sets pclk, peripheral clk (1/2 of hclk) */
+	u32 hdiv;     /* sets hclk, bus (memory) clk */
+	u32 fdiv;     /* sets fclk, processor clk */
+} ep93xx_speed_settings_t;
+
+/* see clocks.h for explanation of pclk, hclk, fclk */
+
+#if 0
+  { 166000, 0x0080fafa, 0, 1, 3, 1 }, /* 166.0 MHz (0x02b4fa5a) */
+  { 41520, 0x0080fa5a, 2, 1, 2, 1 }, /* 41.5 MHz (20.7 memclk) (0x02a6fa5a) */
+  { 41500, 0x0080fa5a, 2, 1, 1, 1 }, /* 41.5 MHz (41.5 memclk) (0x0296fa5a) */
+  { 20710, 0x0080fa5a, 3, 0, 2, 1 }, /* 20.7 MHz (10.4 memclk) (0x02a7fa5a) */
+  { 20700, 0x0080fa5a, 3, 1, 1, 1 }, /* 20.7 MHz (20.7 memclk) (0x02a7fa5a) */
+  { 10400, 0x0080fa5a, 3, 0, 3, 2 }, /* 10.4 MHz (8.3 memclk) (0x04b7fa5a) */
+#endif
+
+static ep93xx_speed_settings_t ep93xx_clkset1_settings[] =
+{
+  /*
+   * Remember changing the pll may take 8-16ms to stabalise, so
+   * changing freq without touching the pll is preferable.
+   * In practice the frequency is almost continuously variable.
+   * These settings below are a subset which work and don't change
+   * the pll and give a reasonable range.
+   * The major power saving is in the memclk (hclk) hence the emphasis
+   * below.
+   * The lower 2 digits in the presets below are the memclk, with 00
+   * being memclk = processor clk.
+   * For the clk checking/getting code to work the list below MUST
+   * be in decending order.
+   */
+  /* { preset, pll1_ps, pdiv, hdiv, fdiv } */ /* clock frequency */
+  { 200000, 0x0080bb36, 0, 1, 2, 1 }, /* 200.0 MHz (0x02a4bb36) */
+  { 100050, 0x0080bb36, 1, 1, 2, 1 }, /* 100.0 MHz (50 memclk) (0x02a5bb36) */
+  { 100025, 0x0080bb36, 1, 1, 5, 1 }, /* 100.0 MHz (25 memclk) (0x02d1bb36) */
+  { 100012, 0x0080bb36, 1, 1, 6, 1 }, /* 100.0 MHz (12.5 memclk) (0x02e1bb36) */
+  { 100000, 0x0080bb36, 1, 1, 1, 1 }, /* 100.0 MHz (100 memclk) (0x0295bb36) */
+  { 50025, 0x0080bb36, 2, 1, 2, 1 }, /* 50.0 MHz (25 memclk) (0x02a2bb36) */
+  { 50012, 0x0080bb36, 2, 1, 5, 1 }, /* 50.0 MHz (12.5 memclk) (0x02d2bb36) */
+  { 50000, 0x0080bb36, 2, 1, 1, 1 }, /* 50.0 MHz (50 memclk) (0x0296bb36) */
+  { 25012, 0x0080bb36, 3, 1, 2, 1 }, /* 25.0 MHz (12.5 memclk) (0x02a7bb36) */
+  { 25000, 0x0080bb36, 3, 1, 1, 1 }, /* 25.0 MHz (25 memclk) (0x0297bb36) */
+  { 12510, 0x0080bb36, 3, 1, 3, 2 }, /* 12.5 MHz (10.0 memclk) (0x04b7bb36) */
+  { 12500, 0x0080bb36, 3, 1, 2, 2 }, /* 12.5 MHz (12.5 memclk) (0x04a7bb36) */
+  { 0, 0, 0, 0, 0, 0 } /* last entry */
+};
+
+static u32 ep93xx_get_clkset1(unsigned int khz)
+{
+  int i = 0;
+
+  while (ep93xx_clkset1_settings[i].speed > 0) {
+    if (ep93xx_clkset1_settings[i].speed == khz) {
+      return(CLKSET1(ep93xx_clkset1_settings[i].preset,
+                     ep93xx_clkset1_settings[i].pll1_ps,
+                     ep93xx_clkset1_settings[i].pdiv,
+                     ep93xx_clkset1_settings[i].hdiv,
+                     ep93xx_clkset1_settings[i].fdiv));
+    }
+    i++;
+  }
+  return(CLKSET1(ep93xx_clkset1_settings[0].preset,
+                 ep93xx_clkset1_settings[0].pll1_ps,
+                 ep93xx_clkset1_settings[0].pdiv,
+                 ep93xx_clkset1_settings[0].hdiv,
+                 ep93xx_clkset1_settings[0].fdiv));
+}
+
+static unsigned int ep93xx_validatespeed(unsigned int khz)
+{
+  int i = 0;
+
+  while (ep93xx_clkset1_settings[i].speed > 0) {
+    if (ep93xx_clkset1_settings[i].speed == khz) {
+      return(khz);
+    }
+    i++;
+  }
+  i = 0;
+  while (ep93xx_clkset1_settings[i].speed > 0) {
+    if (ep93xx_clkset1_settings[i].speed < khz) {
+      if (i == 0) {
+        return(ep93xx_clkset1_settings[i].speed);
+      } else {
+        int tohigher = ep93xx_clkset1_settings[i - 1].speed - khz;
+        int tolower = khz - ep93xx_clkset1_settings[i].speed;
+
+        return(tohigher > tolower ?
+               ep93xx_clkset1_settings[i].speed :
+               ep93xx_clkset1_settings[i - 1].speed);
+      }
+    }
+    i++;
+  }
+  return(ep93xx_clkset1_settings[i - 1].speed);
+}
+
+static void ep93xx_setspeed(unsigned int khz)
+{
+  u32 *clkset1ptr = IO_ADDRESS(SYSCON_CLKSET1);
+  unsigned long flags;
+
+  /* change the clk with interrupts disabled - remember note above
+   * on pll resync time */
+  local_irq_save(flags);
+  *clkset1ptr = ep93xx_get_clkset1(khz);
+  /* 5 nops required to fluch instruction pipeline */
+  __asm__ __volatile__("	\n\
+	nop			\n\
+	nop			\n\
+	nop			\n\
+	nop			\n\
+	nop");
+  local_irq_restore(flags);
+}
+
+static int __init ep93xx_clk_init(void)
+{
+  ep93xx_setspeed(INITIAL_SPEED);
+  cpufreq_init(INITIAL_SPEED, 10400, 200000);
+  cpufreq_setfunctions(ep93xx_validatespeed, ep93xx_setspeed);
+//  cpufreq_set(INITIAL_SPEED);
+  return 0;
+}
+
+__initcall(ep93xx_clk_init);
diff -Naurp linux-2.4-ts11/drivers/char/Config.in linux-2.4-ts11-hrt/drivers/char/Config.in
--- linux-2.4-ts11/drivers/char/Config.in	2005-10-20 23:21:55.000000000 +0200
+++ linux-2.4-ts11-hrt/drivers/char/Config.in	2008-05-26 11:12:35.000000000 +0200
@@ -270,6 +270,7 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
       dep_tristate '  DC21285 watchdog' CONFIG_21285_WATCHDOG $CONFIG_FOOTBRIDGE
       dep_tristate '  NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG $CONFIG_ARCH_NETWINDER
       dep_tristate '  SA1100 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_SA1100
+      dep_tristate '  EP93xx watchdog' CONFIG_EP93XX_WATCHDOG $CONFIG_ARCH_EP93XX
       dep_tristate '  EPXA watchdog' CONFIG_EPXA_WATCHDOG $CONFIG_ARCH_CAMELOT
       dep_tristate '  Omaha watchdog' CONFIG_OMAHA_WATCHDOG $CONFIG_ARCH_OMAHA
       dep_tristate '  AT91RM9200 watchdog' CONFIG_AT91_WATCHDOG $CONFIG_ARCH_AT91RM9200
diff -Naurp linux-2.4-ts11/drivers/char/Makefile linux-2.4-ts11-hrt/drivers/char/Makefile
--- linux-2.4-ts11/drivers/char/Makefile	2005-10-20 23:21:55.000000000 +0200
+++ linux-2.4-ts11-hrt/drivers/char/Makefile	2008-05-26 11:12:35.000000000 +0200
@@ -357,6 +357,7 @@ obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
 obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o
 obj-$(CONFIG_INDYDOG) += indydog.o
 obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
 
 # I2C char devices
 obj-$(CONFIG_I2C_DS1307) += ds1307.o
diff -Naurp linux-2.4-ts11/drivers/char/ep93xx_wdt.c linux-2.4-ts11-hrt/drivers/char/ep93xx_wdt.c
--- linux-2.4-ts11/drivers/char/ep93xx_wdt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4-ts11-hrt/drivers/char/ep93xx_wdt.c	2008-05-26 11:12:35.000000000 +0200
@@ -0,0 +1,223 @@
+/*
+ * drivers/watchdog/ep93xx_wdt.c
+ *
+ * Watchdog driver for Cirrus EP93xx family of devices.
+ *
+ * Author: Ray Lehtiniemi <rayl@mail.com>
+ *
+ * Copyright 2004 (c) Ray Lehtiniemi
+ * Based on ep93xx driver.
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * 20 May 2005 Works as module, tested, returns last rst from watchdog status
+ * Back ported to Technologic 2.4.26 kernel by Bob lees bob@diamond.demon.co.uk
+ */
+
+/*
+    Todo:
+
+    - test last rst from watchdog status, works Tested as part of backport
+    - test module loading, works Tested as part of backport
+    - test nowayout
+    - test all ioctl, add missing ones
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/arch/regmap.h>
+
+#define WD_VERSION "0.02"
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
+
+static unsigned long wdt_status;
+static unsigned long boot_status;
+
+#define        WDT_IN_USE              0
+#define        WDT_OK_TO_CLOSE         1
+
+static void
+wdt_enable(void)
+{
+       writel(0xaaaa, IO_ADDRESS(WATCHDOG));
+}
+
+static void
+wdt_disable(void)
+{
+       writel(0xaa55, IO_ADDRESS(WATCHDOG));
+}
+
+static void
+wdt_ping(void)
+{
+       writel(0x5555, IO_ADDRESS(WATCHDOG));
+}
+
+static int
+ep93xx_wdt_open(struct inode *inode, struct file *file)
+{
+       if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+               return -EBUSY;
+
+       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+       wdt_enable();
+
+       return 0;
+}
+
+static ssize_t
+ep93xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+       /* Can't seek (pwrite) on this device  */
+       if (*ppos != file->f_pos)
+               return -ESPIPE;
+
+       if (len) {
+               if (!nowayout) {
+                       size_t i;
+
+                       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+                       for (i = 0; i != len; i++) {
+                               char c;
+
+                               if (get_user(c, data + i))
+                                       return -EFAULT;
+
+                               if (c == 'V')
+                                       set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+                               else
+                                       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+                       }
+               }
+               wdt_ping();
+       }
+
+       return len;
+}
+
+static struct watchdog_info ident = {
+       .options        = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
+       .identity       = "EP93xx Watchdog",
+};
+
+
+static int
+ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+                       unsigned long arg)
+{
+       int ret = -ENOIOCTLCMD;
+
+       switch (cmd) {
+       case WDIOC_GETSUPPORT:
+               ret = copy_to_user((struct watchdog_info *)arg, &ident,
+                                  sizeof(ident)) ? -EFAULT : 0;
+               break;
+
+       case WDIOC_GETSTATUS:
+              ret = put_user(0, (int *)arg);
+               break;
+
+       case WDIOC_GETBOOTSTATUS:
+               ret = put_user(boot_status, (int *)arg);
+              break;
+
+       case WDIOC_GETTIMEOUT:
+               // actually, it is 0.250 seconds....
+               ret = put_user(1, (int *)arg);
+               break;
+
+       case WDIOC_KEEPALIVE:
+               wdt_ping();
+               ret = 0;
+               break;
+       }
+       return ret;
+}
+
+static int
+ep93xx_wdt_release(struct inode *inode, struct file *file)
+{
+       if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
+               wdt_disable();
+       } else {
+               printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
+                                       "timer will not stop\n");
+       }
+
+       clear_bit(WDT_IN_USE, &wdt_status);
+       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+       return 0;
+}
+
+
+static struct file_operations ep93xx_wdt_fops =
+{
+       .owner          = THIS_MODULE,
+       .write          = ep93xx_wdt_write,
+       .ioctl          = ep93xx_wdt_ioctl,
+       .open           = ep93xx_wdt_open,
+       .release        = ep93xx_wdt_release,
+};
+
+static struct miscdevice ep93xx_wdt_miscdev =
+{
+       .minor          = WATCHDOG_MINOR,
+       .name           = "EP93xx_Watchdog",
+       .fops           = &ep93xx_wdt_fops,
+};
+
+static int __init ep93xx_wdt_init(void)
+{
+       int ret;
+
+       ret = misc_register(&ep93xx_wdt_miscdev);
+
+       boot_status = readl(IO_ADDRESS(WATCHDOG))&0x7f;
+
+       printk("EP93xx Watchdog: Version " WD_VERSION "%s\n",
+               (readl(IO_ADDRESS(WATCHDOG))&0x08) ? " (nCS1 disable detected)" : "");
+
+       return ret;
+}
+
+static void __exit ep93xx_wdt_exit(void)
+{
+       misc_deregister(&ep93xx_wdt_miscdev);
+}
+
+
+module_init(ep93xx_wdt_init);
+module_exit(ep93xx_wdt_exit);
+
+MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>");
+MODULE_DESCRIPTION("EP93xx Watchdog");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
+
+MODULE_LICENSE("GPL");
+//MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
diff -Naurp linux-2.4-ts11/include/asm-arm/arch-ep93xx/time.h linux-2.4-ts11-hrt/include/asm-arm/arch-ep93xx/time.h
--- linux-2.4-ts11/include/asm-arm/arch-ep93xx/time.h	2006-06-17 01:25:15.000000000 +0200
+++ linux-2.4-ts11-hrt/include/asm-arm/arch-ep93xx/time.h	2008-05-26 11:12:35.000000000 +0200
@@ -24,18 +24,66 @@
 #include <asm/arch/hardware.h>
 
 /* First timer channel used for timer interrupt */
+#define TIMER1_INTERVAL 508469
+
+/*************************************************************************
+ * Timer handling for EP93xx
+ *************************************************************************
+ * The ep93xx has four internal timers.  Timers 1, 2 (both 16 bit) and
+ * 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate
+ * an interrupt on underflow.  Timer 4 (40 bit) counts down at 983.04 kHz,
+ * is free-running, and can't generate interrupts.
+ *
+ * The 508 kHz timers are ideal for use for the timer interrupt, as the
+ * most common values of HZ divide 508 kHz nicely.  We pick one of the 16
+ * bit timers (timer 1) since we don't need more than 16 bits of reload
+ * value as long as HZ >= 8.
+ *
+ * The higher clock rate of timer 4 makes it a better choice than the
+ * other timers for use in gettimeoffset(), while the fact that it can't
+ * generate interrupts means we don't have to worry about not being able
+ * to use this timer for something else.  We also use timer 4 for keeping
+ * track of lost jiffies.
+ *
+ * From kernel 2.6.21, backported to 2.4.26 by Juerg Lehni
+ */
+static unsigned int last_jiffy_time;
+
+#define TIMER4_TICKS_PER_JIFFY		((CLOCK_TICK_RATE + (HZ/2)) / HZ)
 
 /*
  * IRQ handler for the timer
  */
 static void ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	write_lock(&xtime_lock);
 
     // ...clear the interrupt
-    outl( 1, TIMER1CLEAR );
+    outl(1, TIMER1CLEAR);
 
-    do_timer(regs);
+	while ((signed long)
+		(readl(IO_ADDRESS(TIMER4VALUELOW)) - last_jiffy_time)
+						>= TIMER4_TICKS_PER_JIFFY) {
+		last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
+		do_timer(regs);
+	}
     do_profile(regs);
+
+	write_unlock(&xtime_lock);
+}
+
+/*
+ * Returns number of usecs since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long ep93xx_gettimeoffset(void)
+{
+	int offset;
+
+	offset = readl(IO_ADDRESS(TIMER4VALUELOW)) - last_jiffy_time;
+
+	/* Calculate (1000000 / 983040) * offset.  */
+	return offset + (53 * offset / 3072);
 }
 
 /*
@@ -44,28 +92,26 @@ static void ep93xx_timer_interrupt(int i
 extern __inline__ void setup_timer(void)
 {
     timer_irq.handler = ep93xx_timer_interrupt;
-
+    
+    gettimeoffset = ep93xx_gettimeoffset;
+    
     /* 
      * Make irqs happen for the system timer
      */
     setup_arm_irq(IRQ_TIMER1, &timer_irq);
 
     /*
-     * Start timer 1, leave others alone
+     * Stop timer 1, leave others alone
      */
-    outl( 0, TIMER1CONTROL );
+    outl(0, TIMER1CONTROL);
 
-    /*
-     * Since the clock is giving u 2 uSeconds per tick,
-     * the timer load value is the timer interval
-     * divided by 2. 
-     */
-    outl( 5085, TIMER1LOAD );
-    outl( 5085, TIMER1VALUE);  /* countdown */
+    /* Enable lost jiffy timer.  */
+    outl(0x100, TIMER4VALUEHIGH);
 
-    /*
-     * Set up Timer 1 for 508 kHz clock and periodic mode.
-     */ 
-    outl( 0xC8, TIMER1CONTROL );
+    /* Enable periodic HZ timer.  */
+    outl(0x48, TIMER1CONTROL);
+    outl((TIMER1_INTERVAL / HZ) - 1, TIMER1LOAD);
+    outl(0xc8, TIMER1CONTROL);
 }
 
+
diff -Naurp linux-2.4-ts11/include/asm-arm/arch-ep93xx/time.orig.h linux-2.4-ts11-hrt/include/asm-arm/arch-ep93xx/time.orig.h
--- linux-2.4-ts11/include/asm-arm/arch-ep93xx/time.orig.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4-ts11-hrt/include/asm-arm/arch-ep93xx/time.orig.h	2008-05-26 11:12:35.000000000 +0200
@@ -0,0 +1,110 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/time.h
+ *
+ * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+ *
+ * Copyright (C) 2002-2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/arch/hardware.h>
+
+/* First timer channel used for timer interrupt */
+#define TIMER1INTERVAL (508469/HZ)
+#define TICKS2USECS(x) (((x) * 1000000) / TIMER1INTERVAL)
+
+static unsigned long timer_reload = TIMER_INTERVAL;
+
+/*
+ * IRQ handler for the timer
+ */
+static void ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	write_lock(&xtime_lock);
+
+    // ...clear the interrupt
+    outl(1, TIMER1CLEAR);
+
+    do_timer(regs);
+    do_profile(regs);
+
+	write_unlock(&xtime_lock);
+}
+
+/*
+ * Returns number of usecs since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long ep93xx_gettimeoffset(void)
+{
+    unsigned long ticks1, status;
+    /*
+     * Get the current number of ticks.  Note that there is a race
+     * condition between us reading the timer and checking for
+     * an interrupt.  We don't really mind if we have we are only going
+     * to be 1 clock tick (ish) out, 2usec or so which in the scheme
+     * of things should not be significant.
+     */
+    /*
+     * Number of ticks since last interrupt.
+    */
+    ticks1 = timer_reload - (inl(TIMER1VALUE) & 0xffff);
+    status = inl(VIC0RAWINTR);
+    /*
+     * Interrupt pending?  If so reload value be result.
+    */
+    if (status & (1 << IRQ_TIMER1))
+        ticks1 = timer_reload;
+    /*
+     * Convert the ticks to usecs
+     */
+    return TICKS2USECS(ticks1);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+extern __inline__ void setup_timer(void)
+{
+    timer_irq.handler = ep93xx_timer_interrupt;
+    
+    gettimeoffset = ep93xx_gettimeoffset;
+    
+    /* 
+     * Make irqs happen for the system timer
+     */
+    setup_arm_irq(IRQ_TIMER1, &timer_irq);
+
+    /*
+     * Stop timer 1, leave others alone
+     */
+    outl(0, TIMER1CONTROL);
+
+    /* Enable lost jiffy timer.  */
+    /* TODO:
+    outl(0x100, EP93XX_TIMER4_VALUE_HIGH);
+    */
+
+    /* Enable periodic HZ timer.  */
+    outl(0x48, TIMER1CONTROL);
+    outl(TIMER1INTERVAL - 1, TIMER1LOAD);
+	/* TODO: remove this once timeofday is timer 4 */
+    outl(TIMER1INTERVAL, TIMER1VALUE);  /* countdown */
+    outl(0xc8, TIMER1CONTROL);
+}
+
+
diff -Naurp linux-2.4-ts11/include/asm-arm/arch-ep93xx/timex.h linux-2.4-ts11-hrt/include/asm-arm/arch-ep93xx/timex.h
--- linux-2.4-ts11/include/asm-arm/arch-ep93xx/timex.h	2004-07-22 21:50:54.000000000 +0200
+++ linux-2.4-ts11-hrt/include/asm-arm/arch-ep93xx/timex.h	2008-05-26 11:12:35.000000000 +0200
@@ -1,26 +1,6 @@
 /*
- *  linux/include/asm-arm/arch-integrator/timex.h
- *
- *  Integrator architecture timex specifications
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * linux/include/asm-arm/arch-ep93xx/timex.h
  */
 
-/*
- * ??
- */
-#define CLOCK_TICK_RATE		(50000000 / 16)
+#define CLOCK_TICK_RATE		983040
+
