diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/include/asm-arm/arch-s3c2410/irqs.h linux-2.6.11-rc5-test2/include/asm-arm/arch-s3c2410/irqs.h
--- linux-2.6.11-rc5-test-base/include/asm-arm/arch-s3c2410/irqs.h	2005-03-01 01:04:54.000000000 +0000
+++ linux-2.6.11-rc5-test2/include/asm-arm/arch-s3c2410/irqs.h	2005-03-01 00:54:26.000000000 +0000
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/irqs.h
  *
- * Copyright (c) 2003 Simtec Electronics
+ * Copyright (c) 2003-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -12,6 +12,7 @@
  *  08-Jan-2003 BJD  Linux 2.6.0 version, moved BAST bits out
  *  12-Mar-2004 BJD  Fixed bug in header protection
  *  10-Feb-2005 BJD  Added camera IRQ from guillaume.gourat@nexvision.tv
+ *  28-Feb-2005 BJD  Updated s3c2440 IRQs
  */
 
 
@@ -36,8 +37,8 @@
 #define IRQ_EINT3      S3C2410_IRQ(3)
 #define IRQ_EINT4t7    S3C2410_IRQ(4)	    /* 20 */
 #define IRQ_EINT8t23   S3C2410_IRQ(5)
-#define IRQ_RESERVED6  S3C2410_IRQ(6)		/* for s3c2410 */
-#define IRQ_CAM        S3C2410_IRQ(6)		/* for s3c2440 */
+#define IRQ_RESERVED6  S3C2410_IRQ(6)	    /* for s3c2410 */
+#define IRQ_CAM        S3C2410_IRQ(6)	    /* for s3c2440 */
 #define IRQ_BATT_FLT   S3C2410_IRQ(7)
 #define IRQ_TICK       S3C2410_IRQ(8)	    /* 24 */
 #define IRQ_WDT	       S3C2410_IRQ(9)
@@ -56,6 +57,7 @@
 #define IRQ_SPI0       S3C2410_IRQ(22)
 #define IRQ_UART1      S3C2410_IRQ(23)
 #define IRQ_RESERVED24 S3C2410_IRQ(24)	    /* 40 */
+#define IRQ_NFCON      S3C2410_IRQ(24)	    /* for s3c2440 */
 #define IRQ_USBD       S3C2410_IRQ(25)
 #define IRQ_USBH       S3C2410_IRQ(26)
 #define IRQ_IIC	       S3C2410_IRQ(27)
@@ -111,7 +113,14 @@
 #define IRQ_TC		 S3C2410_IRQ(63)
 #define IRQ_ADC		 S3C2410_IRQ(64)
 
-#define NR_IRQS (IRQ_ADC+1)
+/* extra irqs for s3c2440 */
+
+#define IRQ_S3C2440_CAM_C	S3C2410_IRQ(65)
+#define IRQ_S3C2440_CAM_P	S3C2410_IRQ(66)
+#define IRQ_S3C2440_WDT		S3C2410_IRQ(67)
+#define IRQ_S3C2440_AC97	S3C2410_IRQ(68)
+
+#define NR_IRQS (IRQ_S3C2440_AC97+1)
 
 
 #endif /* __ASM_ARCH_IRQ_H */
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/clock.c linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/clock.c
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/clock.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/clock.c	2005-03-01 00:29:07.000000000 +0000
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-s3c2410/clock.c
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 Clock control support
  *
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/device.h>
+#include <linux/sysdev.h>
 
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -46,18 +47,13 @@
 #include <asm/arch/regs-clock.h>
 
 #include "clock.h"
+#include "cpu.h"
 
 /* clock information */
 
-unsigned long s3c24xx_xtal = 12*1000*1000;	/* default 12MHz */
-unsigned long s3c24xx_fclk;
-unsigned long s3c24xx_hclk;
-unsigned long s3c24xx_pclk;
-
 static LIST_HEAD(clocks);
 static DECLARE_MUTEX(clocks_sem);
 
-
 /* old functions */
 
 void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
@@ -206,6 +202,14 @@
 
 /* base clocks */
 
+static struct clk clk_xtal = {
+	.name		= "xtal",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
 static struct clk clk_f = {
 	.name		= "fclk",
 	.id		= -1,
@@ -286,6 +290,7 @@
 	  .ctrlbit = S3C2410_CLKCON_USBD
 	},
 	{ .name    = "timers",
+	  .id	   = -1,
 	  .parent  = &clk_p,
 	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_PWMT
@@ -378,19 +383,24 @@
 
 /* initalise all the clocks */
 
-int __init s3c24xx_setup_clocks(void)
+int __init s3c24xx_setup_clocks(unsigned long xtal,
+				unsigned long fclk,
+				unsigned long hclk,
+				unsigned long pclk)
 {
 	struct clk *clkp = init_clocks;
 	int ptr;
 	int ret;
 
-	printk(KERN_INFO "S3C2410 Clock control, (c) 2004 Simtec Electronics\n");
+	printk(KERN_INFO "S3C2410 Clocks, (c) 2004 Simtec Electronics\n");
 
 	/* initialise the main system clocks */
 
-	clk_h.rate = s3c24xx_hclk;
-	clk_p.rate = s3c24xx_pclk;
-	clk_f.rate = s3c24xx_fclk;
+	clk_xtal.rate = xtal;
+
+	clk_h.rate = hclk;
+	clk_p.rate = pclk;
+	clk_f.rate = fclk;
 
 	/* it looks like just setting the register here is not good
 	 * enough, and causes the odd hang at initial boot time, so
@@ -414,6 +424,9 @@
 
 	/* register our clocks */
 
+	if (s3c24xx_register_clock(&clk_xtal) < 0)
+		printk(KERN_ERR "failed to register master xtal\n");
+
 	if (s3c24xx_register_clock(&clk_f) < 0)
 		printk(KERN_ERR "failed to register cpu fclk\n");
 
@@ -423,6 +436,8 @@
 	if (s3c24xx_register_clock(&clk_p) < 0)
 		printk(KERN_ERR "failed to register cpu pclk\n");
 
+	/* register clocks from clock array */
+
 	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
 		ret = s3c24xx_register_clock(clkp);
 		if (ret < 0) {
@@ -434,4 +449,59 @@
 	return 0;
 }
 
+/* S3C2440 extended clock support */
+
+#ifdef CONFIG_CPU_S3C2440
+
+static struct clk s3c2440_clk_upll = {
+	.name		= "upll",
+	.id		= -1,
+};
+
+static struct clk s3c2440_clk_cam = {
+	.name		= "camif",
+	.parent		= &clk_h,
+	.id		= -1,
+	.enable		= s3c24xx_clkcon_enable,
+	.ctrlbit	= S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2440_clk_ac97 = {
+	.name		= "ac97",
+	.parent		= &clk_p,
+	.id		= -1,
+	.enable		= s3c24xx_clkcon_enable,
+	.ctrlbit	= S3C2440_CLKCON_CAMERA,
+};
+
+static int s3c2440_clk_add(struct sys_device *sysdev)
+{
+	unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
+
+	s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2;
+
+	printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
+	       print_mhz(s3c2440_clk_upll.rate));
+
+	s3c24xx_register_clock(&s3c2440_clk_ac97);
+	s3c24xx_register_clock(&s3c2440_clk_cam);
+	s3c24xx_register_clock(&s3c2440_clk_upll);
+
+	clk_disable(&s3c2440_clk_ac97);
+	clk_disable(&s3c2440_clk_cam);
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+	.add	= s3c2440_clk_add,
+};
+
+static int s3c24xx_clk_driver(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c24xx_clk_driver);
 
+#endif /* CONFIG_CPU_S3C2440 */
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/clock.h linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/clock.h
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/clock.h	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/clock.h	2005-03-01 00:29:07.000000000 +0000
@@ -1,7 +1,8 @@
 /*
  * linux/arch/arm/mach-s3c2410/clock.h
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
  *	Written by Ben Dooks, <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -29,13 +30,6 @@
 extern struct clk s3c24xx_clkout1;
 extern struct clk s3c24xx_uclk;
 
-/* processor clock settings, in Hz */
-
-extern unsigned long s3c24xx_xtal;
-extern unsigned long s3c24xx_pclk;
-extern unsigned long s3c24xx_hclk;
-extern unsigned long s3c24xx_fclk;
-
 /* exports for arch/arm/mach-s3c2410
  *
  * Please DO NOT use these outside of arch/arm/mach-s3c2410
@@ -44,4 +38,7 @@
 extern int s3c24xx_clkcon_enable(struct clk *clk, int enable);
 extern int s3c24xx_register_clock(struct clk *clk);
 
-extern int s3c24xx_setup_clocks(void);
+extern int s3c24xx_setup_clocks(unsigned long xtal,
+				unsigned long fclk,
+				unsigned long hclk,
+				unsigned long pclk);
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/cpu.c linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/cpu.c
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/cpu.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/cpu.c	2005-03-01 00:29:07.000000000 +0000
@@ -1,7 +1,8 @@
 /* linux/arch/arm/mach-s3c2410/cpu.c
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C24XX CPU Support
  *
@@ -181,8 +182,8 @@
 
 void __init s3c24xx_init_clocks(int xtal)
 {
-	if (xtal != 0)
-		s3c24xx_xtal = xtal;
+	if (xtal == 0)
+		xtal = 12*1000*1000;
 
 	if (cpu == NULL)
 		panic("s3c24xx_init_clocks: no cpu setup?\n");
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/cpu.h linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/cpu.h
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/cpu.h	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/cpu.h	2005-03-01 00:29:07.000000000 +0000
@@ -27,6 +27,7 @@
 
 /* forward declaration */
 struct s3c2410_uartcfg;
+struct map_desc;
 
 /* core initialisation functions */
 
@@ -58,3 +59,7 @@
 
 struct sys_timer;
 extern struct sys_timer s3c24xx_timer;
+
+/* system device classes */
+
+extern struct sysdev_class s3c2440_sysclass;
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/irq.c linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/irq.c
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/irq.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/irq.c	2005-03-01 01:02:28.000000000 +0000
@@ -57,6 +57,7 @@
 #include <asm/arch/regs-irq.h>
 #include <asm/arch/regs-gpio.h>
 
+#include "cpu.h"
 #include "pm.h"
 
 #define irqdbf(x...)
@@ -628,6 +629,7 @@
 	s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
 }
 
+
 /* s3c24xx_init_irq
  *
  * Initialise S3C2410 IRQ system
@@ -771,3 +773,174 @@
 
 	irqdbf("s3c2410: registered interrupt handlers\n");
 }
+
+/* s3c2440 irq code
+*/
+
+#ifdef CONFIG_CPU_S3C2440
+
+/* WDT/AC97 */
+
+static void s3c_irq_demux_wdtac97(unsigned int irq,
+				  struct irqdesc *desc,
+				  struct pt_regs *regs)
+{
+	unsigned int subsrc, submsk;
+	struct irqdesc *mydesc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc &= ~submsk;
+	subsrc >>= 13;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_S3C2440_WDT;
+			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_S3C2440_AC97;
+			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+		}
+	}
+}
+
+
+#define INTMSK_WDT	 (1UL << (IRQ_WDT - IRQ_EINT0))
+
+static void
+s3c_irq_wdtac97_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
+}
+
+static void
+s3c_irq_wdtac97_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_WDT);
+}
+
+static void
+s3c_irq_wdtac97_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
+}
+
+static struct irqchip s3c_irq_wdtac97 = {
+	.mask	    = s3c_irq_wdtac97_mask,
+	.unmask	    = s3c_irq_wdtac97_unmask,
+	.ack	    = s3c_irq_wdtac97_ack,
+};
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+			      struct irqdesc *desc,
+			      struct pt_regs *regs)
+{
+	unsigned int subsrc, submsk;
+	struct irqdesc *mydesc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc &= ~submsk;
+	subsrc >>= 11;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
+			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
+			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+		}
+	}
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+}
+
+static void
+s3c_irq_cam_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+}
+
+static struct irqchip s3c_irq_cam = {
+	.mask	    = s3c_irq_cam_mask,
+	.unmask	    = s3c_irq_cam_unmask,
+	.ack	    = s3c_irq_cam_ack,
+};
+
+static int s3c2440_irq_add(struct sys_device *sysdev)
+{
+	unsigned int irqno;
+
+	printk("S3C2440: IRQ Support\n");
+
+	set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_NFCON, do_level_IRQ);
+	set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+	/* add new chained handler for wdt, ac7 */
+
+	set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_WDT, do_level_IRQ);
+	set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+
+	for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_wdtac97);
+		set_irq_handler(irqno, do_level_IRQ);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	/* add chained handler for camera */
+
+	set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_CAM, do_level_IRQ);
+	set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+	for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_cam);
+		set_irq_handler(irqno, do_level_IRQ);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+	.add	= s3c2440_irq_add,
+};
+
+static int s3c24xx_irq_driver(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c24xx_irq_driver);
+
+#endif /* CONFIG_CPU_S3C2440 */
+
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/s3c2410.c linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/s3c2410.c
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/s3c2410.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/s3c2410.c	2005-03-01 00:29:07.000000000 +0000
@@ -17,7 +17,7 @@
  *     21-Aug-2004 BJD  Added new struct s3c2410_board handler
  *     28-Sep-2004 BJD  Updates for new serial port bits
  *     04-Nov-2004 BJD  Updated UART configuration process
- *     10-Jan-2004 BJD  Removed s3c2410_clock_tick_rate
+ *     10-Jan-2005 BJD  Removed s3c2410_clock_tick_rate
 */
 
 #include <linux/kernel.h>
@@ -164,31 +164,32 @@
 void __init s3c2410_init_clocks(int xtal)
 {
 	unsigned long tmp;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long pclk;
 
 	/* now we've got our machine bits initialised, work out what
 	 * clocks we've got */
 
-	s3c24xx_fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON),
-				       s3c24xx_xtal);
+	fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal);
 
 	tmp = __raw_readl(S3C2410_CLKDIVN);
 
 	/* work out clock scalings */
 
-	s3c24xx_hclk = s3c24xx_fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
-	s3c24xx_pclk = s3c24xx_hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
+	hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
+	pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
 
 	/* print brieft summary of clocks, etc */
 
 	printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(s3c24xx_fclk), print_mhz(s3c24xx_hclk),
-	       print_mhz(s3c24xx_pclk));
+	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
 
 	/* initialise the clocks here, to allow other things like the
 	 * console to use them
 	 */
 
-	s3c24xx_setup_clocks();
+	s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
 }
 
 int __init s3c2410_init(void)
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/s3c2440.c linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/s3c2440.c
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/s3c2440.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/s3c2440.c	2005-03-01 00:41:52.000000000 +0000
@@ -109,7 +109,6 @@
 	.resource	  = s3c_uart0_resource,
 };
 
-
 static struct platform_device s3c_uart1 = {
 	.name		  = "s3c2440-uart",
 	.id		  = 1,
@@ -149,19 +148,6 @@
 	s3c2440_uart_count = uart;
 }
 
-/* s3c2440 specific clock sources */
-
-static struct clk s3c2440_clk_cam = {
-	.name		= "camera",
-	.enable		= s3c24xx_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA
-};
-
-static struct clk s3c2440_clk_ac97 = {
-	.name		= "ac97",
-	.enable		= s3c24xx_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA
-};
 
 #ifdef CONFIG_PM
 
@@ -190,7 +176,7 @@
 #define s3c2440_resume  NULL
 #endif
 
-static struct sysdev_class s3c2440_sysclass = {
+struct sysdev_class s3c2440_sysclass = {
 	set_kset_name("s3c2440-core"),
 	.suspend	= s3c2440_suspend,
 	.resume		= s3c2440_resume
@@ -209,19 +195,24 @@
 	/* rename any peripherals used differing from the s3c2410 */
 
 	s3c_device_i2c.name = "s3c2440-i2c";
+
+	/* change irq for watchdog */
+
+	s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
+	s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
 }
 
 void __init s3c2440_init_clocks(int xtal)
 {
 	unsigned long clkdiv;
 	unsigned long camdiv;
-	int s3c2440_hdiv = 1;
+	unsigned long hclk, fclk, pclk;
+	int hdiv = 1;
 
 	/* now we've got our machine bits initialised, work out what
 	 * clocks we've got */
 
-	s3c24xx_fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON),
-				       s3c24xx_xtal) * 2;
+	fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
 
 	clkdiv = __raw_readl(S3C2410_CLKDIVN);
 	camdiv = __raw_readl(S3C2440_CAMDIVN);
@@ -230,63 +221,60 @@
 
 	switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
 	case S3C2440_CLKDIVN_HDIVN_1:
-		s3c2440_hdiv = 1;
+		hdiv = 1;
 		break;
 
 	case S3C2440_CLKDIVN_HDIVN_2:
-		s3c2440_hdiv = 1;
+		hdiv = 1;
 		break;
 
 	case S3C2440_CLKDIVN_HDIVN_4_8:
-		s3c2440_hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
 		break;
 
 	case S3C2440_CLKDIVN_HDIVN_3_6:
-		s3c2440_hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
 		break;
 	}
 
-	s3c24xx_hclk = s3c24xx_fclk / s3c2440_hdiv;
-	s3c24xx_pclk = s3c24xx_hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
+	hclk = fclk / hdiv;
+	pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
 
 	/* print brief summary of clocks, etc */
 
 	printk("S3C2440: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(s3c24xx_fclk), print_mhz(s3c24xx_hclk),
-	       print_mhz(s3c24xx_pclk));
+	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
 
 	/* initialise the clocks here, to allow other things like the
 	 * console to use them, and to add new ones after the initialisation
 	 */
 
-	s3c24xx_setup_clocks();
-
-	/* add s3c2440 specific clocks */
-
-	s3c2440_clk_cam.parent = clk_get(NULL, "hclk");
-	s3c2440_clk_ac97.parent = clk_get(NULL, "pclk");
+	s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+}
 
-	s3c24xx_register_clock(&s3c2440_clk_ac97);
-	s3c24xx_register_clock(&s3c2440_clk_cam);
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
 
-	clk_disable(&s3c2440_clk_ac97);
-	clk_disable(&s3c2440_clk_cam);
+int __init s3c2440_core_init(void)
+{
+	return sysdev_class_register(&s3c2440_sysclass);
 }
 
+core_initcall(s3c2440_core_init);
+
 int __init s3c2440_init(void)
 {
 	int ret;
 
 	printk("S3C2440: Initialising architecture\n");
 
-	ret = sysdev_class_register(&s3c2440_sysclass);
-	if (ret == 0)
-		ret = sysdev_register(&s3c2440_sysdev);
-
+	ret = sysdev_register(&s3c2440_sysdev);
 	if (ret != 0)
 		printk(KERN_ERR "failed to register sysdev for s3c2440\n");
-
-	if (ret == 0)
+	else
 		ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
 
 	return ret;
diff -urN -X ../dontdiff linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/time.c linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/time.c
--- linux-2.6.11-rc5-test-base/arch/arm/mach-s3c2410/time.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-test2/arch/arm/mach-s3c2410/time.c	2005-03-01 00:29:07.000000000 +0000
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/time.c
  *
- * Copyright (C) 2003,2004 Simtec Electronics
+ * Copyright (C) 2003-2005 Simtec Electronics
  *	Ben Dooks, <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,8 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
+
 #include <asm/system.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
@@ -33,6 +35,7 @@
 #include <asm/arch/regs-timer.h>
 #include <asm/arch/regs-irq.h>
 #include <asm/mach/time.h>
+#include <asm/hardware/clock.h>
 
 #include "clock.h"
 
@@ -169,6 +172,9 @@
 		tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
 		tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
 	} else {
+		unsigned long pclk;
+		struct clk *clk;
+
 		/* for the h1940 (and others), we use the pclk from the core
 		 * to generate the timer values. since values around 50 to
 		 * 70MHz are not values we can directly generate the timer
@@ -180,7 +186,18 @@
 
 		/* this is used as default if no other timer can be found */
 
-		timer_usec_ticks = timer_mask_usec_ticks(6, s3c24xx_pclk);
+		clk = clk_get(NULL, "timers");
+		if (IS_ERR(clk))
+			panic("failed to get clock for system timer");
+
+		clk_use(clk);
+		clk_enable(clk);
+
+		pclk = clk_get_rate(clk);
+
+		/* configure clock tick */
+
+		timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
 
 		tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
 		tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
@@ -188,7 +205,7 @@
 		tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
 		tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
 
-		tcnt = (s3c24xx_pclk / 6) / HZ;
+		tcnt = (pclk / 6) / HZ;
 	}
 
 	/* timers reload after counting zero, so reduce the count by 1 */
