diff -Nur linux-2.6.10-rc1-bk19/arch/arm/kernel/calls.S linux-2.6.10-rc1-bk19-h1940/arch/arm/kernel/calls.S
--- linux-2.6.10-rc1-bk19/arch/arm/kernel/calls.S	2004-10-18 23:55:36.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/kernel/calls.S	2004-11-09 21:18:14.000000000 +0100
@@ -236,7 +236,7 @@
 		.long	sys_mincore
 /* 220 */	.long	sys_madvise
 		.long	sys_fcntl64
-		.long	sys_ni_syscall /* TUX */
+		.long	sys_mhelper
 		.long	sys_ni_syscall
 		.long	sys_gettid
 /* 225 */	.long	sys_readahead
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/devs.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/devs.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/devs.c	2004-10-18 23:53:43.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/devs.c	2004-11-09 21:33:00.000000000 +0100
@@ -27,13 +27,19 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
-
+#include <asm/arch/s3c2410fb.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
+#include <asm/arch/regs-serial.h>
+
 #include "devs.h"
 
+/* Serial port registrations */
+
+struct platform_device *s3c24xx_uart_devs[3];
+
 /* USB Host Controller */
 
 static struct resource s3c_usb_resource[] = {
@@ -66,6 +72,15 @@
 
 /* LCD Controller */
 
+static struct s3c2410fb_mach_info s3c2410fb_info;
+
+void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info)
+{
+	memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info));
+}
+EXPORT_SYMBOL(set_s3c2410fb_info);
+
+
 static struct resource s3c_lcd_resource[] = {
 	[0] = {
 		.start = S3C2410_PA_LCD,
@@ -88,6 +103,7 @@
 	.num_resources	  = ARRAY_SIZE(s3c_lcd_resource),
 	.resource	  = s3c_lcd_resource,
 	.dev              = {
+ 		.platform_data	= &s3c2410fb_info,
 		.dma_mask = &s3c_device_lcd_dmamask,
 		.coherent_dma_mask = 0xffffffffUL
 	}
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/Kconfig linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/Kconfig
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/Kconfig	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/Kconfig	2004-11-09 21:33:00.000000000 +0100
@@ -26,6 +26,12 @@
 	   Say Y here if you are using the SMDK2410 or the derived module A9M2410
            <http://www.fsforth.de>
 
+config ARCH_S3C2440
+	bool "SMDK2440"
+	select CPU_S3C2440
+	help
+	  Say Y here if you are using an SMDK2440
+
 config MACH_VR1000
 	bool "Thorcom VR1000"
 	select CPU_S3C2410
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-bast.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-bast.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-bast.c	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-bast.c	2004-11-09 21:33:00.000000000 +0100
@@ -19,6 +19,7 @@
  *     06-Jan-2003 BJD  Updates for <arch/map.h>
  *     18-Jan-2003 BJD  Added serial port configuration
  *     05-Oct-2004 BJD  Power management code
+ *     04-Nov-2004 BJD  Updated serial port clocks
 */
 
 #include <linux/kernel.h>
@@ -47,6 +48,7 @@
 #include <asm/arch/regs-mem.h>
 
 #include "s3c2410.h"
+#include "clock.h"
 #include "devs.h"
 #include "cpu.h"
 #include "usb-simtec.h"
@@ -153,35 +155,50 @@
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 
-/* base baud rate for all our UARTs */
-static unsigned long bast_serial_clock = 24*1000*1000;
+static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
+	[0] = {
+		.name		= "uclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+	[1] = {
+		.name		= "pclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0.
+	}
+};
+
 
 static struct s3c2410_uartcfg bast_uartcfgs[] = {
 	[0] = {
 		.hwport	     = 0,
 		.flags	     = 0,
-		.clock	     = &bast_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
+		.clocks	     = bast_serial_clocks,
+		.clocks_size = ARRAY_SIZE(bast_serial_clocks)
 	},
 	[1] = {
 		.hwport	     = 1,
 		.flags	     = 0,
-
-		.clock	     = &bast_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
+		.clocks	     = bast_serial_clocks,
+		.clocks_size = ARRAY_SIZE(bast_serial_clocks)
 	},
 	/* port 2 is not actually used */
 	[2] = {
 		.hwport	     = 2,
 		.flags	     = 0,
-		.clock	     = &bast_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
+		.clocks	     = bast_serial_clocks,
+		.clocks_size = ARRAY_SIZE(bast_serial_clocks)
 	}
 };
 
@@ -214,13 +231,36 @@
 	&bast_device_nor
 };
 
+static struct clk *bast_clocks[] = {
+	&s3c24xx_dclk0,
+	&s3c24xx_dclk1,
+	&s3c24xx_clkout0,
+	&s3c24xx_clkout1,
+	&s3c24xx_uclk,
+};
+
 static struct s3c24xx_board bast_board __initdata = {
 	.devices       = bast_devices,
-	.devices_count = ARRAY_SIZE(bast_devices)
+	.devices_count = ARRAY_SIZE(bast_devices),
+	.clocks	       = bast_clocks,
+	.clocks_count  = ARRAY_SIZE(bast_clocks)
 };
 
 void __init bast_map_io(void)
 {
+	/* initialise the clocks */
+
+	s3c24xx_dclk0.parent = NULL;
+	s3c24xx_dclk0.rate   = 12*1000*1000;
+
+	s3c24xx_dclk1.parent = NULL;
+	s3c24xx_dclk1.rate   = 24*1000*1000;
+
+	s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+	s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
 	s3c2410_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
 	s3c24xx_set_board(&bast_board);
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-h1940.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-h1940.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-h1940.c	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-h1940.c	2004-11-09 21:33:00.000000000 +0100
@@ -19,6 +19,8 @@
  *     21-Aug-2004 BJD  Added struct s3c2410_board
  *     04-Sep-2004 BJD  Changed uart init, renamed ipaq_ -> h1940_
  *     18-Oct-2004 BJD  Updated new board structure name
+ *     03-Nov-2004 BJD  Updated for new LCD bits
+ *     04-Nov-2004 BJD  Change for new serial clock
 */
 
 #include <linux/kernel.h>
@@ -27,6 +29,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -40,7 +43,9 @@
 
 //#include <asm/debug-ll.h>
 #include <asm/arch/regs-serial.h>
-
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/s3c2410fb.h>
+ 
 #include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
@@ -58,7 +63,6 @@
 	[0] = {
 		.hwport	     = 0,
 		.flags	     = 0,
-		.clock	     = &s3c24xx_pclk,
 		.ucon	     = 0x3c5,
 		.ulcon	     = 0x03,
 		.ufcon	     = 0x51,
@@ -66,7 +70,6 @@
 	[1] = {
 		.hwport	     = 1,
 		.flags	     = 0,
-		.clock	     = &s3c24xx_pclk,
 		.ucon	     = 0x245,
 		.ulcon	     = 0x03,
 		.ufcon	     = 0x00,
@@ -75,15 +78,129 @@
 	[2] = {
 		.hwport	     = 2,
 		.flags	     = 0,
-		.clock	     = &s3c24xx_pclk,
 		.ucon	     = 0x3c5,
 		.ulcon	     = 0x43,
 		.ufcon	     = 0x51,
 	}
 };
 
+/**
+ * Set the backlight on or off.
+ **/
+static void h1940_backlight_power(int on)
+{
+	s3c2410_gpio_setpin(S3C2410_GPB0, 0);
+	s3c2410_gpio_pullup(S3C2410_GPB0, 0);
+
+	s3c2410_gpio_cfgpin(S3C2410_GPB0,
+			    (on) ? S3C2410_GPB0_TOUT0 : S3C2410_GPB0_OUTP);
+}
 
+/* Set the backlight pwm according to the level from wince */
 
+#include <asm/arch/regs-timer.h>
+static void h1940_set_brightness(int level)
+{
+	unsigned long tcfg0;
+	unsigned long tcfg1;
+	unsigned long tcmpb0=0x00;
+	unsigned long tcon;
+
+	/* configure power on/off */
+	h1940_backlight_power(level ? 1 : 0);
+
+	switch (level)
+	{
+		case 0:
+			break;
+		case 1:
+			tcmpb0=0x0b;
+			break;
+		default:
+		case 2:
+			tcmpb0=0x16;
+			break;	
+		case 3:
+			tcmpb0=0x21;
+			break;	
+		case 4:
+			tcmpb0=0x2c;
+			break;
+	}
+	
+	tcfg0=__raw_readl(S3C2410_TCFG0);
+	tcfg1=__raw_readl(S3C2410_TCFG1);
+	
+	tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
+	tcfg0 |= 0x18;
+
+	tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
+	tcfg1 |= S3C2410_TCFG1_MUX0_DIV2;
+
+	__raw_writel(tcfg0, S3C2410_TCFG0);
+	__raw_writel(tcfg1, S3C2410_TCFG1);
+	__raw_writel(0x31, S3C2410_TCNTB(0));
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon &= ~0x0F;
+	tcon |= S3C2410_TCON_T0RELOAD;
+	tcon |= S3C2410_TCON_T0MANUALUPD;
+
+	__raw_writel(tcon, S3C2410_TCON);
+	__raw_writel(0x31, S3C2410_TCNTB(0));
+	__raw_writel(tcmpb0, S3C2410_TCMPB(0));
+
+	/* start the timer running */
+	tcon |= S3C2410_TCON_T0START;
+	tcon &= ~S3C2410_TCON_T0MANUALUPD;
+	__raw_writel(tcon, S3C2410_TCON);
+}
+
+#include <asm/arch/regs-lcd.h>
+
+static struct s3c2410fb_mach_info h1940_lcdcfg = {
+	.lcdcon1=	S3C2410_LCDCON1_TFT16BPP | \
+			S3C2410_LCDCON1_TFT | \
+			S3C2410_LCDCON1_CLKVAL(0x0C),
+	
+	.lcdcon2=	S3C2410_LCDCON2_VBPD(7) | \
+			S3C2410_LCDCON2_LINEVAL(319) | \
+			S3C2410_LCDCON2_VFPD(6) | \
+			S3C2410_LCDCON2_VSPW(0),
+			  
+	.lcdcon3=	S3C2410_LCDCON3_HBPD(19) | \
+			S3C2410_LCDCON3_HOZVAL(239) | \
+			S3C2410_LCDCON3_HFPD(7),
+			  
+	.lcdcon4=	S3C2410_LCDCON4_MVAL(0) | \
+			S3C2410_LCDCON4_HSPW(3),
+	
+	.lcdcon5=	S3C2410_LCDCON5_FRM565 | \
+			S3C2410_LCDCON5_INVVLINE | \
+			S3C2410_LCDCON5_HWSWP,
+	.lpcsel=	0x02,
+	.gpccon=	0xaa940659,
+	.gpccon_mask=	0xffffffff,
+	.gpcup=		0x0000ffff,
+	.gpcup_mask=	0xffffffff,
+	.gpdcon=	0xaa84aaa0,
+	.gpdcon_mask=	0xffffffff,
+	.gpdup=		0x0000faff,
+	.gpdup_mask=	0xffffffff,
+
+	.width=		240,
+	.height=	320,
+	.xres=		240,
+	.yres=		320,
+	.bpp=		16,
+
+	.backlight_min		= 0,
+	.backlight_max		= 4,
+	.backlight_default	= 2,
+
+	.backlight_power	= h1940_backlight_power,
+	.set_brightness		= h1940_set_brightness,
+};
 
 static struct platform_device *h1940_devices[] __initdata = {
 	&s3c_device_usb,
@@ -91,6 +208,7 @@
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&s3c_device_usbgadget,
 };
 
 static struct s3c24xx_board h1940_board __initdata = {
@@ -111,11 +229,17 @@
 
 }
 
+void __init h1940_init(void)
+{
+	s3c_device_lcd.dev.platform_data = &h1940_lcdcfg;
+}
+		
 MACHINE_START(H1940, "IPAQ-H1940")
      MAINTAINER("Ben Dooks <ben@fluff.org>")
      BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(h1940_map_io)
      INITIRQ(h1940_init_irq)
+     INIT_MACHINE(h1940_init)
      .timer		= &s3c2410_timer,
 MACHINE_END
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-smdk2410.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-smdk2410.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-smdk2410.c	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-smdk2410.c	2004-11-09 21:33:00.000000000 +0100
@@ -58,14 +58,10 @@
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 
-/* base baud rate for all our UARTs */
-static unsigned long smdk2410_serial_clock = 24*1000*1000;
-
 static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
 	[0] = {
 		.hwport	     = 0,
 		.flags	     = 0,
-		.clock	     = &smdk2410_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
@@ -73,7 +69,6 @@
 	[1] = {
 		.hwport	     = 1,
 		.flags	     = 0,
-		.clock	     = &smdk2410_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
@@ -81,7 +76,6 @@
 	[2] = {
 		.hwport	     = 2,
 		.flags	     = 0,
-		.clock	     = &smdk2410_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-smdk2440.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-smdk2440.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-smdk2440.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-smdk2440.c	2004-11-09 21:33:00.000000000 +0100
@@ -0,0 +1,146 @@
+/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ *	01-Nov-2004 BJD Initial version
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/idle.h>
+
+#include "s3c2410.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+
+static struct map_desc smdk2440_iodesc[] __initdata = {
+	/* ISA IO Space map (memory space selected by A24) */
+
+	{ S3C2410_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE },
+	{ S3C2410_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2440_uartcfgs[] = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	/* IR port */
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x43,
+		.ufcon	     = 0x51,
+	}
+};
+
+static struct platform_device *smdk2440_devices[] __initdata = {
+	&s3c_device_usb,
+	&s3c_device_lcd,
+	&s3c_device_wdt,
+	&s3c_device_i2c,
+	&s3c_device_iis,
+};
+
+static struct s3c24xx_board smdk2440_board __initdata = {
+	.devices       = smdk2440_devices,
+	.devices_count = ARRAY_SIZE(smdk2440_devices)
+};
+
+void __init smdk2440_map_io(void)
+{
+	s3c24xx_xtal = 16934400;
+
+	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
+	s3c2440_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+	s3c24xx_set_board(&smdk2440_board);
+}
+
+void __init smdk2440_init_irq(void)
+{
+	s3c2410_init_irq();
+}
+
+/* smdk2440_idle
+ *
+ * set LED7 during idle phase
+*/
+
+static void smdk2440_idle(void)
+{
+	unsigned int pin = S3C2410_GPF7;
+
+	s3c2410_gpio_setpin(pin, 0);
+	s3c24xx_default_idle();
+	s3c2410_gpio_setpin(pin, 1);
+}
+
+void __init smdk2440_machine_init(void)
+{
+	/* Configure the LEDs */
+
+	s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
+	s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
+	s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
+	s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
+
+	s3c2410_gpio_setpin(S3C2410_GPF4, 0);
+	s3c2410_gpio_setpin(S3C2410_GPF5, 1);
+	s3c2410_gpio_setpin(S3C2410_GPF6, 1);
+	s3c2410_gpio_setpin(S3C2410_GPF7, 1);
+
+	s3c24xx_idle = smdk2440_idle;
+}
+
+MACHINE_START(S3C2440, "SMDK2440")
+     MAINTAINER("Ben Dooks <ben@fluff.org>")
+     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
+     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+     MAPIO(smdk2440_map_io)
+     INITIRQ(smdk2440_init_irq)
+     INIT_MACHINE(smdk2440_machine_init)
+
+     .timer		= &s3c2410_timer,
+MACHINE_END
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-vr1000.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-vr1000.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/mach-vr1000.c	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/mach-vr1000.c	2004-11-09 21:33:00.000000000 +0100
@@ -17,6 +17,7 @@
  *     06-Aug-2004 BJD  Fixed call to time initialisation
  *     05-Apr-2004 BJD  Copied to make mach-vr1000.c
  *     18-Oct-2004 BJD  Updated board struct
+ *     04-Nov-2004 BJD  Clock and serial configuration update
 */
 
 #include <linux/kernel.h>
@@ -42,6 +43,7 @@
 #include <asm/arch/regs-serial.h>
 
 #include "s3c2410.h"
+#include "clock.h"
 #include "devs.h"
 #include "cpu.h"
 #include "usb-simtec.h"
@@ -113,34 +115,52 @@
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 
-/* base baud rate for all our UARTs */
-static unsigned long vr1000_serial_clock = 3692307;
+/* uart clock source(s) */
+
+static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
+	[0] = {
+		.name		= "uclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+	[1] = {
+		.name		= "pclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0.
+	}
+};
 
 static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
 	[0] = {
 		.hwport	     = 0,
 		.flags	     = 0,
-		.clock	     = &vr1000_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
+		.clocks	     = vr1000_serial_clocks,
+		.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
 	},
 	[1] = {
 		.hwport	     = 1,
 		.flags	     = 0,
-		.clock	     = &vr1000_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
+		.clocks	     = vr1000_serial_clocks,
+		.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
 	},
 	/* port 2 is not actually used */
 	[2] = {
 		.hwport	     = 2,
 		.flags	     = 0,
-		.clock	     = &vr1000_serial_clock,
 		.ucon	     = UCON,
 		.ulcon	     = ULCON,
 		.ufcon	     = UFCON,
+		.clocks	     = vr1000_serial_clocks,
+		.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
+
 	}
 };
 
@@ -152,14 +172,37 @@
 	&s3c_device_iis,
 };
 
+static struct clk *vr1000_clocks[] = {
+	&s3c24xx_dclk0,
+	&s3c24xx_dclk1,
+	&s3c24xx_clkout0,
+	&s3c24xx_clkout1,
+	&s3c24xx_uclk,
+};
+
 static struct s3c24xx_board vr1000_board __initdata = {
 	.devices       = vr1000_devices,
-	.devices_count = ARRAY_SIZE(vr1000_devices)
+	.devices_count = ARRAY_SIZE(vr1000_devices),
+	.clocks	       = vr1000_clocks,
+	.clocks_count  = ARRAY_SIZE(vr1000_clocks),
 };
 
 
 void __init vr1000_map_io(void)
 {
+	/* initialise clock sources */
+
+	s3c24xx_dclk0.parent = NULL;
+	s3c24xx_dclk0.rate   = 12*1000*1000;
+
+	s3c24xx_dclk1.parent = NULL;
+	s3c24xx_dclk1.rate   = 3692307;
+
+	s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+	s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
 	s3c2410_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 	s3c24xx_set_board(&vr1000_board);
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/Makefile linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/Makefile
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/Makefile	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/Makefile	2004-11-09 21:33:00.000000000 +0100
@@ -28,5 +28,6 @@
 obj-$(CONFIG_ARCH_BAST)		+= mach-bast.o usb-simtec.o
 obj-$(CONFIG_ARCH_H1940)	+= mach-h1940.o
 obj-$(CONFIG_ARCH_SMDK2410)	+= mach-smdk2410.o
+obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2440.o
 obj-$(CONFIG_MACH_VR1000)	+= mach-vr1000.o usb-simtec.o
 
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/s3c2410.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/s3c2410.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/s3c2410.c	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/s3c2410.c	2004-11-09 21:33:00.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-s3c2410/s3c2410.c
  *
  * Copyright (c) 2003,2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
  *
@@ -16,6 +16,7 @@
  *     18-Jan-2004 BJD  Added serial port configuration
  *     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
 */
 
 #include <linux/kernel.h>
@@ -43,14 +44,11 @@
 
 int s3c2410_clock_tick_rate = 12*1000*1000;  /* current timers at 12MHz */
 
-/* serial port setup */
-
-struct s3c2410_uartcfg *s3c2410_uartcfgs;
-
 /* Initial IO mappings */
 
-static struct map_desc s3c2410_iodesc[] __initdata = {
+struct map_desc s3c2410_iodesc[] __initdata = {
 	IODESC_ENT(USBHOST),
+	IODESC_ENT(USBDEV),
 	IODESC_ENT(CLKPWR),
 	IODESC_ENT(LCD),
 	IODESC_ENT(UART),
@@ -59,6 +57,8 @@
 	IODESC_ENT(WATCHDOG)
 };
 
+unsigned long s3c2410_iodesc_size = ARRAY_SIZE(s3c2410_iodesc);
+
 static struct resource s3c_uart0_resource[] = {
 	[0] = {
 		.start = S3C2410_PA_UART0,
@@ -141,12 +141,10 @@
 	struct platform_device *platdev;
 	int uart;
 
-	s3c2410_uartcfgs = cfg;		/* compatibility */
-
 	for (uart = 0; uart < no; uart++, cfg++) {
 		platdev = uart_devices[cfg->hwport];
 
-		s3c2410_uart_devices[uart] = platdev;
+		s3c24xx_uart_devs[uart] = platdev;
 		platdev->dev.platform_data = cfg;
 	}
 
@@ -199,10 +197,7 @@
 
 int __init s3c2410_init(void)
 {
-	int ret;
-
 	printk("S3C2410: Initialising architecture\n");
 
-	ret = platform_add_devices(uart_devices, ARRAY_SIZE(uart_devices));
-	return ret;
+	return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count);
 }
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/s3c2440.c linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/s3c2440.c
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/s3c2440.c	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/s3c2440.c	2004-11-09 21:33:00.000000000 +0100
@@ -13,6 +13,7 @@
  *	24-Aug-2004 BJD  Start of s3c2440 support
  *	12-Oct-2004 BJD	 Moved clock info out to clock.c
  *	01-Nov-2004 BJD  Fixed clock build code
+ *	04-Nov-2004 BJD  New serial registration
 */
 
 #include <linux/kernel.h>
@@ -122,6 +123,25 @@
 	&s3c_uart2
 };
 
+/* uart initialisation */
+
+static int __initdata s3c2440_uart_count;
+
+void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	struct platform_device *platdev;
+	int uart;
+
+	for (uart = 0; uart < no; uart++, cfg++) {
+		platdev = uart_devices[cfg->hwport];
+
+		s3c24xx_uart_devs[uart] = platdev;
+		platdev->dev.platform_data = cfg;
+	}
+
+	s3c2440_uart_count = uart;
+}
+
 /* s3c2440 specific clock sources */
 
 static struct clk s3c2440_clk_cam = {
@@ -206,11 +226,8 @@
 
 int __init s3c2440_init(void)
 {
-	int ret;
-
 	printk("S3C2440: Initialising architecture\n");
 
-	ret = platform_add_devices(uart_devices, ARRAY_SIZE(uart_devices));
-	return ret;
+	return platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
 }
 
diff -Nur linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/s3c2440.h linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/s3c2440.h
--- linux-2.6.10-rc1-bk19/arch/arm/mach-s3c2410/s3c2440.h	2004-10-18 23:54:38.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/arch/arm/mach-s3c2410/s3c2440.h	2004-11-09 21:33:01.000000000 +0100
@@ -10,9 +10,14 @@
  * published by the Free Software Foundation.
  *
  * Modifications:
- *     24-Aug-2004 BJD  Start of S3C2440 CPU support
+ *	24-Aug-2004 BJD  Start of S3C2440 CPU support
+ *	04-Nov-2004 BJD  Added s3c2440_init_uarts()
 */
 
+struct s3c2410_uartcfg;
+
 extern void s3c2440_init_irq(void);
 
 extern void s3c2440_init_time(void);
+
+extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
diff -Nur linux-2.6.10-rc1-bk19/drivers/input/touchscreen/h1940ts.c linux-2.6.10-rc1-bk19-h1940/drivers/input/touchscreen/h1940ts.c
--- linux-2.6.10-rc1-bk19/drivers/input/touchscreen/h1940ts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/input/touchscreen/h1940ts.c	2004-11-09 21:18:18.000000000 +0100
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * iPAQ H1940 touchscreen support
+ *
+ * ChangeLog
+ *
+ * 2004-09-05: Herbert PÃ¶tzl <herbert@13thfloor.at>
+ *	- added clock (de-)allocation code
+ *
+ */
+/*
+ * 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 <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-adc.h>
+#include <asm/hardware/clock.h>
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("h1940 touchscreen driver");
+MODULE_LICENSE("GPL");
+
+#undef	KERN_DEBUG
+#define	KERN_DEBUG	"ts: "
+
+/*
+ * Definitions & global arrays.
+ */
+
+
+static char *h1940ts_name = "h1940 TouchScreen";
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct h1940ts {
+	struct input_dev dev;
+	long xp;
+	long yp;
+	char phys[32];
+};
+
+static struct h1940ts ts;
+
+static irqreturn_t stylus_down(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long adctsc;
+	unsigned long adccon;
+	unsigned long data0;
+	unsigned long data1;
+	disable_irq(IRQ_TC);
+	
+	adccon = __raw_readl(S3C2410_ADCCON);
+	adctsc = __raw_readl(S3C2410_ADCTSC);
+	data0  = __raw_readl(S3C2410_ADCDAT0);
+	data1  = __raw_readl(S3C2410_ADCDAT1);
+
+
+	printk(KERN_DEBUG "stylus down\n");
+	// BUG_ON(1);
+
+	/* start X conversion */
+	adctsc &= ~0x07;
+	adctsc |= 1;
+	__raw_writel(adctsc,S3C2410_ADCTSC);
+	__raw_writel(adccon|1,S3C2410_ADCCON);
+
+	enable_irq(IRQ_TC);
+	return IRQ_HANDLED;
+}
+
+
+static irqreturn_t stylus_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long adccon;
+	unsigned long data0;
+	unsigned long data1;
+	unsigned long adctsc;
+	
+	disable_irq(IRQ_ADC);
+
+	adccon = __raw_readl(S3C2410_ADCCON);
+	adctsc = __raw_readl(S3C2410_ADCTSC);
+
+	switch(adctsc & 3)
+	{
+	case 1: /* X conversion ended, starts Y conversion */
+		adctsc &= ~0x07;
+		adctsc |= 2;
+		__raw_writel(adctsc,S3C2410_ADCTSC);
+		data0  = __raw_readl(S3C2410_ADCDAT0);
+		ts.xp=data0&0x3FF;
+		printk(KERN_DEBUG "X : %ld, U/D: %ld\n",data0&0x3FF,data0>>15);
+		__raw_writel(adccon|1,S3C2410_ADCCON);
+		break;
+	case 2:
+		adctsc &= ~0x07;
+		adctsc |= 3;
+		__raw_writel(adctsc,S3C2410_ADCTSC);
+		data1  = __raw_readl(S3C2410_ADCDAT1);
+		ts.yp = data1&0x3FF;
+		printk(KERN_DEBUG "Y : %ld, U/D: %ld\n",data1&0x3FF,data1>>15);
+		input_report_abs(&ts.dev, ABS_X, ts.xp);
+		input_report_abs(&ts.dev, ABS_Y, ts.yp);
+		input_report_key(&ts.dev, BTN_TOUCH, 1);
+		input_sync(&ts.dev);
+
+		/* if stylus down, starts X conversion */
+		if (!(data1>>15))
+		{
+			adctsc &= ~0x07;
+			adctsc |= 1;
+			__raw_writel(adctsc,S3C2410_ADCTSC);
+			__raw_writel(adccon|1,S3C2410_ADCCON);
+		}
+		break;
+	default:
+		break;
+	}
+
+	enable_irq(IRQ_ADC);
+	return IRQ_HANDLED;
+}
+
+
+static struct clk	*adc_clock;
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+int __init h1940ts_init(void)
+{
+	
+	printk(KERN_DEBUG "Entering h1940ts_connect\n");
+
+	adc_clock = clk_get(NULL, "adc");
+	if (!adc_clock) {
+		printk(KERN_ERR "failed to get adc clock source\n");
+		return -ENOENT;
+	}
+	clk_use(adc_clock);
+	clk_enable(adc_clock);
+	printk(KERN_INFO "got and enabled clock\n");
+
+	/* probably not required */
+	msleep(10);
+
+	/* Initialise registers */
+	__raw_writel(0xcc78,  S3C2410_ADCCON);
+	__raw_writel(  0xD3,  S3C2410_ADCTSC);
+	__raw_writel(0x2710,  S3C2410_ADCDLY);
+	__raw_writel(0xb1b4, S3C2410_ADCDAT0);
+	__raw_writel(0xb24c, S3C2410_ADCDAT1);
+
+	
+	memset(&ts, 0, sizeof(struct h1940ts));
+
+	init_input_dev(&ts.dev);
+	ts.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	ts.dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+/*	input_set_abs_params(&ts.dev, ABS_X, 0, 0x3FF, 0, 0);
+	input_set_abs_params(&ts.dev, ABS_Y, 0, 0x3FF, 0, 0);*/
+
+	sprintf(ts.phys, "ts0");
+
+	ts.dev.private = &ts;
+	ts.dev.name = h1940ts_name;
+	ts.dev.phys = ts.phys;
+	ts.dev.id.bustype = BUS_RS232;
+	ts.dev.id.vendor = 0xDEAD;
+	ts.dev.id.product = 0xBEEF;
+	ts.dev.id.version = 0x0100;
+
+	if (request_irq(IRQ_ADC, stylus_action, SA_SAMPLE_RANDOM,
+		"h1940_action", &ts.dev)) {
+		printk(KERN_ERR "h1940ts.c: Could not allocate ts IRQ_ADC !\n");
+		return -EIO;
+	}
+	if (request_irq(IRQ_TC, stylus_down, SA_SAMPLE_RANDOM,
+			"h1940_action", &ts.dev)) {
+		printk(KERN_ERR "h1940ts.c: Could not allocate ts IRQ_TC !\n");
+		return -EIO;
+	}
+
+	printk(KERN_DEBUG "input: %s on ts0\n", h1940ts_name);
+
+	input_register_device(&ts.dev);
+	return 0;
+}
+
+void __exit h1940ts_exit(void)
+{
+	disable_irq(IRQ_ADC);
+	disable_irq(IRQ_TC);
+	free_irq(IRQ_TC,&ts.dev);
+	free_irq(IRQ_ADC,&ts.dev);
+
+	if (adc_clock) {
+		clk_disable(adc_clock);
+		clk_unuse(adc_clock);
+		clk_put(adc_clock);
+		adc_clock = NULL;
+	}
+	
+	input_unregister_device(&ts.dev);
+}
+
+module_init(h1940ts_init);
+module_exit(h1940ts_exit);
diff -Nur linux-2.6.10-rc1-bk19/drivers/input/touchscreen/Kconfig linux-2.6.10-rc1-bk19-h1940/drivers/input/touchscreen/Kconfig
--- linux-2.6.10-rc1-bk19/drivers/input/touchscreen/Kconfig	2004-10-18 23:54:08.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/drivers/input/touchscreen/Kconfig	2004-11-09 21:18:18.000000000 +0100
@@ -22,6 +22,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called h3600_ts_input.
 
+config TOUCHSCREEN_H1940
+	tristate "HP iPAQ H1940 touchscreen input driver"
+	depends on ARCH_H1940 && INPUT && INPUT_TOUCHSCREEN
+	select SERIO
+	help
+	  Say Y here if you have the h1940 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called h1940ts_input.
+
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	depends on INPUT && INPUT_TOUCHSCREEN
diff -Nur linux-2.6.10-rc1-bk19/drivers/input/touchscreen/Makefile linux-2.6.10-rc1-bk19-h1940/drivers/input/touchscreen/Makefile
--- linux-2.6.10-rc1-bk19/drivers/input/touchscreen/Makefile	2004-10-18 23:55:07.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/drivers/input/touchscreen/Makefile	2004-11-09 21:18:18.000000000 +0100
@@ -4,5 +4,7 @@
 
 # Each configuration option enables a list of files.
 
+
 obj-$(CONFIG_TOUCHSCREEN_BITSY)	+= h3600_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_H1940)	+= h1940ts.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)	+= gunze.o
diff -Nur linux-2.6.10-rc1-bk19/drivers/serial/s3c2410.c linux-2.6.10-rc1-bk19-h1940/drivers/serial/s3c2410.c
--- linux-2.6.10-rc1-bk19/drivers/serial/s3c2410.c	2004-10-18 23:54:08.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/drivers/serial/s3c2410.c	2004-11-09 21:33:00.000000000 +0100
@@ -1,7 +1,7 @@
 /*
- * linux/drivers/char/s3c2410.c
+ * linux/drivers/serial/s3c2410.c
  *
- * Driver for onboard UARTs on the Samsung S3C2410
+ * Driver for onboard UARTs on the Samsung S3C24XX
  *
  * Based on drivers/char/serial.c and drivers/char/21285.c
  *
@@ -9,54 +9,150 @@
  *
  * Changelog:
  *
- */
+ * 22-Jul-2004  BJD  Finished off device rewrite
+ *
+ * 21-Jul-2004  BJD  Thanks to <herbet@13thfloor.at> for pointing out
+ *                   problems with baud rate and loss of IR settings. Update
+ *                   to add configuration via platform_device structure
+ *
+ * 28-Sep-2004  BJD  Re-write for the following items
+ *		     - S3C2410 and S3C2440 serial support
+ *		     - Power Management support
+ *		     - Fix console via IrDA devices
+ *		     - SysReq (Herbert Pötzl)
+ *		     - Break character handling (Herbert Pötzl)
+ *		     - spin-lock initialisation (Dimitry Andric)
+ *		     - added clock control
+*/
+
+/* Hote on 2410 error handling
+ *
+ * The s3c2410 manual has a love/hate affair with the contents of the
+ * UERSTAT register in the UART blocks, and keeps marking some of the
+ * error bits as reserved. Having checked with the s3c2410x01,
+ * it copes with BREAKs properly, so I am happy to ignore the RESERVED
+ * feature from the latter versions of the manual.
+ *
+ * If it becomes aparrent that latter versions of the 2410 remove these
+ * bits, then action will have to be taken to differentiate the versions
+ * and change the policy on BREAK
+ *
+ * BJD, 04-Nov-2004
+*/
+
 #include <linux/config.h>
+
+#if defined(CONFIG_SERIAL_S3C2410_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/sysrq.h>
 #include <linux/console.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/clock.h>
+
 #include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/mach-types.h>
+
+/* structures */
+
+struct s3c24xx_uart_info {
+	char			*name;
+	unsigned int		type;
+	unsigned int		fifosize;
+	unsigned long		rx_fifomask;
+	unsigned long		rx_fifoshift;
+	unsigned long		tx_fifomask;
+	unsigned long		tx_fifoshift;
+	unsigned long		tx_fifofull;
+
+	/* clock source control */
+
+	int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
+	int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
+};
+
+struct s3c24xx_uart_port {
+	unsigned char			rx_claimed;
+	unsigned char			tx_claimed;
+       
+	struct s3c24xx_uart_info	*info;
+	struct s3c24xx_uart_clksrc	*clksrc;
+	struct clk			*clk;
+	struct clk			*baudclk;
+	struct uart_port		port;
+};
+
+
+/* configuration defines */
 
 #if 0
-#include <asm/debug-ll.h>
-#define dbg(x...) llprintk(x)
+#if 1
+/* send debug to the low-level output routines */
+
+extern void printascii(const char *);
+
+static void
+s3c24xx_serial_dbg(const char *fmt, ...)
+{
+	va_list va;
+	char buff[256];
+
+	va_start(va, fmt);
+	vsprintf(buff, fmt, va);
+	va_end(va);
+
+	printascii(buff);
+}
+
+#define dbg(x...) s3c24xx_serial_dbg(x)
+
 #else
-#define dbg(x...)
+#define dbg(x...) printk(KERN_DEBUG "s3c24xx: ");
+#endif
+#else /* no debug */
+#define dbg(x...) do {} while(0)
 #endif
 
-#define SERIAL_S3C2410_NAME	"ttySAC"
-#define SERIAL_S3C2410_MAJOR	204
-#define SERIAL_S3C2410_MINOR	64
+/* UART name and device definitions */
+
+#define S3C24XX_SERIAL_NAME	"ttySAC"
+#define S3C24XX_SERIAL_DEVFS    "tts/"
+#define S3C24XX_SERIAL_MAJOR	204
+#define S3C24XX_SERIAL_MINOR	64
+
+
+/* conversion functions */
+
+#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
+#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
 
 /* we can support 3 uarts, but not always use them */
 
 #define NR_PORTS (3)
 
-static const char serial_s3c2410_name[] = "Samsung S3C2410 UART";
-
 /* port irq numbers */
 
 #define TX_IRQ(port) ((port)->irq + 1)
 #define RX_IRQ(port) ((port)->irq)
 
-#define tx_enabled(port) ((port)->unused[0])
-#define rx_enabled(port) ((port)->unused[1])
-
-/* flag to ignore all characters comming in */
-#define RXSTAT_DUMMY_READ (0x10000000)
-
-/* access functions */
+/* register access controls */
 
-#define portaddr(port, reg) ((void *)((port)->membase + (reg)))
+#define portaddr(port, reg) ((void __iomem *)((port)->membase + (reg)))
 
 #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
 #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
@@ -67,58 +163,146 @@
 #define wr_regl(port, reg, val) \
   do { __raw_writel(val, portaddr(port, reg)); } while(0)
 
+/* macros to change one thing to another */
+
+#define tx_enabled(port) ((port)->unused[0])
+#define rx_enabled(port) ((port)->unused[1])
+
+/* flag to ignore all characters comming in */
+#define RXSTAT_DUMMY_READ (0x10000000)
+
+static int s3c24xx_serial_get_portno(struct uart_port *port);
+
+static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
+{
+	return container_of(port, struct s3c24xx_uart_port, port);
+}
+
+/* translate a port to the device name */
+
+static char *s3c24xx_serial_portname(struct uart_port *port)
+{
+	return to_platform_device(port->dev)->name;
+}
+
+static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
+{
+	return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
+}
+
+static void s3c24xx_serial_rx_enable(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int ucon, ufcon;
+	int count = 10000;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	while (--count && !s3c24xx_serial_txempty_nofifo(port))
+		udelay(100);
+
+	ufcon = rd_regl(port, S3C2410_UFCON);
+	ufcon |= S3C2410_UFCON_RESETRX;
+	wr_regl(port, S3C2410_UFCON, ufcon);
+
+	ucon = rd_regl(port, S3C2410_UCON);
+	ucon |= S3C2410_UCON_RXIRQMODE;
+	wr_regl(port, S3C2410_UCON, ucon);
+
+	rx_enabled(port) = 1;
+	spin_unlock_irqrestore(&port->lock, flags);
+}
 
+static void s3c24xx_serial_rx_disable(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int ucon;
 
+	spin_lock_irqsave(&port->lock, flags);
 
-/* code */
+	ucon = rd_regl(port, S3C2410_UCON);
+	ucon &= ~S3C2410_UCON_RXIRQMODE;
+	wr_regl(port, S3C2410_UCON, ucon);
+
+	rx_enabled(port) = 0;
+	spin_unlock_irqrestore(&port->lock, flags);
+}
 
 static void
-serial_s3c2410_stop_tx(struct uart_port *port, unsigned int tty_stop)
+s3c24xx_serial_stop_tx(struct uart_port *port, unsigned int tty_stop)
 {
 	if (tx_enabled(port)) {
 		disable_irq(TX_IRQ(port));
 		tx_enabled(port) = 0;
+		if (port->flags & UPF_CONS_FLOW)
+			s3c24xx_serial_rx_enable(port);
 	}
 }
 
 static void
-serial_s3c2410_start_tx(struct uart_port *port, unsigned int tty_start)
+s3c24xx_serial_start_tx(struct uart_port *port, unsigned int tty_start)
 {
 	if (!tx_enabled(port)) {
+		if (port->flags & UPF_CONS_FLOW)
+			s3c24xx_serial_rx_disable(port);
+
 		enable_irq(TX_IRQ(port));
 		tx_enabled(port) = 1;
 	}
 }
 
-static void serial_s3c2410_stop_rx(struct uart_port *port)
+
+static void s3c24xx_serial_stop_rx(struct uart_port *port)
 {
 	if (rx_enabled(port)) {
-		dbg("serial_s3c2410_stop_rx: port=%p\n", port);
+		dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
 		disable_irq(RX_IRQ(port));
 		rx_enabled(port) = 0;
 	}
 }
 
-static void serial_s3c2410_enable_ms(struct uart_port *port)
+static void s3c24xx_serial_enable_ms(struct uart_port *port)
+{
+}
+
+static struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port)
 {
+	return to_ourport(port)->info;
 }
 
+static struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
+{
+	if (port->dev == NULL)
+		return NULL;
+
+	return (struct s3c2410_uartcfg *)port->dev->platform_data;
+}
+
+static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
+				     unsigned long ufstat)
+{
+	struct s3c24xx_uart_info *info = ourport->info;
+	return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
+} 
+
+
 /* ? - where has parity gone?? */
 #define S3C2410_UERSTAT_PARITY (0x1000)
 
 static irqreturn_t
-serial_s3c2410_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
+s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct uart_port *port = dev_id;
+	struct s3c24xx_uart_port *ourport = dev_id;
+	struct uart_port *port = &ourport->port;
 	struct tty_struct *tty = port->info->tty;
-	unsigned int ufcon, ch, rxs, ufstat;
-	int max_count = 256;
+	unsigned int ufcon, ch, ufstat, uerstat;
+	int max_count = 32;
 
 	while (max_count-- > 0) {
 		ufcon = rd_regl(port, S3C2410_UFCON);
 		ufstat = rd_regl(port, S3C2410_UFSTAT);
 
-		if (S3C2410_UFCON_RXC(ufstat) == 0)
+		if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
 			break;
 
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
@@ -129,35 +313,71 @@
 			}
 		}
 
+		uerstat = rd_regl(port, S3C2410_UERSTAT);
 		ch = rd_regb(port, S3C2410_URXH);
 
+		if (port->flags & UPF_CONS_FLOW) {
+			int txe = s3c24xx_serial_txempty_nofifo(port);
+
+			if (rx_enabled(port)) {
+				if (!txe) {
+					rx_enabled(port) = 0;
+					continue;
+				}
+			} else {
+				if (txe) {
+					ufcon |= S3C2410_UFCON_RESETRX;
+					wr_regl(port, S3C2410_UFCON, ufcon);
+					rx_enabled(port) = 1;
+					goto out;
+				}
+				continue;
+			}
+		}
+
+		/* insert the character into the buffer */
+
 		*tty->flip.char_buf_ptr = ch;
 		*tty->flip.flag_buf_ptr = TTY_NORMAL;
 		port->icount.rx++;
 
-		rxs = rd_regb(port, S3C2410_UERSTAT) | RXSTAT_DUMMY_READ;
+		if (uerstat & S3C2410_UERSTAT_ANY) {
+			dbg("rxerr: port %d ch=0x%02x, rxs=0x%08x\n",
+			    s3c24xx_serial_get_portno(port), ch, uerstat);
+
+			/* check for break */
+			if (uerstat & S3C2410_UERSTAT_BREAK) {
+				dbg("break!\n");
+				port->icount.brk++;
+				if (uart_handle_break(port))
+				    goto ignore_char;
+			}
 
-		if (rxs & S3C2410_UERSTAT_ANY) {
-			if (rxs & S3C2410_UERSTAT_FRAME)
+			if (uerstat & S3C2410_UERSTAT_FRAME)
 				port->icount.frame++;
-			if (rxs & S3C2410_UERSTAT_OVERRUN)
+			if (uerstat & S3C2410_UERSTAT_OVERRUN)
 				port->icount.overrun++;
 
-			rxs &= port->read_status_mask;
+			uerstat &= port->read_status_mask;
 
-			if (rxs & S3C2410_UERSTAT_PARITY)
+			if (uerstat & S3C2410_UERSTAT_BREAK)
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			else if (uerstat & S3C2410_UERSTAT_PARITY)
 				*tty->flip.flag_buf_ptr = TTY_PARITY;
-			else if (rxs & ( S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_OVERRUN))
+			else if (uerstat & ( S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_OVERRUN))
 				*tty->flip.flag_buf_ptr = TTY_FRAME;
 		}
 
-		if ((rxs & port->ignore_status_mask) == 0) {
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+		
+		if ((uerstat & port->ignore_status_mask) == 0) {
 			tty->flip.flag_buf_ptr++;
 			tty->flip.char_buf_ptr++;
 			tty->flip.count++;
 		}
 
-		if ((rxs & S3C2410_UERSTAT_OVERRUN) &&
+		if ((uerstat & S3C2410_UERSTAT_OVERRUN) &&
 		    tty->flip.count < TTY_FLIPBUF_SIZE) {
 			/*
 			 * Overrun is special, since it's reported
@@ -168,6 +388,9 @@
 			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
 			tty->flip.count++;
 		}
+
+	ignore_char:
+		continue;
 	}
 	tty_flip_buffer_push(tty);
 
@@ -176,9 +399,10 @@
 }
 
 static irqreturn_t
-serial_s3c2410_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
+s3c24xx_serial_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct uart_port *port = (struct uart_port *)dev_id;
+	struct s3c24xx_uart_port *ourport = dev_id;
+	struct uart_port *port = &ourport->port;
 	struct circ_buf *xmit = &port->info->xmit;
 	int count = 256;
 
@@ -194,14 +418,14 @@
 	*/
 
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-		serial_s3c2410_stop_tx(port, 0);
+		s3c24xx_serial_stop_tx(port, 0);
 		goto out;
 	}
 
 	/* try and drain the buffer... */
 
 	while (!uart_circ_empty(xmit) && count-- > 0) {
-		if (rd_regl(port, S3C2410_UFSTAT) & S3C2410_UFSTAT_TXFULL)
+		if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
 			break;
 
 		wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
@@ -213,22 +437,33 @@
 		uart_write_wakeup(port);
 
 	if (uart_circ_empty(xmit))
-		serial_s3c2410_stop_tx(port, 0);
+		s3c24xx_serial_stop_tx(port, 0);
 
  out:
 	return IRQ_HANDLED;
 }
 
 static unsigned int
-serial_s3c2410_tx_empty(struct uart_port *port)
+s3c24xx_serial_tx_empty(struct uart_port *port)
 {
-	unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
-	return (S3C2410_UFCON_TXC(ufcon) != 0) ? 0 : TIOCSER_TEMT;
+	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+	unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
+	unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
+
+	if (ufcon & S3C2410_UFCON_FIFOMODE) {
+		if ((ufstat & info->tx_fifomask) != 0 ||
+		    (ufstat & info->tx_fifofull))
+			return 0;
+
+		return 1;
+	}
+	
+	return s3c24xx_serial_txempty_nofifo(port);
 }
 
 /* no modem control lines */
 static unsigned int
-serial_s3c2410_get_mctrl(struct uart_port *port)
+s3c24xx_serial_get_mctrl(struct uart_port *port)
 {
 	unsigned int umstat = rd_regb(port,S3C2410_UMSTAT);
 
@@ -239,12 +474,12 @@
 }
 
 static void
-serial_s3c2410_set_mctrl(struct uart_port *port, unsigned int mctrl)
+s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
 	/* todo - possibly remove AFC and do manual CTS */
 }
 
-static void serial_s3c2410_break_ctl(struct uart_port *port, int break_state)
+static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
 {
 	unsigned long flags;
 	unsigned int ucon;
@@ -263,46 +498,233 @@
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static int serial_s3c2410_startup(struct uart_port *port)
+static void s3c24xx_serial_shutdown(struct uart_port *port)
 {
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+	if (ourport->tx_claimed) {
+		free_irq(TX_IRQ(port), ourport);
+		tx_enabled(port) = 0;
+		ourport->tx_claimed = 0;
+	}
+
+	if (ourport->rx_claimed) {
+		free_irq(RX_IRQ(port), ourport);
+		ourport->rx_claimed = 0;
+		rx_enabled(port) = 0;
+	}
+
+	if (ourport->clk && 0)
+		clk_disable(ourport->clk);
+}
+
+static int s3c24xx_serial_startup(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	unsigned long flags;
 	int ret;
 
-	tx_enabled(port) = 1;
-	rx_enabled(port) = 1;
+	dbg("s3c24xx_serial_startup: port=%p (%d) (%08lx,%p)\n",
+	    port, s3c24xx_serial_get_portno(port),
+	    port->mapbase, port->membase );
+
+	if (ourport->clk)
+		clk_enable(ourport->clk);
+
+	local_irq_save(flags);
 
-	dbg("serial_s3c2410_startup: port=%p (%p)\n",
-	    port, port->mapbase);
+	rx_enabled(port) = 1;
 
-	ret = request_irq(RX_IRQ(port), serial_s3c2410_rx_chars, 0,
-			  serial_s3c2410_name, port);
+	ret = request_irq(RX_IRQ(port),
+			  s3c24xx_serial_rx_chars, 0,
+			  s3c24xx_serial_portname(port), ourport);
 
-	if (ret != 0)
+	if (ret != 0) {
+		printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port));
 		return ret;
+	}
 
-	ret = request_irq(TX_IRQ(port), serial_s3c2410_tx_chars, 0,
-			  serial_s3c2410_name, port);
+	ourport->rx_claimed = 1;
+
+	dbg("requesting tx irq...\n");
+
+	tx_enabled(port) = 1;
+
+	ret = request_irq(TX_IRQ(port),
+			  s3c24xx_serial_tx_chars, 0,
+			  s3c24xx_serial_portname(port), ourport);
 
 	if (ret) {
-		free_irq(RX_IRQ(port), port);
-		return ret;
+		printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port));
+		goto err;
 	}
 
+	ourport->tx_claimed = 1;
+
+	dbg("s3c24xx_serial_startup ok\n");
+
 	/* the port reset code should have done the correct
-	 * register setup for the port controls */
+	 * register setup for the port controls */	
+
+	local_irq_restore(flags);
+	return ret;
 
+ err:
+	s3c24xx_serial_shutdown(port);
+	local_irq_restore(flags);
 	return ret;
 }
 
-static void serial_s3c2410_shutdown(struct uart_port *port)
+/* baud rate calculation
+ *
+ * The UARTs on the S3C2410/S3C2440 can take their clocks from a number
+ * of different sources, including the peripheral clock ("pclk") and an
+ * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk")
+ * with a programmable extra divisor.
+ *
+ * The following code goes through the clock sources, and calculates the
+ * baud clocks (and the resultant actual baud rates) and then tries to
+ * pick the closest one and select that.
+ *
+ * NOTES:
+ *	1) there is no current code to properly select/deselect FCLK on
+ *	   the s3c2440, so only specify FCLK or non-FCLK in the clock
+ *	   sources for the UART
+ *
+*/
+
+
+#define MAX_CLKS (8)
+
+static struct s3c24xx_uart_clksrc tmp_clksrc = {
+	.name		= "pclk",
+	.min_baud	= 0,
+	.max_baud	= 0,
+	.divisor	= 1,
+};
+
+static inline int
+s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
+{
+	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+	return (info->get_clksrc)(port, c);
+}
+
+static inline int
+s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
+{
+	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+	return (info->set_clksrc)(port, c);
+}
+
+
+struct baud_calc {
+	struct s3c24xx_uart_clksrc	*clksrc;
+	unsigned int			 calc;
+	unsigned int			 quot;
+	struct clk			*src;
+};
+
+static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
+				   struct uart_port *port,
+				   struct s3c24xx_uart_clksrc *clksrc,
+				   unsigned int baud)
 {
-	free_irq(TX_IRQ(port), port);
-	free_irq(RX_IRQ(port), port);
+	unsigned long rate;
+
+	calc->src = clk_get(port->dev, clksrc->name);
+	if (calc->src == NULL)
+		return 0;
+
+	rate = clk_get_rate(calc->src);
+
+	calc->clksrc = clksrc;
+	calc->quot = (rate + (8 * baud)) / (16 * baud);
+	calc->calc = (rate / (calc->quot * 16));
+
+	calc->quot--;
+	return 1;
+}
+
+static unsigned int
+s3c24xx_serial_getclk(struct uart_port *port,
+		      struct s3c24xx_uart_clksrc **clksrc,
+		      struct clk **clk,
+		      unsigned int baud)
+{
+	struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
+	struct s3c24xx_uart_clksrc *clkp;
+	struct baud_calc res[MAX_CLKS];
+	struct baud_calc *resptr, *best, *sptr;
+	int i;
+
+	clkp = cfg->clocks;
+	best = NULL;
+
+	if (cfg->clocks_size < 2) {
+		if (cfg->clocks_size == 0)
+			clkp = &tmp_clksrc;
+
+		s3c24xx_serial_calcbaud(res, port, clkp, baud);		
+		best = res;
+
+	} else {
+		resptr = res;
+
+		for (i = 0; i < cfg->clocks_size; i++, clkp++) {
+			if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
+				resptr++;
+		}
+	}
+
+	/* ok, we now need to select the best clock we found */
+
+	if (!best) {
+		unsigned int deviation = (1<<30)|((1<<30)-1);
+		int calc_deviation;
+
+		for (sptr = res; sptr < resptr; sptr++) {
+			printk(KERN_DEBUG 
+			       "found clk %p (%s) quot %d, calc %d\n",
+			       sptr->clksrc, sptr->clksrc->name,
+			       sptr->quot, sptr->calc);
+			
+			calc_deviation = baud - sptr->calc;
+			if (calc_deviation < 0)
+				calc_deviation = -calc_deviation;
+
+			if (calc_deviation < deviation) {
+				best = sptr;
+				deviation = calc_deviation;
+			}
+		}
+
+		printk(KERN_DEBUG "best %p (deviation %d)\n", best, deviation);
+		best = res;
+	}
+
+	printk(KERN_DEBUG "selected clock %p (%s) quot %d, calc %d\n",
+	       best->clksrc, best->clksrc->name, best->quot, best->calc);
+
+	/* store results to pass back */
+
+	*clksrc = best->clksrc;
+	*clk    = best->src;
+	
+	return best->quot;
 }
 
 static void
-serial_s3c2410_set_termios(struct uart_port *port, struct termios *termios,
+s3c24xx_serial_set_termios(struct uart_port *port,
+			   struct termios *termios,
 			   struct termios *old)
 {
+	struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	struct s3c24xx_uart_clksrc *clksrc;
+	struct clk *clk;
 	unsigned long flags;
 	unsigned int baud, quot;
 	unsigned int ulcon;
@@ -314,15 +736,24 @@
 	termios->c_cflag |= CLOCAL;
 
 	/*
-	 * We don't support BREAK character recognition.
-	 */
-	termios->c_iflag &= ~(IGNBRK | BRKINT);
-
-	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
-	quot = uart_get_divisor(port, baud);
+	baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
+	//quot = uart_get_divisor(port, baud) - 1;
+
+	if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
+		quot = port->custom_divisor;
+	else
+		quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);
+
+	/* check to see if we need  to change clock source */
+
+	if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
+		s3c24xx_serial_setsource(port, clksrc);
+
+		ourport->clksrc = clksrc;
+		ourport->baudclk = clk;
+	}
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -344,6 +775,9 @@
 		break;
 	}
 
+	/* preserve original lcon IR settings */
+	ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);
+
 	if (termios->c_cflag & CSTOPB)
 		ulcon |= S3C2410_LCON_STOPB;
 
@@ -356,18 +790,12 @@
 		ulcon |= S3C2410_LCON_PNONE;
 	}
 
-	/*
-	if (port->fifosize)
-	enable_fifo()
-	*/
-
 	spin_lock_irqsave(&port->lock, flags);
 
-	dbg("setting ulcon to %08x\n", ulcon);
-	//dbg("<flushing output from serial>\n");
+	dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot);
 
-	/* set the ulcon register */
 	wr_regl(port, S3C2410_ULCON, ulcon);
+	wr_regl(port, S3C2410_UBRDIV, quot);
 
 	dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
 	    rd_regl(port, S3C2410_ULCON),
@@ -404,117 +832,163 @@
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static const char *serial_s3c2410_type(struct uart_port *port)
+static const char *s3c24xx_serial_type(struct uart_port *port)
 {
-	return port->type == PORT_S3C2410 ? "S3C2410" : NULL;
+	switch (port->type) {
+	case PORT_S3C2410:
+		return "S3C2410";
+	case PORT_S3C2440:
+		return "S3C2440";
+	default:
+		return NULL;
+	}
 }
 
 #define MAP_SIZE (0x100)
 
-static void
-serial_s3c2410_release_port(struct uart_port *port)
+static void s3c24xx_serial_release_port(struct uart_port *port)
 {
 	release_mem_region(port->mapbase, MAP_SIZE);
 }
 
-static int
-serial_s3c2410_request_port(struct uart_port *port)
+static int s3c24xx_serial_request_port(struct uart_port *port)
 {
-	return request_mem_region(port->mapbase, MAP_SIZE, serial_s3c2410_name)
-		!= NULL ? 0 : -EBUSY;
+	char *name = s3c24xx_serial_portname(port);
+	return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
 }
 
-static void
-serial_s3c2410_config_port(struct uart_port *port, int flags)
+static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
 {
+	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
 	if (flags & UART_CONFIG_TYPE &&
-	    serial_s3c2410_request_port(port) == 0)
-		port->type = PORT_S3C2410;
+	    s3c24xx_serial_request_port(port) == 0)
+		port->type = info->type;
 }
 
 /*
  * verify the new serial_struct (for TIOCSSERIAL).
  */
 static int
-serial_s3c2410_verify_port(struct uart_port *port, struct serial_struct *ser)
+s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
-	int ret = 0;
+	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
 
-	if (ser->type != PORT_UNKNOWN && ser->type != PORT_S3C2410)
-		ret = -EINVAL;
+	if (ser->type != PORT_UNKNOWN && ser->type != info->type)
+		return -EINVAL;
 
-	return ret;
+	return 0;
 }
 
-static struct uart_ops serial_s3c2410_ops = {
-	.tx_empty	= serial_s3c2410_tx_empty,
-	.get_mctrl	= serial_s3c2410_get_mctrl,
-	.set_mctrl	= serial_s3c2410_set_mctrl,
-	.stop_tx	= serial_s3c2410_stop_tx,
-	.start_tx	= serial_s3c2410_start_tx,
-	.stop_rx	= serial_s3c2410_stop_rx,
-	.enable_ms	= serial_s3c2410_enable_ms,
-	.break_ctl	= serial_s3c2410_break_ctl,
-	.startup	= serial_s3c2410_startup,
-	.shutdown	= serial_s3c2410_shutdown,
-	.set_termios	= serial_s3c2410_set_termios,
-	.type		= serial_s3c2410_type,
-	.release_port	= serial_s3c2410_release_port,
-	.request_port	= serial_s3c2410_request_port,
-	.config_port	= serial_s3c2410_config_port,
-	.verify_port	= serial_s3c2410_verify_port,
-};
-
-static struct uart_port serial_s3c2410_ports[NR_PORTS] = {
-	{
-		.membase	= 0,
-		.mapbase	= 0,
-		.iotype		= UPIO_MEM,
-		.irq		= IRQ_S3CUART_RX0,
-		.uartclk	= 0,
-		.fifosize	= 16,
-		.ops		= &serial_s3c2410_ops,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.line		= 0,
+
+#ifdef CONFIG_SERIAL_S3C2410_CONSOLE
+
+static struct console s3c24xx_serial_console;
+
+#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
+#else
+#define S3C24XX_SERIAL_CONSOLE NULL
+#endif
+
+static struct uart_ops s3c24xx_serial_ops = {
+	.tx_empty	= s3c24xx_serial_tx_empty,
+	.get_mctrl	= s3c24xx_serial_get_mctrl,
+	.set_mctrl	= s3c24xx_serial_set_mctrl,
+	.stop_tx	= s3c24xx_serial_stop_tx,
+	.start_tx	= s3c24xx_serial_start_tx,
+	.stop_rx	= s3c24xx_serial_stop_rx,
+	.enable_ms	= s3c24xx_serial_enable_ms,
+	.break_ctl	= s3c24xx_serial_break_ctl,
+	.startup	= s3c24xx_serial_startup,
+	.shutdown	= s3c24xx_serial_shutdown,
+	.set_termios	= s3c24xx_serial_set_termios,
+	.type		= s3c24xx_serial_type,
+	.release_port	= s3c24xx_serial_release_port,
+	.request_port	= s3c24xx_serial_request_port,
+	.config_port	= s3c24xx_serial_config_port,
+	.verify_port	= s3c24xx_serial_verify_port,
+};
+
+
+static struct uart_driver s3c24xx_uart_drv = {
+	.owner		= THIS_MODULE,
+	.dev_name	= "s3c2410_serial",
+	.nr		= 3,
+	.cons		= S3C24XX_SERIAL_CONSOLE,
+	.driver_name	= S3C24XX_SERIAL_NAME,
+	.devfs_name	= S3C24XX_SERIAL_DEVFS,
+	.major		= S3C24XX_SERIAL_MAJOR,
+	.minor		= S3C24XX_SERIAL_MINOR,
+};
+
+static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
+	[0] = {
+		.port = {
+			.lock		= SPIN_LOCK_UNLOCKED,
+			.membase	= 0,
+			.mapbase	= 0,
+			.iotype		= UPIO_MEM,
+			.irq		= IRQ_S3CUART_RX0,
+			.uartclk	= 0,
+			.fifosize	= 16,
+			.ops		= &s3c24xx_serial_ops,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 0,
+		}
+	},
+	[1] = {
+		.port = {
+			.lock		= SPIN_LOCK_UNLOCKED,
+			.membase	= 0,
+			.mapbase	= 0,
+			.iotype		= UPIO_MEM,
+			.irq		= IRQ_S3CUART_RX1,
+			.uartclk	= 0,
+			.fifosize	= 16,
+			.ops		= &s3c24xx_serial_ops,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 1,
+		}
 	},
-	{
-		.membase	= 0,
-		.mapbase	= 0,
-		.iotype		= UPIO_MEM,
-		.irq		= IRQ_S3CUART_RX1,
-		.uartclk	= 0,
-		.fifosize	= 16,
-		.ops		= &serial_s3c2410_ops,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.line		= 1,
-	}
 #if NR_PORTS > 2
-	,
-	{
-		.membase	= 0,
-		.mapbase	= 0,
-		.iotype		= UPIO_MEM,
-		.irq		= IRQ_S3CUART_RX2,
-		.uartclk	= 0,
-		.fifosize	= 16,
-		.ops		= &serial_s3c2410_ops,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.line		= 2,
+
+	[2] = {
+		.port = {
+			.lock		= SPIN_LOCK_UNLOCKED,
+			.membase	= 0,
+			.mapbase	= 0,
+			.iotype		= UPIO_MEM,
+			.irq		= IRQ_S3CUART_RX2,
+			.uartclk	= 0,
+			.fifosize	= 16,
+			.ops		= &s3c24xx_serial_ops,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 2,
+		}
 	}
 #endif
 };
 
+static int s3c24xx_serial_get_portno(struct uart_port *port)
+{
+	return to_ourport(port) - s3c24xx_serial_ports;
+}
+
 static int
-serial_s3c2410_resetport(struct uart_port *port,
+s3c24xx_serial_resetport(struct uart_port *port,
 			 struct s3c2410_uartcfg *cfg)
 {
 	/* ensure registers are setup */
 
-	dbg("serial_s3c2410_resetport: port=%p (%08x), cfg=%p\n",
+	dbg("s3c24xx_serial_resetport: port=%p (%08lx), cfg=%p\n",
 	    port, port->mapbase, cfg);
 
-	wr_regl(port, S3C2410_UCON,  cfg->ucon);
-	wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+	if (!machine_is_rx3715()) {
+		wr_regl(port, S3C2410_UCON,  cfg->ucon);
+		wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+	} else {
+		wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+	}
 
 	/* reset both fifos */
 
@@ -524,105 +998,423 @@
 	return 0;
 }
 
-/* serial_s3c2410_init_ports
+/* s3c24xx_serial_init_port
  *
- * initialise the serial ports from the machine provided initialisation
- * data.
+ * initialise a single serial port from the platform device given
+ */
+
+static void s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
+				     struct s3c24xx_uart_info *info,
+				     struct platform_device *platdev)
+{
+	struct uart_port *port = &ourport->port;
+	struct s3c2410_uartcfg *cfg;
+
+	dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev);
+
+	if (platdev == NULL)
+		return;
+
+	cfg = s3c24xx_dev_to_cfg(&platdev->dev);
+
+	if (cfg->hwport > 3 || port->mapbase != 0)
+		return;
+
+	/* setup info for port */
+	port->dev	= &platdev->dev;
+	ourport->info	= info;
+
+	/* copy the info in from provided structure */
+	ourport->port.fifosize = info->fifosize;
+
+	dbg("s3c24xx_serial_init_port: port %p (hw %d)...\n",
+	    s3c24xx_serial_get_portno(port), cfg->hwport);
+
+	port->uartclk = 1;
+
+	if (cfg->uart_flags & UPF_CONS_FLOW) {
+		dbg("s3c24xx_serial_init_port: enabling flow control\n");
+		port->flags |= UPF_CONS_FLOW;
+	}
+
+	/* sort our the physical and virtual addresses for each UART */
+
+	switch (cfg->hwport) {
+	case 0:
+		port->mapbase = S3C2410_PA_UART0;
+		port->membase = (char *)S3C2410_VA_UART0;
+		port->irq     = IRQ_S3CUART_RX0;
+		ourport->clk  = clk_get(port->dev, "uart0");
+		break;
+
+	case 1:
+		port->mapbase = S3C2410_PA_UART1;
+		port->membase = (char *)S3C2410_VA_UART1;
+		port->irq     = IRQ_S3CUART_RX1;
+		ourport->clk  = clk_get(port->dev, "uart1");
+		break;
+
+	case 2:
+		port->mapbase = S3C2410_PA_UART2;
+		port->membase = (char *)S3C2410_VA_UART2;
+		port->irq     = IRQ_S3CUART_RX2;
+		ourport->clk  = clk_get(port->dev, "uart2");
+		break;
+	}
+
+	if (ourport->clk != NULL)
+		clk_use(ourport->clk);
+
+	dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
+	    port->mapbase, port->membase, port->irq, port->uartclk);
+
+	/* reset the fifos (and setup the uart) */
+	s3c24xx_serial_resetport(port, cfg);
+}
+
+/* Device driver serial port probe */
+
+static int probe_index = 0;
+
+int s3c24xx_serial_probe(struct device *_dev,
+			 struct s3c24xx_uart_info *info)
+{
+	struct s3c24xx_uart_port *ourport;
+	struct platform_device *dev = to_platform_device(_dev);
+
+	dbg("s3c24xx_serial_probe(%p, %p) %d\n", _dev, info, probe_index);
+	
+	ourport = &s3c24xx_serial_ports[probe_index];
+	probe_index++;
+
+	dbg("%s: initialising port %p...\n", __FUNCTION__, ourport);
+
+	s3c24xx_serial_init_port(ourport, info, dev);
+
+	dbg("%s: adding port\n", __FUNCTION__);
+	uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
+	dev_set_drvdata(_dev, &ourport->port);
+
+	return 0;
+}
+
+int s3c24xx_serial_remove(struct device *_dev)
+{
+	struct uart_port *port = s3c24xx_dev_to_port(_dev);
+
+	if (port)
+		uart_remove_one_port(&s3c24xx_uart_drv, port);
+
+	return 0;
+}
+
+/* UART power management code */
+
+#ifdef CONFIG_PM
+
+int s3c24xx_serial_suspend(struct device *dev, u32 state, u32 level)
+{
+	struct uart_port *port = s3c24xx_dev_to_port(dev);
+
+	if (port && level == SUSPEND_DISABLE)
+		uart_suspend_port(&s3c24xx_uart_drv, port);
+
+	return 0;
+}
+
+int s3c24xx_serial_resume(struct device *dev, u32 level)
+{
+	struct uart_port *port = s3c24xx_dev_to_port(dev);
+
+	if (port && level == RESUME_ENABLE) {
+		s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
+		uart_resume_port(&s3c24xx_uart_drv, port);
+	}
+
+	return 0;
+}
+
+#else
+#define s3c24xx_serial_suspend NULL
+#define s3c24xx_serial_resume  NULL
+#endif
+
+int s3c24xx_serial_init(struct device_driver *drv,
+			struct s3c24xx_uart_info *info)
+{
+	dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
+	return driver_register(drv);
+}
+
+
+/* now comes the code to initialise either the s3c2410 or s3c2440 serial
+ * port information
 */
 
-static int serial_s3c2410_init_ports(void)
+/* cpu specific variations on the serial port support */
+
+#ifdef CONFIG_CPU_S3C2410
+
+static int s3c2410_serial_setsource(struct uart_port *port,
+				    struct s3c24xx_uart_clksrc *clk)
 {
-	struct uart_port *ptr = serial_s3c2410_ports;
-	struct s3c2410_uartcfg *cfg = s3c2410_uartcfgs;
-	static int inited = 0;
-	int i;
+	unsigned long ucon = rd_regl(port, S3C2410_UCON);
 
-	if (inited)
-		return 0;
-	inited = 1;
+	if (strcmp(clk->name, "uclk") == 0)
+		ucon |= S3C2410_UCON_UCLK;
+	else
+		ucon &= ~S3C2410_UCON_UCLK;
+
+	wr_regl(port, S3C2410_UCON, ucon);
+	return 0;
+}
 
-	dbg("serial_s3c2410_init_ports: initialising ports...\n");
+static int s3c2410_serial_getsource(struct uart_port *port,
+				    struct s3c24xx_uart_clksrc *clk)
+{
+	unsigned long ucon = rd_regl(port, S3C2410_UCON);
 
-	for (i = 0; i < NR_PORTS; i++, ptr++, cfg++) {
+	clk->divisor = 1;
+	clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk";
 
-		if (cfg->hwport > 3)
-			continue;
+	return 0;
+}
 
-		dbg("serial_s3c2410_init_ports: port %d (hw %d)...\n",
-		    i, cfg->hwport);
+static struct s3c24xx_uart_info s3c2410_uart_inf = {
+	.name		= "Samsung S3C2410 UART",
+	.type		= PORT_S3C2410,
+	.fifosize	= 16,
+	.rx_fifomask	= S3C2410_UFSTAT_RXMASK,
+	.rx_fifoshift	= S3C2410_UFSTAT_RXSHIFT,
+	.tx_fifofull	= S3C2410_UFSTAT_TXFULL,
+	.tx_fifomask	= S3C2410_UFSTAT_TXMASK,
+	.tx_fifoshift	= S3C2410_UFSTAT_TXSHIFT,
+	.get_clksrc	= s3c2410_serial_getsource,
+	.set_clksrc	= s3c2410_serial_setsource,
+};
 
-		if (cfg->clock != NULL)
-			ptr->uartclk = *cfg->clock;
+/* device management */
 
-		switch (cfg->hwport) {
-		case 0:
-			ptr->mapbase = S3C2410_PA_UART0;
-			ptr->membase = (char *)S3C2410_VA_UART0;
-			ptr->irq     = IRQ_S3CUART_RX0;
-			break;
+static int s3c2410_serial_probe(struct device *dev)
+{
+	return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
+}
 
-		case 1:
-			ptr->mapbase = S3C2410_PA_UART1;
-			ptr->membase = (char *)S3C2410_VA_UART1;
-			ptr->irq     = IRQ_S3CUART_RX1;
-			break;
+static struct device_driver s3c2410_serial_drv = {
+	.name		= "s3c2410-uart",
+	.bus		= &platform_bus_type,
+	.probe		= s3c2410_serial_probe,
+	.remove		= s3c24xx_serial_remove,
+	.suspend	= s3c24xx_serial_suspend,
+	.resume		= s3c24xx_serial_resume,
+};
 
-		case 2:
-			ptr->mapbase = S3C2410_PA_UART2;
-			ptr->membase = (char *)S3C2410_VA_UART2;
-			ptr->irq     = IRQ_S3CUART_RX2;
-			break;
-		}
+static inline int s3c2410_serial_init(void)
+{
+	return s3c24xx_serial_init(&s3c2410_serial_drv, &s3c2410_uart_inf);
+}
+
+static inline void s3c2410_serial_exit(void)
+{
+	driver_unregister(&s3c2410_serial_drv);
+}
+
+#define s3c2410_uart_inf_at &s3c2410_uart_inf
+#else
+
+static inline int s3c2410_serial_init(void)
+{
+	return 0;
+}
+
+static inline void s3c2410_serial_exit(void)
+{
+}
+
+#define s3c2410_uart_inf_at NULL
+
+#endif /* CONFIG_CPU_S3C2410 */
+
+#ifdef CONFIG_CPU_S3C2440
+static int s3c2440_serial_setsource(struct uart_port *port,
+				     struct s3c24xx_uart_clksrc *clk)
+{
+	unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+	// todo - proper fclk<>nonfclk switch //
+
+	ucon &= ~S3C2440_UCON_CLKMASK;
+
+	if (strcmp(clk->name, "uclk") == 0)
+		ucon |= S3C2440_UCON_UCLK;
+	else if (strcmp(clk->name, "pclk") == 0)
+		ucon |= S3C2440_UCON_PCLK;
+	else if (strcmp(clk->name, "fclk") == 0)
+		ucon |= S3C2440_UCON_FCLK;
+	else {
+		printk(KERN_ERR "unknown clock source %s\n", clk->name);
+		return -EINVAL;
+	}
+
+	wr_regl(port, S3C2410_UCON, ucon);
+	return 0;
+}
+
+
+static int s3c2440_serial_getsource(struct uart_port *port,
+				    struct s3c24xx_uart_clksrc *clk)
+{
+	unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+	switch (ucon & S3C2440_UCON_CLKMASK) {
+	case S3C2440_UCON_UCLK:
+		clk->divisor = 1;
+		clk->name = "uclk";
+		break;
 
-		if (ptr->mapbase == 0)
-			continue;
+	case S3C2440_UCON_PCLK:
+	case S3C2440_UCON_PCLK2:
+		clk->divisor = 1;
+		clk->name = "pclk";
+		break;
 
-		/* reset the fifos (and setup the uart */
-		serial_s3c2410_resetport(ptr, cfg);
+	case S3C2440_UCON_FCLK:
+		clk->divisor = 7; /* todo - work out divisor */
+		clk->name = "fclk";
+		break;
 	}
 
+
 	return 0;
 }
 
+
+static struct s3c24xx_uart_info s3c2440_uart_inf = {
+	.name		= "Samsung S3C2440 UART",
+	.type		= PORT_S3C2440,
+	.fifosize	= 64,
+	.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
+	.rx_fifoshift	= S3C2440_UFSTAT_RXSHIFT,
+	.tx_fifofull	= S3C2440_UFSTAT_TXFULL,
+	.tx_fifomask	= S3C2440_UFSTAT_TXMASK,
+	.tx_fifoshift	= S3C2440_UFSTAT_TXSHIFT,
+	.get_clksrc	= s3c2440_serial_getsource,
+	.set_clksrc	= s3c2440_serial_setsource
+};
+
+/* device management */
+
+static int s3c2440_serial_probe(struct device *dev)
+{
+	dbg("s3c2440_serial_probe: dev=%p\n", dev);
+	return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
+}
+
+static struct device_driver s3c2440_serial_drv = {
+	.name		= "s3c2440-uart",
+	.bus		= &platform_bus_type,
+	.probe		= s3c2440_serial_probe,
+	.remove		= s3c24xx_serial_remove,
+	.suspend	= s3c24xx_serial_suspend,
+	.resume		= s3c24xx_serial_resume,
+};
+
+
+static inline int s3c2440_serial_init(void)
+{
+	return s3c24xx_serial_init(&s3c2440_serial_drv, &s3c2440_uart_inf);
+}
+
+static inline void s3c2440_serial_exit(void)
+{
+	driver_unregister(&s3c2440_serial_drv);
+}
+
+#define s3c2440_uart_inf_at &s3c2440_uart_inf
+#else
+
+static inline int s3c2440_serial_init(void)
+{
+	return 0;
+}
+
+static inline void s3c2440_serial_exit(void)
+{
+}
+
+#define s3c2440_uart_inf_at NULL
+#endif /* CONFIG_CPU_S3C2440 */
+
+/* module initialisation code */
+
+static int __init s3c24xx_serial_modinit(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&s3c24xx_uart_drv);
+	if (ret < 0) {
+		printk(KERN_ERR "failed to register UART driver\n");
+		return -1;
+	}
+
+	s3c2410_serial_init();
+	s3c2440_serial_init();
+
+	return 0;
+}
+
+static void __exit s3c24xx_serial_modexit(void)
+{
+	s3c2410_serial_exit();
+	s3c2440_serial_exit();
+
+	uart_unregister_driver(&s3c24xx_uart_drv);
+}
+
+
+module_init(s3c24xx_serial_modinit);
+module_exit(s3c24xx_serial_modexit);
+
+/* Console code */			
+
 #ifdef CONFIG_SERIAL_S3C2410_CONSOLE
 
 static struct uart_port *cons_uart;
 
 static int
-serial_s3c2410_console_txrdy(struct uart_port *port, unsigned int ufcon)
+s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
 {
+	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
 	unsigned long ufstat, utrstat;
 
 	if (ufcon & S3C2410_UFCON_FIFOMODE) {
 		/* fifo mode - check ammount of data in fifo registers... */
 
 		ufstat = rd_regl(port, S3C2410_UFSTAT);
-
-		return S3C2410_UFCON_TXC(ufstat) < 12;
+		return (ufstat & info->tx_fifofull) ? 0 : 1;
 	}
 
 	/* in non-fifo mode, we go and use the tx buffer empty */
 
 	utrstat = rd_regl(port, S3C2410_UTRSTAT);
-
-	return (utrstat & S3C2410_UTRSTAT_TXFE) ? 1 : 0;
+	return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
 }
 
 static void
-serial_s3c2410_console_write(struct console *co, const char *s,
+s3c24xx_serial_console_write(struct console *co, const char *s,
 			     unsigned int count)
 {
 	int i;
 	unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
 
 	for (i = 0; i < count; i++) {
-		while (!serial_s3c2410_console_txrdy(cons_uart, ufcon))
+		while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon))
 			barrier();
 
 		wr_regb(cons_uart, S3C2410_UTXH, s[i]);
 
 		if (s[i] == '\n') {
-			while (!serial_s3c2410_console_txrdy(cons_uart, ufcon))
+			while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon))
 				barrier();
 
 			wr_regb(cons_uart, S3C2410_UTXH, '\r');
@@ -631,17 +1423,21 @@
 }
 
 static void __init
-serial_s3c2410_get_options(struct uart_port *port, int *baud,
+s3c24xx_serial_get_options(struct uart_port *port, int *baud,
 			   int *parity, int *bits)
 {
-
-	unsigned int ulcon, ucon, ubrdiv;
+	struct s3c24xx_uart_clksrc clksrc;
+	struct clk *clk;
+	unsigned int ulcon;
+	unsigned int ucon;
+	unsigned int ubrdiv;
+	unsigned long rate;
 
 	ulcon  = rd_regl(port, S3C2410_ULCON);
 	ucon   = rd_regl(port, S3C2410_UCON);
 	ubrdiv = rd_regl(port, S3C2410_UBRDIV);
 
-	dbg("serial_s3c2410_get_options: port=%p\n"
+	dbg("s3c24xx_serial_get_options: port=%p\n"
 	    "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n",
 	    port, ulcon, ucon, ubrdiv);
 
@@ -673,21 +1469,53 @@
 			*parity = 'o';
 			break;
 
-		default:
 		case S3C2410_LCON_PNONE:
+		default:
 			*parity = 'n';
 		}
 
 		/* now calculate the baud rate */
 
-		*baud = port->uartclk / ( 16 * (ubrdiv + 1));
+		s3c24xx_serial_getsource(port, &clksrc);
+
+		clk = clk_get(port->dev, clksrc.name);
+		if (clk != NULL)
+			rate = clk_get_rate(clk);
+		else
+			rate = 1;
+			
+
+		*baud = rate / ( 16 * (ubrdiv + 1));
 		dbg("calculated baud %d\n", *baud);
 	}
 
 }
 
+/* s3c24xx_serial_init_ports
+ *
+ * initialise the serial ports from the machine provided initialisation
+ * data.
+*/
+
+static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
+{
+	struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
+	struct platform_device **platdev_ptr;
+	int i;
+
+	dbg("s3c24xx_serial_init_ports: initialising ports...\n");
+
+	platdev_ptr = s3c24xx_uart_devs;
+
+	for (i = 0; i < NR_PORTS; i++, ptr++, platdev_ptr++) {
+		s3c24xx_serial_init_port(ptr, info, *platdev_ptr);
+	}
+
+	return 0;
+}
+
 static int __init
-serial_s3c2410_console_setup(struct console *co, char *options)
+s3c24xx_serial_console_setup(struct console *co, char *options)
 {
 	struct uart_port *port;
 	int baud = 9600;
@@ -695,23 +1523,26 @@
 	int parity = 'n';
 	int flow = 'n';
 
+	dbg("s3c24xx_serial_console_setup: co=%p (%d), %s\n",
+	    co, co->index, options);
+
 	/* is this a valid port */
 
 	if (co->index == -1 || co->index >= NR_PORTS)
 		co->index = 0;
 
-	port = &serial_s3c2410_ports[co->index];
+	port = &s3c24xx_serial_ports[co->index].port;
 
 	/* is the port configured? */
 
 	if (port->mapbase == 0x0) {
 		co->index = 0;
-		port = &serial_s3c2410_ports[co->index];
+		port = &s3c24xx_serial_ports[co->index].port;
 	}
 
 	cons_uart = port;
 
-	dbg("serial_s3c2410_console_setup: port=%p (%d)\n", port, co->index);
+	dbg("s3c24xx_serial_console_setup: port=%p (%d)\n", port, co->index);
 
 	/*
 	 * Check whether an invalid uart number has been specified, and
@@ -721,138 +1552,68 @@
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 	else
-		serial_s3c2410_get_options(port, &baud, &parity, &bits);
+		s3c24xx_serial_get_options(port, &baud, &parity, &bits);
+
+	dbg("s3c24xx_serial_console_setup: baud %d\n", baud);
 
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
-static struct uart_driver s3c2410_uart_drv;
+/* s3c24xx_serial_initconsole
+ *
+ * initialise the console from one of the uart drivers
+*/
 
-static struct console serial_s3c2410_console =
+static struct console s3c24xx_serial_console =
 {
-	.name		= SERIAL_S3C2410_NAME,
-	.write		= serial_s3c2410_console_write,
+	.name		= S3C24XX_SERIAL_NAME,
 	.device		= uart_console_device,
-	.setup		= serial_s3c2410_console_setup,
 	.flags		= CON_PRINTBUFFER,
 	.index		= -1,
-	.data		= &s3c2410_uart_drv,
-};
-
-static int __init s3c2410_console_init(void)
-{
-	dbg("s3c2410_console_init:\n");
-
-	serial_s3c2410_init_ports();
-	register_console(&serial_s3c2410_console);
-	return 0;
-}
-console_initcall(s3c2410_console_init);
-
-#define SERIAL_S3C2410_CONSOLE	&serial_s3c2410_console
-#else
-#define SERIAL_S3C2410_CONSOLE	NULL
-#endif
-
-static struct uart_driver s3c2410_uart_drv = {
-	.owner			= THIS_MODULE,
-	.driver_name		= SERIAL_S3C2410_NAME,
-	.dev_name		= SERIAL_S3C2410_NAME,
-	.major			= SERIAL_S3C2410_MAJOR,
-	.minor			= SERIAL_S3C2410_MINOR,
-	.nr			= 3,
-	.cons			= SERIAL_S3C2410_CONSOLE,
-};
-
-/* device driver */
-
-static int s3c2410_serial_probe(struct device *_dev);
-static int s3c2410_serial_remove(struct device *_dev);
-
-static struct device_driver s3c2410_serial_drv = {
-	.name		= "s3c2410-uart",
-	.bus		= &platform_bus_type,
-	.probe		= s3c2410_serial_probe,
-	.remove		= s3c2410_serial_remove,
-	.suspend	= NULL,
-	.resume		= NULL,
+	.write		= s3c24xx_serial_console_write,
+	.setup		= s3c24xx_serial_console_setup
 };
 
-#define s3c2410_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
 
-static int s3c2410_serial_probe(struct device *_dev)
+static int s3c24xx_serial_initconsole(void)
 {
-	struct platform_device *dev = to_platform_device(_dev);
-	struct resource *res = dev->resource;
-	int i;
-
-	dbg("s3c2410_serial_probe: dev=%p, _dev=%p, res=%p\n", _dev, dev, res);
-
-	for (i = 0; i < dev->num_resources; i++, res++)
-		if (res->flags & IORESOURCE_MEM)
-			break;
+	struct s3c24xx_uart_info *info;
+	struct platform_device *dev = s3c24xx_uart_devs[0];
 
-	if (i < dev->num_resources) {
-		struct uart_port *ptr = serial_s3c2410_ports;
-
-		for (i = 0; i < NR_PORTS; i++, ptr++) {
-			dbg("s3c2410_serial_probe: ptr=%p (%08x, %08x)\n",
-			    ptr, ptr->mapbase, ptr->membase);
-
-			if (ptr->mapbase != res->start)
-				continue;
+	dbg("s3c24xx_serial_initconsole\n");
 
-			dbg("s3c2410_serial_probe: got device %p: port=%p\n",
-			    _dev, ptr);
+	/* select driver based on the cpu */
 
-			uart_add_one_port(&s3c2410_uart_drv, ptr);
-			dev_set_drvdata(_dev, ptr);
-			break;
-		}
+	if (dev == NULL) {
+		printk(KERN_ERR "s3c24xx: no devices for console init\n");
+		return 0;
 	}
 
-	return 0;
-}
+	if (strcmp(dev->name, "s3c2410-uart") == 0) {
+		info = s3c2410_uart_inf_at;
+	} else if (strcmp(dev->name, "s3c2440-uart") == 0) {
+		info = s3c2440_uart_inf_at;
+	} else {
+		printk(KERN_ERR "s3c24xx: no driver for %s\n", dev->name);
+		return 0;
+	}
 
-static int s3c2410_serial_remove(struct device *_dev)
-{
-	struct uart_port *port = s3c2410_dev_to_port(_dev);
+	if (info == NULL) {
+		printk(KERN_ERR "s3c24xx: no driver for console\n");
+		return 0;
+	}
 
-	if (port)
-		uart_remove_one_port(&s3c2410_uart_drv, port);
+	s3c24xx_serial_console.data = &s3c24xx_uart_drv;
+	s3c24xx_serial_init_ports(info);
 
+	register_console(&s3c24xx_serial_console);
 	return 0;
 }
 
+console_initcall(s3c24xx_serial_initconsole);
 
-
-static int __init serial_s3c2410_init(void)
-{
-	int ret;
-
-	printk(KERN_INFO "S3C2410X Serial, (c) 2003 Simtec Electronics\n");
-
-	ret = uart_register_driver(&s3c2410_uart_drv);
-	if (ret != 0)
-		return ret;
-
-	ret = driver_register(&s3c2410_serial_drv);
-	if (ret) {
-		uart_unregister_driver(&s3c2410_uart_drv);
-	}
-
-	return ret;
-}
-
-static void __exit serial_s3c2410_exit(void)
-{
-	driver_unregister(&s3c2410_serial_drv);
-	uart_unregister_driver(&s3c2410_uart_drv);
-}
-
-module_init(serial_s3c2410_init);
-module_exit(serial_s3c2410_exit);
+#endif /* CONFIG_SERIAL_S3C2410_CONSOLE */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("Samsung S3C2410X (S3C2410) Serial driver");
+MODULE_DESCRIPTION("Samsung S3C2410/S3C2440 Serial port driver");
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/ether.c linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/ether.c
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/ether.c	2004-11-09 20:22:16.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/ether.c	2004-11-09 21:18:11.000000000 +0100
@@ -256,6 +256,9 @@
 #define	DEV_CONFIG_SUBSET
 #endif
 
+#ifdef CONFIG_USB_GADGET_S3C2410
+#define DEV_CONFIG_CDC
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -360,7 +363,7 @@
 	.bLength =		sizeof device_desc,
 	.bDescriptorType =	USB_DT_DEVICE,
 
-	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
+	.bcdUSB =		__constant_cpu_to_le16 (0x0110),
 
 	.bDeviceClass =		USB_CLASS_COMM,
 	.bDeviceSubClass =	0,
@@ -2321,6 +2324,8 @@
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
 	} else if (gadget_is_n9604(gadget)) {
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
+	} else if (gadget_is_s3c2410(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x020A);
 	} else {
 		/* can't assume CDC works.  don't want to default to
 		 * anything less functional on CDC-capable hardware,
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/gadget_chips.h linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/gadget_chips.h
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/gadget_chips.h	2004-11-09 20:21:41.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/gadget_chips.h	2004-11-09 21:18:11.000000000 +0100
@@ -68,6 +68,12 @@
 #define	gadget_is_n9604(g)	0
 #endif
 
+#ifdef CONFIG_USB_GADGET_S3C2410
+#define gadget_is_s3c2410(g)    !strcmp("s3c2410_udc", (g)->name)
+#else
+#define gadget_is_s3c2410(g)    0
+#endif
+
 // CONFIG_USB_GADGET_AT91RM9200
 // CONFIG_USB_GADGET_SX2
 // CONFIG_USB_GADGET_AU1X00
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/Kconfig linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/Kconfig
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/Kconfig	2004-11-09 20:21:41.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/Kconfig	2004-11-09 21:18:11.000000000 +0100
@@ -157,7 +157,19 @@
 	depends on USB_GADGET_LH7A40X
 	default USB_GADGET
 
-
+config USB_GADGET_S3C2410
+	boolean "S3C2410"
+	depends on ARCH_S3C2410
+	help
+	  Samsung's S3C2410 is an ARM-4 processor with an integrated
+	  full speed USB 1.1 device controller.
+	  It has 4 configurable endpoints, as well as endpoint
+	  zero (for control transfers).
+config USB_S3C2410
+	tristate
+	depends on USB_GADGET_S3C2410
+	default USB_GADGET
+											    
 config USB_GADGET_DUMMY_HCD
 	boolean "Dummy HCD (DEVELOPMENT)"
 	depends on USB && EXPERIMENTAL
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/Makefile linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/Makefile
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/Makefile	2004-11-09 20:22:16.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/Makefile	2004-11-09 21:18:11.000000000 +0100
@@ -7,7 +7,7 @@
 obj-$(CONFIG_USB_GOKU)		+= goku_udc.o
 obj-$(CONFIG_USB_OMAP)		+= omap_udc.o
 obj-$(CONFIG_USB_LH7A40X)	+= lh7a40x_udc.o
-
+obj-$(CONFIG_USB_S3C2410)	+= s3c2410_udc.o
 #
 # USB gadget drivers
 #
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/s3c2410_udc.c linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/s3c2410_udc.c
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/s3c2410_udc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/s3c2410_udc.c	2004-11-09 21:18:11.000000000 +0100
@@ -0,0 +1,1365 @@
+/*
+ * linux/drivers/usb/gadget/s3c2410_udc.c
+ * Samsung on-chip full speed USB device controllers
+ *
+ * Copyright (C) 2004 Herbert PÃ¶tzl - Arnaud Patard
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
+
+#include <linux/usb.h>
+#include <linux/usb_gadget.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+#include <asm/arch/irqs.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-udc.h>
+#include <asm/hardware/clock.h>
+
+#include "s3c2410_udc.h"
+
+#define DRIVER_DESC     "S3C2410 USB Device Controller Gadget"
+#define DRIVER_VERSION  "29 Oct 2004"
+#define DRIVER_AUTHOR	"Herbert PÃ¶tzl <herbert@13thfloor.at>, Arnaud Patard <arnaud.patard@rtp-net.org>"
+
+static const char       gadget_name [] = "s3c2410_udc";
+static const char	driver_desc [] = DRIVER_DESC;
+
+static struct s3c2410_udc	*the_controller;
+static struct s3c2410_udc 	memory;
+static struct clk      		*udc_clock;
+
+/*------------------------- I/O ----------------------------------*/
+static void nuke (struct s3c2410_udc *udc, struct s3c2410_ep *ep)
+{
+	while (!list_empty (&ep->queue)) {
+		struct s3c2410_request  *req;
+		req = list_entry (ep->queue.next, struct s3c2410_request, queue);
+		list_del_init (&req->queue);
+		req->req.status = -ESHUTDOWN;
+		spin_unlock (&udc->lock);
+		req->req.complete (&ep->ep, &req->req);
+		spin_lock (&udc->lock);
+	}
+}
+
+/*
+ * 	done
+ */
+static void done(struct s3c2410_ep *ep, struct s3c2410_request *req, int status)
+{
+	list_del_init(&req->queue);
+
+	if (likely (req->req.status == -EINPROGRESS))
+		req->req.status = status;
+	else
+		status = req->req.status;
+
+	req->req.complete(&ep->ep, &req->req);
+}
+
+static inline void clear_ep_state (struct s3c2410_udc *dev)
+{
+	        unsigned i;
+		
+		/* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
+		 * fifos, and pending transactions mustn't be continued in any case.
+		 */
+		 for (i = 1; i < S3C2410_ENDPOINTS; i++)
+			 nuke(dev, &dev->ep[i]);
+}
+
+static inline int fifo_count_out(void)
+{
+	int tmp;
+	
+	tmp = __raw_readl(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
+	tmp |= __raw_readl(S3C2410_UDC_OUT_FIFO_CNT1_REG);
+	
+	return tmp & 0xffff;
+}
+
+/*
+ * 	write_packet
+ */
+static inline int 
+write_packet(u32 fifo, struct s3c2410_request *req, unsigned max)
+{
+	unsigned	len;
+	u8		*buf;
+
+	buf = req->req.buf + req->req.actual;
+	len = min(req->req.length - req->req.actual, max);
+	dprintk("write_packet %d %d %d ",req->req.actual,req->req.length,len);
+	req->req.actual += len;
+	dprintk("%d\n",req->req.actual);
+
+	max = len;
+	while (max--)
+		 __raw_writel(*buf++,fifo);
+	return len;
+}
+
+/*
+ * 	write_fifo
+ */
+// return:  0 = still running, 1 = completed, negative = errno
+static int write_fifo(struct s3c2410_ep *ep, struct s3c2410_request *req)
+{
+	u8		*buf;
+	unsigned	count;
+	int		is_last;
+	u32		idx,fifo_reg;
+	u32		ep_csr;
+
+
+	switch(ep->bEndpointAddress&0x7F)
+	{
+		default:
+		case 0: idx = 0;
+			fifo_reg = S3C2410_UDC_EP0_FIFO_REG;
+			break;
+		case 1:
+			idx = 1;
+			fifo_reg = S3C2410_UDC_EP1_FIFO_REG;
+			break;
+		case 2:
+			idx = 2;
+			fifo_reg = S3C2410_UDC_EP2_FIFO_REG;
+			break;
+
+		case 3:
+			idx = 3;
+			fifo_reg = S3C2410_UDC_EP3_FIFO_REG;
+			break;
+
+		case 4:
+			idx = 4;
+			fifo_reg = S3C2410_UDC_EP4_FIFO_REG;
+			break;
+
+	}
+	
+	buf = req->req.buf + req->req.actual;
+	prefetch(buf);
+
+	count = ep->ep.maxpacket;
+	count = write_packet(fifo_reg, req, count);
+
+	/* last packet is often short (sometimes a zlp) */
+	if (count < ep->ep.maxpacket)
+		is_last = 1;
+	else if (req->req.length == req->req.actual
+			&& !req->req.zero)
+		is_last = 2;
+	else
+		is_last = 0;
+
+	dprintk("Written ep%d %d. %d of %d b [last %d]\n",idx,count,req->req.actual,req->req.length,is_last);
+
+	if (is_last)
+	{
+		/* The order is important. It prevents to send 2 packet at the same time
+		 **/
+		if (!idx)
+		{
+			set_ep0_de_in();
+			ep->dev->ep0state=EP0_IDLE;
+		}
+		else
+		{
+			 __raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			 ep_csr=__raw_readl(S3C2410_UDC_IN_CSR1_REG);
+			 __raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			 __raw_writel(ep_csr|S3C2410_UDC_ICSR1_PKTRDY,S3C2410_UDC_IN_CSR1_REG);
+		}
+		done(ep, req, 0);
+	}
+	else
+	{
+		if (!idx)
+		{
+			set_ep0_ipr();
+		}
+		else
+		{
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			ep_csr=__raw_readl(S3C2410_UDC_IN_CSR1_REG);
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			__raw_writel(ep_csr|S3C2410_UDC_ICSR1_PKTRDY,S3C2410_UDC_IN_CSR1_REG);
+		}
+	}
+	return is_last;
+}
+
+static inline int 
+read_packet(u32 fifo, u8 *buf, struct s3c2410_request *req, unsigned avail)
+{
+	unsigned	len;
+
+	len = min(req->req.length - req->req.actual, avail);
+	req->req.actual += len;
+	avail = len;
+
+	while (avail--)
+		*buf++ = (unsigned char)__raw_readl(fifo);
+	return len;
+}
+
+// return:  0 = still running, 1 = queue empty, negative = errno
+static int read_fifo(struct s3c2410_ep *ep, struct s3c2410_request *req)
+{
+	u8		*buf;
+	u32		ep_csr;
+	unsigned	bufferspace;
+	int is_last=1;
+	unsigned avail;
+	int fifo_count = 0;
+	u32		idx,fifo_reg;
+
+
+	switch(ep->bEndpointAddress&0x7F)
+	{
+		default:
+		case 0: idx = 0;
+			fifo_reg = S3C2410_UDC_EP0_FIFO_REG;
+			break;
+		case 1:
+			idx = 1;
+			fifo_reg = S3C2410_UDC_EP1_FIFO_REG;
+			break;
+		case 2:
+			idx = 2;
+			fifo_reg = S3C2410_UDC_EP2_FIFO_REG;
+			break;
+
+		case 3:
+			idx = 3;
+			fifo_reg = S3C2410_UDC_EP3_FIFO_REG;
+			break;
+
+		case 4:
+			idx = 4;
+			fifo_reg = S3C2410_UDC_EP4_FIFO_REG;
+			break;
+
+	}
+
+
+	buf = req->req.buf + req->req.actual;
+	bufferspace = req->req.length - req->req.actual;
+	if (!bufferspace)
+	{
+		dprintk("read_fifo: Buffer full !!\n");
+		return -1;
+	}
+
+
+	__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+		
+        fifo_count = fifo_count_out();
+	dprintk("fifo_read fifo count : %d\n",fifo_count);
+
+	if (fifo_count > ep->ep.maxpacket)
+		avail = ep->ep.maxpacket;
+	else
+		avail = fifo_count;
+
+	fifo_count=read_packet(fifo_reg,buf,req,avail);
+
+	if (fifo_count < ep->ep.maxpacket) {
+		is_last = 1;
+		/* overflowed this request?  flush extra data */
+		if (fifo_count != avail) {
+			req->req.status = -EOVERFLOW;
+		}
+	} else {
+		if (req->req.length == req->req.actual) 
+			is_last = 1;
+		else
+			is_last = 0;
+	}
+
+	__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+	fifo_count = fifo_count_out();		
+	dprintk("fifo_read fifo count : %d [last %d]\n",fifo_count,is_last);
+
+/*	if (idx)
+		is_last=0;*/
+	
+	if (is_last) {
+		if (!idx)
+		{
+			set_ep0_de_out();
+			ep->dev->ep0state=EP0_IDLE;
+		}
+		else
+		{
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			ep_csr=__raw_readl(S3C2410_UDC_OUT_CSR1_REG);
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			__raw_writel(ep_csr&~S3C2410_UDC_OCSR1_PKTRDY,S3C2410_UDC_OUT_CSR1_REG);
+		}
+		done(ep, req, 0);
+		if (!list_empty(&ep->queue))
+		{
+			is_last=0;
+			req = container_of(ep->queue.next,
+				struct s3c2410_request, queue);
+		}
+		else
+			is_last=1;
+//		is_last = 0;
+
+	}
+	else
+	{
+		if (!idx)
+		{
+			clear_ep0_opr();
+		}
+		else
+		{	
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			ep_csr=__raw_readl(S3C2410_UDC_OUT_CSR1_REG);
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			__raw_writel(ep_csr&~S3C2410_UDC_OCSR1_PKTRDY,S3C2410_UDC_OUT_CSR1_REG);
+
+		}
+	}
+	
+
+	return is_last;
+}
+
+
+static int
+read_fifo_crq(struct usb_ctrlrequest *crq)
+{
+	int bytes_read = 0;
+	int fifo_count = 0;
+	int i;
+	
+	
+	unsigned char *pOut = (unsigned char*)crq;
+	
+	__raw_writel(0, S3C2410_UDC_INDEX_REG);
+	
+	fifo_count = fifo_count_out();
+	
+	BUG_ON( fifo_count > 8 );
+	
+	dprintk("read_fifo_crq(): fifo_count=%d\n", fifo_count );
+	while( fifo_count-- ) {
+		i = 0;
+		
+		do {
+			*pOut = (unsigned char)__raw_readl(S3C2410_UDC_EP0_FIFO_REG);
+			udelay( 10 );
+			i++;
+		} while((fifo_count_out() != fifo_count) && (i < 10));
+		
+		if ( i == 10 ) {
+			printk("read_fifo(): read failure\n");
+		}
+		
+		pOut++;
+		bytes_read++;
+	}
+	
+	dprintk("read_fifo_crq: len=%d %02x:%02x {%x,%x,%x}\n",
+			bytes_read, crq->bRequest, crq->bRequestType,
+			crq->wValue, crq->wIndex, crq->wLength);
+	
+	return bytes_read;
+}
+
+/*------------------------- usb state machine -------------------------------*/
+static void handle_ep0(struct s3c2410_udc *dev)
+{
+	u32			ep0csr;
+	struct s3c2410_ep	*ep = &dev->ep [0];
+	struct s3c2410_request	*req;
+	struct usb_ctrlrequest	crq;
+
+	if (list_empty(&ep->queue))
+    		req = 0;
+	else
+		req = list_entry(ep->queue.next, struct s3c2410_request, queue);
+
+  	
+	__raw_writel(0, S3C2410_UDC_INDEX_REG);
+	ep0csr = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+
+	/* clear stall status */
+	if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
+		/* FIXME */
+		nuke(dev, ep);
+	    	dprintk("... clear SENT_STALL ...\n");
+	    	clear_ep0_sst();
+	    	ep0csr &= ~(S3C2410_UDC_EP0_CSR_SENTSTL|S3C2410_UDC_EP0_CSR_SENDSTL);
+		__raw_writel(0, S3C2410_UDC_INDEX_REG);
+		__raw_writel(ep0csr, S3C2410_UDC_IN_CSR1_REG);
+		dev->ep0state = EP0_IDLE;
+		return;
+	}
+
+	/* clear setup end */
+	if (ep0csr & S3C2410_UDC_EP0_CSR_SE
+	    	/* && dev->ep0state != EP0_IDLE */) {
+	    	dprintk("... serviced SETUP_END ...\n");
+		nuke(dev, ep);
+	    	clear_ep0_se();
+		dev->ep0state = EP0_IDLE;
+		return;
+	}
+
+
+	switch (dev->ep0state) {
+	case EP0_IDLE:
+		/* start control request? */
+		if (ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) {
+			int len, ret, tmp;
+			
+			nuke (dev, ep);
+
+			len = read_fifo_crq(&crq);
+			if (len != sizeof(crq)) {
+			  	dprintk("setup begin: fifo READ ERROR" 
+				    	" wanted %d bytes got %d. Stalling out...\n", 
+					sizeof(crq), len);
+ 				set_ep0_ss();
+				return;
+			}
+
+
+			/* cope with automagic for some standard requests. */
+			dev->req_std = (crq.bRequestType & USB_TYPE_MASK)
+						== USB_TYPE_STANDARD;
+			dev->req_config = 0;
+			dev->req_pending = 1;
+			switch (crq.bRequest) {
+				/* hardware restricts gadget drivers here! */
+				case USB_REQ_SET_CONFIGURATION:
+				    	dprintk("USB_REQ_SET_CONFIGURATION ... \n");
+					if (crq.bRequestType == USB_RECIP_DEVICE) {
+config_change:
+						dev->req_config = 1;
+						clear_ep_state(dev);
+						set_ep0_de_out();
+					}
+					break;
+				/* ... and here, even more ... */
+				case USB_REQ_SET_INTERFACE:
+				    	dprintk("USB_REQ_SET_INTERFACE ... \n");
+					if (crq.bRequestType == USB_RECIP_INTERFACE) {
+						goto config_change;
+					}
+					break;
+
+				/* hardware was supposed to hide this */
+				case USB_REQ_SET_ADDRESS:
+				    	dprintk("USB_REQ_SET_ADDRESS ... \n");
+					if (crq.bRequestType == USB_RECIP_DEVICE) {
+						tmp = crq.wValue & 0x7F;
+						dev->address = tmp;
+ 						__raw_writel((tmp | 0x80), S3C2410_UDC_FUNC_ADDR_REG);
+						set_ep0_de_out();
+						return;
+					}
+					break;
+				default:
+					clear_ep0_opr();
+					break;
+			}
+
+			if (crq.bRequestType & USB_DIR_IN)
+				dev->ep0state = EP0_IN_DATA_PHASE;
+			else
+				dev->ep0state = EP0_OUT_DATA_PHASE;
+			ret = dev->driver->setup(&dev->gadget, &crq);
+			if (ret < 0) {
+				if (dev->req_config) {
+					dprintk("config change %02x fail %d?\n",
+						crq.bRequest, ret);
+					return;
+				}
+				if (ret == -EOPNOTSUPP)
+					dprintk("Operation not supported\n");
+				else
+					dprintk("dev->driver->setup failed. (%d)\n",ret);
+				dev->ep0state = EP0_STALL;
+			/* deferred i/o == no response yet */
+			} else if (dev->req_pending) {
+			    	dprintk("dev->req_pending... what now?\n");
+				dev->req_pending=0;
+			}
+			dprintk("ep0state %s\n",ep0states[dev->ep0state]);
+		}
+		break;
+	case EP0_IN_DATA_PHASE:			/* GET_DESCRIPTOR etc */
+	    	dprintk("EP0_IN_DATA_PHASE ... what now?\n");
+		if (!(ep0csr & 2) && req)
+		{
+			write_fifo(ep, req);
+		}
+		break;
+	case EP0_OUT_DATA_PHASE:		/* SET_DESCRIPTOR etc */
+	    	dprintk("EP0_OUT_DATA_PHASE ... what now?\n");
+		if ((ep0csr & 1) && req ) {
+			read_fifo(ep,req);
+		}
+		break;
+	case EP0_END_XFER:
+	    	dprintk("EP0_END_XFER ... what now?\n");
+		dev->ep0state=EP0_IDLE;
+		break;
+	case EP0_STALL:
+	    	set_ep0_ss();
+		break;
+	}
+}
+/*
+ * 	handle_ep - Manage I/O endpoints
+ */
+static void handle_ep(struct s3c2410_ep *ep)
+{
+	struct s3c2410_request	*req;
+	int			is_in = ep->bEndpointAddress & USB_DIR_IN;
+	u32			ep_csr1;
+	u32			idx;
+
+	if (likely (!list_empty(&ep->queue)))
+		req = list_entry(ep->queue.next,
+				struct s3c2410_request, queue);
+	else
+		req = 0;
+		
+	idx = (u32)(ep->bEndpointAddress&0x7F);
+
+	if (is_in) {
+		__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+		ep_csr1 = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+		dprintk("ep%01d write csr:%02x ",idx,ep_csr1);
+		
+		if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL)
+		{
+			dprintk("st\n");
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			__raw_writel(0x00,S3C2410_UDC_IN_CSR1_REG);
+			return;
+		}
+
+		if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req)
+		{
+			write_fifo(ep,req);
+		}
+	} 
+	else {
+		__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+		ep_csr1 = __raw_readl(S3C2410_UDC_OUT_CSR1_REG);
+		dprintk("ep%01d read csr:%02x\n",idx,ep_csr1);
+		
+		if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL)
+		{
+			__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+			__raw_writel(0x00,S3C2410_UDC_OUT_CSR1_REG);
+			return;
+		}
+		if( (ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req)
+		{
+			read_fifo(ep,req);
+		}
+	}
+}
+
+/*
+ *      s3c2410_udc_irq - interrupt handler
+ */
+static irqreturn_t
+s3c2410_udc_irq(int irq, void *_dev, struct pt_regs *r)
+{
+	struct s3c2410_udc      *dev = _dev;
+	int usb_status;
+	int usbd_status;
+	int pwr_reg;
+	int ep0csr;
+	int     i;
+	u32	idx = __raw_readl(S3C2410_UDC_INDEX_REG);
+
+	usb_status = __raw_readl(S3C2410_UDC_USB_INT_REG);
+	usbd_status = __raw_readl(S3C2410_UDC_EP_INT_REG);
+	pwr_reg = __raw_readl(S3C2410_UDC_PWR_REG);
+
+	S3C2410_UDC_SETIX(EP0);
+	ep0csr = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+
+	dprintk("usbs=%02x, usbds=%02x, pwr=%02x ep0csr=%02x\n", usb_status, usbd_status, pwr_reg,ep0csr);
+
+
+	/*
+	 * Now, handle interrupts. There's two types : 
+	 * - Reset, Resume, Suspend coming -> usb_int_reg
+	 * - EP -> ep_int_reg
+	 */
+
+	/* RESET */
+	if (usb_status & S3C2410_UDC_USBINT_RESET)
+	{
+		dprintk("USB reset\n");
+
+	    	__raw_writel(0x00, S3C2410_UDC_PWR_REG);
+		S3C2410_UDC_SETIX(EP0);
+		__raw_writel(S3C2410_UDC_MAXP_8, S3C2410_UDC_MAXP_REG);
+		__raw_writel(0x80, S3C2410_UDC_FUNC_ADDR_REG);
+//		clear_ep0_opr();
+		   
+		/* clear interrupt */
+		__raw_writel(S3C2410_UDC_USBINT_RESET,
+			S3C2410_UDC_USB_INT_REG);
+
+		dev->gadget.speed = USB_SPEED_FULL;
+		dev->ep0state = EP0_IDLE;
+	}
+
+	/* RESUME */
+	if (usb_status & S3C2410_UDC_USBINT_RESUME)
+	{
+		dprintk("USB resume\n");
+		
+		/* clear interrupt */
+		__raw_writel(S3C2410_UDC_USBINT_RESUME,
+			S3C2410_UDC_USB_INT_REG);
+
+		if (dev->gadget.speed != USB_SPEED_UNKNOWN
+			&& dev->driver
+			&& dev->driver->resume)
+			dev->driver->resume(&dev->gadget);
+	}
+
+	/* SUSPEND */
+	if (usb_status & S3C2410_UDC_USBINT_SUSPEND)
+	{
+		dprintk("USB suspend\n");
+			
+		/* clear interrupt */
+		__raw_writel(S3C2410_UDC_USBINT_SUSPEND,
+			S3C2410_UDC_USB_INT_REG);
+				
+		if (dev->gadget.speed != USB_SPEED_UNKNOWN
+				&& dev->driver
+				&& dev->driver->suspend)
+			dev->driver->suspend(&dev->gadget);
+
+		dev->ep0state = EP0_IDLE;
+	}
+
+	/* EP */
+	/* control traffic */
+	/* check on ep0csr != 0 is not a good idea as clearing in_pkt_ready
+	 * generate an interrupt 
+	 */
+	if (usbd_status & S3C2410_UDC_INT_EP0)
+	{
+		dprintk("USB ep0 irq\n");
+		/* Clear the interrupt bit by setting it to 1 */
+		__raw_writel(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
+		handle_ep0(dev);
+	}
+	/* endpoint data transfers */
+	for (i = 1; i < S3C2410_ENDPOINTS; i++) {
+		u32 tmp = 1 << i;
+		if (usbd_status & tmp) {
+			dprintk("USB ep%d irq\n", i);
+
+			/* Clear the interrupt bit by setting it to 1 */
+			__raw_writel(tmp, S3C2410_UDC_EP_INT_REG);
+			handle_ep(&dev->ep[i]);
+		}
+	}
+	
+
+	dprintk("irq: %d done.\n", irq);
+	__raw_writel(idx,S3C2410_UDC_INDEX_REG);
+	return IRQ_HANDLED;		
+}
+
+/*
+ * udc_reinit
+ */
+static void udc_reinit(struct s3c2410_udc *dev)
+{
+	u32     i;
+	
+	/* device/ep0 records init */
+	INIT_LIST_HEAD (&dev->gadget.ep_list);
+	INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
+	dev->ep0state = EP0_IDLE;
+	
+	/* basic endpoint records init */
+	for (i = 0; i < S3C2410_ENDPOINTS; i++) {
+		struct s3c2410_ep *ep = &dev->ep[i];
+		if (i != 0)
+			list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
+
+		ep->desc = 0;
+		INIT_LIST_HEAD (&ep->queue);
+	}
+}
+
+/*------------------------- s3c2410_ep_ops ----------------------------------*/
+
+/*
+ * 	s3c2410_ep_enable
+ */
+static int
+s3c2410_ep_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
+{
+	struct s3c2410_udc	*dev;
+	struct s3c2410_ep	*ep;
+	u32			max, tmp;
+	unsigned long		flags;
+	u32			csr1,csr2;
+	u32			int_en_reg;
+
+
+	ep = container_of (_ep, struct s3c2410_ep, ep);
+	if (!_ep || !desc || ep->desc || _ep->name == ep0name
+			|| desc->bDescriptorType != USB_DT_ENDPOINT)
+		return -EINVAL;
+	dev = ep->dev;
+	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	max = le16_to_cpu (desc->wMaxPacketSize) & 0x1fff;
+
+	spin_lock_irqsave (&dev->lock, flags);
+	_ep->maxpacket = max & 0x7ff;
+	ep->desc = desc;
+	ep->bEndpointAddress = desc->bEndpointAddress;
+
+	/* set max packet */
+	__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+	__raw_writel(max>>3,S3C2410_UDC_MAXP_REG);
+
+
+	/* set type, direction, address; reset fifo counters */
+	if (desc->bEndpointAddress & USB_DIR_IN)
+	{
+		csr1 = S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT;
+		csr2 = S3C2410_UDC_ICSR2_MODEIN|S3C2410_UDC_ICSR2_DMAIEN;
+		
+		__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+		__raw_writel(csr1,S3C2410_UDC_IN_CSR1_REG);
+		__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+		__raw_writel(csr2,S3C2410_UDC_IN_CSR2_REG);
+	}
+	else
+	{
+		/* don't flush he in fifo or there will be an interrupt for that
+		 * endpoint */ 
+		csr1 = S3C2410_UDC_ICSR1_CLRDT;
+		csr2 = S3C2410_UDC_ICSR2_DMAIEN;
+
+		__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+		__raw_writel(csr1,S3C2410_UDC_IN_CSR1_REG);
+		__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+		__raw_writel(csr2,S3C2410_UDC_IN_CSR2_REG);
+		
+		csr1 = S3C2410_UDC_OCSR1_FFLUSH | S3C2410_UDC_OCSR1_CLRDT;
+		csr2 = S3C2410_UDC_OCSR2_DMAIEN;
+		
+		__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+		__raw_writel(csr1,S3C2410_UDC_OUT_CSR1_REG);
+		__raw_writel(ep->num, S3C2410_UDC_INDEX_REG);
+		__raw_writel(csr2,S3C2410_UDC_OUT_CSR2_REG);
+	}
+
+	
+	/* enable irqs */
+	int_en_reg = __raw_readl(S3C2410_UDC_EP_INT_EN_REG);
+	__raw_writel(int_en_reg | (1<<ep->num),S3C2410_UDC_EP_INT_EN_REG);
+
+
+	/* print some debug message */
+	tmp = desc->bEndpointAddress;
+	dprintk ("enable %s(%d) ep%x%s-blk max %02x\n",
+		_ep->name,ep->num, tmp, desc->bEndpointAddress & USB_DIR_IN ? "in" : "out", max);
+
+	spin_unlock_irqrestore (&dev->lock, flags);
+	
+	return 0;
+}
+
+/*
+ * s3c2410_ep_disable
+ */
+static int s3c2410_ep_disable (struct usb_ep *_ep)
+{
+	struct s3c2410_ep	*ep = container_of(_ep, struct s3c2410_ep, ep);
+	unsigned long	flags;
+
+	if (!_ep || !ep->desc) {
+		dprintk("%s not enabled\n",
+			_ep ? ep->ep.name : NULL);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&ep->dev->lock, flags);
+	ep->desc = 0;
+	
+	nuke (ep->dev, ep);
+	ep->ep.maxpacket = EP_FIFO_SIZE; 
+
+	spin_unlock_irqrestore(&ep->dev->lock, flags);
+
+	dprintk("%s disabled\n", _ep->name);
+
+	return 0;
+}
+
+/*
+ * s3c2410_alloc_request
+ */
+static struct usb_request *
+s3c2410_alloc_request (struct usb_ep *_ep, int mem_flags)
+{
+	struct s3c2410_ep	*ep;
+	struct s3c2410_request	*req;
+
+    	printk("s3c2410_alloc_request(ep=%p,flags=%d)\n", _ep, mem_flags);
+
+	ep = container_of (_ep, struct s3c2410_ep, ep);
+	if (!_ep)
+		return 0;
+
+	req = kmalloc (sizeof *req, mem_flags);
+	if (!req)
+		return 0;
+	memset (req, 0, sizeof *req);
+	INIT_LIST_HEAD (&req->queue);
+	return &req->req;
+}
+
+/*
+ * s3c2410_free_request
+ */
+static void
+s3c2410_free_request (struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct s3c2410_ep	*ep;
+	struct s3c2410_request	*req;
+
+    	printk("s3c2410_free_request(ep=%p,req=%p)\n", _ep, _req);
+
+	ep = container_of (_ep, struct s3c2410_ep, ep);
+	if (!ep || !_req || (!ep->desc && _ep->name != ep0name))
+		return;
+
+	req = container_of (_req, struct s3c2410_request, req);
+	WARN_ON (!list_empty (&req->queue));
+	kfree (req);
+}
+
+/*
+ * 	s3c2410_alloc_buffer
+ */
+static void *
+s3c2410_alloc_buffer (
+	struct usb_ep *_ep,
+	unsigned bytes,
+	dma_addr_t *dma,
+	int mem_flags)
+{
+	char *retval;
+
+    	printk("s3c2410_alloc_buffer()\n");
+
+	if (!the_controller->driver)
+		return 0;
+	retval = kmalloc (bytes, mem_flags);
+	*dma = (dma_addr_t) retval;
+	return retval;
+}
+
+/*
+ * s3c2410_free_buffer
+ */
+static void
+s3c2410_free_buffer (
+	struct usb_ep *_ep,
+	void *buf,
+	dma_addr_t dma,
+	unsigned bytes)
+{
+    	printk("s3c2410_free_buffer()\n");
+
+	if (bytes)
+		kfree (buf);
+}
+
+/*
+ * 	s3c2410_queue
+ */
+static int
+s3c2410_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+{
+	struct s3c2410_request	*req;
+	struct s3c2410_ep	*ep;
+	struct s3c2410_udc	*dev;
+	u32			ep_csr=0;
+	int 			fifo_count=0;
+
+	req = container_of(_req, struct s3c2410_request, req);
+	if (unlikely (!_req || !_req->complete || !_req->buf
+	|| !list_empty(&req->queue))) {
+		if (!_req)
+			dprintk("s3c2410_queue: 1 X X X\n");
+		else
+		{
+			dprintk("s3c2410_queue: 0 %01d %01d %01d\n",!_req->complete,!_req->buf, !list_empty(&req->queue));
+		}
+		return -EINVAL;
+	}
+
+	ep = container_of(_ep, struct s3c2410_ep, ep);
+	if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+		dprintk("s3c2410_queue: inval 2\n");
+		return -EINVAL;
+	}
+
+	dev = ep->dev;
+	if (unlikely (!dev->driver
+			|| dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+		return -ESHUTDOWN;
+	}
+
+	/* iso is always one packet per request, that's the only way
+	 * we can report per-packet status.  that also helps with dma.
+	 */
+	if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
+			&& req->req.length > le16_to_cpu
+						(ep->desc->wMaxPacketSize)))
+		return -EMSGSIZE;
+
+	_req->status = -EINPROGRESS;
+	_req->actual = 0;
+
+	if (ep->bEndpointAddress)
+	{
+		__raw_writel(ep->bEndpointAddress&0x7F,S3C2410_UDC_INDEX_REG);
+		ep_csr = __raw_readl(ep->bEndpointAddress&USB_DIR_IN ? S3C2410_UDC_IN_CSR1_REG : S3C2410_UDC_OUT_CSR1_REG);
+		fifo_count=fifo_count_out();
+	}
+	/* kickstart this i/o queue? */
+	if (list_empty(&ep->queue)) {
+		if (ep->bEndpointAddress == 0 /* ep0 */) {
+
+			switch (dev->ep0state) {
+			case EP0_IN_DATA_PHASE:
+				if (write_fifo(ep, req))
+				{
+					req = 0;
+				}
+				break;
+
+			case EP0_OUT_DATA_PHASE:
+				/* nothing to do here */
+				dev->ep0state = EP0_IDLE;
+				break;
+
+			default:
+				return -EL2HLT;
+			}
+		}
+		else if ((ep->bEndpointAddress & USB_DIR_IN) != 0
+				&& (!(ep_csr&S3C2410_UDC_OCSR1_PKTRDY)) && write_fifo(ep, req)) {
+			req = 0;
+		} else if ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY) && fifo_count && read_fifo(ep, req)) {
+			req = 0;
+		}
+
+	}
+
+	/* pio or dma irq handler advances the queue. */
+	if (likely (req != 0))
+		list_add_tail(&req->queue, &ep->queue);
+	dprintk("s3c2410_queue normal end\n");
+	return 0;
+}
+
+/* 
+ * 	s3c2410_dequeue
+ */
+static int s3c2410_dequeue (struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct s3c2410_ep	*ep;
+	struct s3c2410_udc	*udc;
+	int			retval = -EINVAL;
+	unsigned long		flags;
+	struct s3c2410_request	*req = 0;
+
+    	printk("s3c2410_dequeue(ep=%p,req=%p)\n", _ep, _req);
+
+	if (!the_controller->driver)
+		return -ESHUTDOWN;
+
+	if (!_ep || !_req)
+		return retval;
+	ep = container_of (_ep, struct s3c2410_ep, ep);
+	udc = container_of (ep->gadget, struct s3c2410_udc, gadget);
+
+	spin_lock_irqsave (&udc->lock, flags);
+	list_for_each_entry (req, &ep->queue, queue) {
+		if (&req->req == _req) {
+			list_del_init (&req->queue);
+			_req->status = -ECONNRESET;
+			retval = 0;
+			break;
+		}
+	}
+	spin_unlock_irqrestore (&udc->lock, flags);
+
+	if (retval == 0) {
+		dprintk( "dequeued req %p from %s, len %d buf %p\n",
+				req, _ep->name, _req->length, _req->buf);
+
+		_req->complete (_ep, _req);
+		done(ep, req, -ECONNRESET);
+	}
+	return retval;
+
+	return 0;
+}
+
+
+/* 
+ * s3c2410_set_halt
+ */
+static int
+s3c2410_set_halt (struct usb_ep *_ep, int value)
+{
+	return 0;
+}
+
+
+static const struct usb_ep_ops s3c2410_ep_ops = {
+	.enable         = s3c2410_ep_enable,
+	.disable        = s3c2410_ep_disable,
+	
+	.alloc_request  = s3c2410_alloc_request,
+	.free_request   = s3c2410_free_request,
+	
+	.alloc_buffer   = s3c2410_alloc_buffer,
+	.free_buffer    = s3c2410_free_buffer,
+	
+	.queue          = s3c2410_queue,
+	.dequeue        = s3c2410_dequeue,
+	
+	.set_halt       = s3c2410_set_halt,
+};
+
+/*------------------------- usb_gadget_ops ----------------------------------*/
+
+/*
+ * 	s3c2410_g_get_frame
+ */
+static int s3c2410_g_get_frame (struct usb_gadget *_gadget)
+{
+	int tmp;
+	
+	printk("s3c2410_g_get_frame()\n");
+
+	tmp = __raw_readl(S3C2410_UDC_FRAME_NUM2_REG) << 8;
+	tmp |= __raw_readl(S3C2410_UDC_FRAME_NUM1_REG);
+	
+	return tmp & 0xffff;
+}
+
+/*
+ * 	s3c2410_wakeup
+ */
+static int s3c2410_wakeup (struct usb_gadget *_gadget)
+{
+	
+	printk("s3c2410_wakeup()\n");
+	
+	return 0;
+}
+
+/*
+ * 	s3c2410_set_selfpowered
+ */
+static int s3c2410_set_selfpowered (struct usb_gadget *_gadget, int value)
+{
+	struct s3c2410_udc  *udc;
+	
+	printk("s3c2410_set_selfpowered()\n");
+	
+	udc = container_of (_gadget, struct s3c2410_udc, gadget);
+	
+	if (value)
+		udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
+	else
+		udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
+	
+	return 0;
+}
+                                                                                   
+
+
+static const struct usb_gadget_ops s3c2410_ops = {
+	.get_frame          = s3c2410_g_get_frame,
+	.wakeup             = s3c2410_wakeup,
+	.set_selfpowered    = s3c2410_set_selfpowered,
+};
+
+
+/*------------------------- gadget driver handling---------------------------*/
+
+/*
+ * 	nop_release
+ */
+static void nop_release (struct device *dev)
+{
+	        dprintk("%s %s\n", __FUNCTION__, dev->bus_id);
+}
+/*
+ *	usb_gadget_register_driver
+ */
+int
+usb_gadget_register_driver (struct usb_gadget_driver *driver)
+{
+	struct s3c2410_udc *udc = the_controller;
+	int		retval, i;
+
+    	printk("usb_gadget_register_driver() '%s'\n",
+		driver->driver.name);
+
+	if (!udc)
+		return -ENODEV;
+	if (udc->driver)
+		return -EBUSY;
+	if (!driver->bind || !driver->unbind || !driver->setup
+			|| driver->speed == USB_SPEED_UNKNOWN)
+		return -EINVAL;
+
+	udc->gadget.name = gadget_name;
+	udc->gadget.ops = &s3c2410_ops;
+	udc->gadget.is_dualspeed = 1;
+
+	udc->gadget.dev.release = nop_release;
+	udc->devstatus = 0;
+
+	INIT_LIST_HEAD (&udc->gadget.ep_list);
+	for (i = 0; i < S3C2410_ENDPOINTS; i++) {
+		struct s3c2410_ep *ep = &udc->ep[i];
+
+		if (!ep_name[i])
+			break;
+		ep->num = i;
+		ep->ep.name = ep_name[i];
+		ep->ep.ops = &s3c2410_ep_ops;
+		list_add_tail (&ep->ep.ep_list, &udc->gadget.ep_list);
+		ep->halted = ep->already_seen = ep->setup_stage = 0;
+
+		/* maxpacket differs between ep0 and others ep */
+		if (!i) 
+			ep->ep.maxpacket = EP0_FIFO_SIZE;
+		else
+			ep->ep.maxpacket = EP_FIFO_SIZE;
+		ep->last_io = jiffies;
+		ep->gadget = &udc->gadget;
+		ep->dev = udc;
+		ep->desc = 0;
+		INIT_LIST_HEAD (&ep->queue);
+	}
+
+	udc->gadget.ep0 = &udc->ep[0].ep;
+	udc->ep[0].ep.maxpacket = 8;
+	list_del_init (&udc->ep[0].ep.ep_list);
+	INIT_LIST_HEAD(&udc->fifo_req.queue);
+
+	udc->driver = driver;
+	udc->gadget.dev.driver = &driver->driver;
+	dprintk( "binding gadget driver '%s'\n", driver->driver.name);
+	if ((retval = driver->bind (&udc->gadget)) != 0) {
+		udc->driver = 0;
+		udc->gadget.dev.driver = 0;
+		return retval;
+	}
+
+        driver->driver.bus = 0;
+	udc_reinit(udc);
+	
+	return 0;
+}
+
+
+/*
+ * 	usb_gadget_unregister_driver
+ */
+int
+usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+{
+	struct s3c2410_udc *udc = the_controller;
+
+	if (!udc)
+		return -ENODEV;
+	if (!driver || driver != udc->driver)
+		return -EINVAL;
+
+    	printk("usb_gadget_register_driver() '%s'\n",
+		driver->driver.name);
+
+	driver->unbind (&udc->gadget);
+	udc->driver = 0;
+
+	device_release_driver (&udc->gadget.dev);
+	driver_unregister (&driver->driver);
+
+	return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ *	probe - binds to the platform device
+ */
+static int __init s3c2410_udc_probe(struct device *_dev)
+{
+	struct s3c2410_udc *udc = &memory;
+	u32 int_en_reg;
+	int retval;
+
+
+	dprintk("s3c2410_udc_probe\n");
+
+
+	device_initialize(&udc->gadget.dev);
+	udc->gadget.dev.parent = _dev;
+	udc->gadget.dev.dma_mask = _dev->dma_mask;
+
+	the_controller = udc;
+	dev_set_drvdata(_dev, udc);
+	spin_lock_init (&udc->lock);
+
+	/* irq setup after old hardware state is cleaned up */
+	retval = request_irq(IRQ_USBD, s3c2410_udc_irq,
+		SA_INTERRUPT, gadget_name, udc);
+	if (retval != 0) {
+		printk(KERN_ERR "%s: can't get irq %i, err %d\n",
+			gadget_name, IRQ_USBD, retval);
+		return -EBUSY;
+	}
+	dprintk("%s: got irq %i\n", gadget_name, IRQ_USBD);
+	udc->got_irq = 1;
+
+	/* Enable ep0 interrupts */
+	int_en_reg = __raw_readl(S3C2410_UDC_EP_INT_EN_REG);
+	__raw_writel(int_en_reg | 1,S3C2410_UDC_EP_INT_EN_REG);
+
+	return 0;
+}
+
+/*
+ * 	s3c2410_udc_remove
+ */
+static int __exit s3c2410_udc_remove(struct device *_dev)
+{
+	struct s3c2410_udc *udc = _dev->driver_data;
+	
+	dprintk("s3c2410_udc_remove\n");
+	usb_gadget_unregister_driver(udc->driver);
+	
+	if (udc->got_irq) {
+		free_irq(IRQ_USBD, udc);
+		udc->got_irq = 0;
+	}
+	
+	dev_set_drvdata(_dev, 0);
+	kfree(udc);
+	
+	return 0;
+}
+                                                                               
+static struct device_driver udc_driver = {
+	.name		= "s3c2410-usbgadget",
+	.bus            = &platform_bus_type,
+	.probe          = s3c2410_udc_probe,
+	.remove         = __exit_p(s3c2410_udc_remove),			
+};
+
+static int __init udc_init(void)
+{
+	dprintk("%s: version %s\n", gadget_name, DRIVER_VERSION);
+	
+	udc_clock = clk_get(NULL, "usb-device");
+	if (!udc_clock) {
+		printk(KERN_INFO "failed to get udc clock source\n");
+		return -ENOENT;
+	}
+	clk_use(udc_clock);
+	clk_enable(udc_clock);
+	dprintk("got and enabled clock\n");
+						
+	
+	return driver_register(&udc_driver);
+}
+
+static void __exit udc_exit(void)
+{
+	if (udc_clock) {
+		clk_disable(udc_clock);
+		clk_unuse(udc_clock);
+		clk_put(udc_clock);
+		udc_clock = NULL;
+	}
+		
+	driver_unregister(&udc_driver);
+}
+
+
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
+EXPORT_SYMBOL (usb_gadget_register_driver);
+
+module_init(udc_init);
+module_exit(udc_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/s3c2410_udc.h linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/s3c2410_udc.h
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/s3c2410_udc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/s3c2410_udc.h	2004-11-09 21:18:11.000000000 +0100
@@ -0,0 +1,215 @@
+#ifndef _S3C2410_UDC_H
+#define _S3C2410_UDC_H
+
+struct s3c2410_ep {
+	struct list_head		queue;
+	unsigned long			last_io;	/* jiffies timestamp */
+	struct usb_gadget		*gadget;
+	struct s3c2410_udc		*dev;
+	const struct usb_endpoint_descriptor *desc;
+	struct usb_ep			ep;
+	u8				num;
+
+	unsigned short			fifo_size;
+	u8				bEndpointAddress;
+	u8				bmAttributes;
+
+	unsigned			halted : 1;
+	unsigned			already_seen : 1;
+	unsigned			setup_stage : 1;
+};
+
+static const char ep0name [] = "ep0";
+
+static const char *const ep_name[] = {
+	ep0name,                                /* everyone has ep0 */
+	/* s3c2410 four bidirectional bulk endpoints */
+	"ep1-bulk", "ep2-bulk", "ep3-bulk", "ep4-bulk",
+};
+
+#define S3C2410_ENDPOINTS       ARRAY_SIZE(ep_name)
+
+#define EP0_FIFO_SIZE		8
+#define EP_FIFO_SIZE		64
+
+
+struct s3c2410_request {
+	struct list_head		queue;		/* ep's requests */
+	struct usb_request		req;
+};
+
+enum ep0_state { 
+        EP0_IDLE,
+        EP0_IN_DATA_PHASE,
+        EP0_OUT_DATA_PHASE,
+        EP0_END_XFER,
+        EP0_STALL,
+};
+
+static const char *ep0states[]= {
+        "EP0_IDLE",
+        "EP0_IN_DATA_PHASE",
+        "EP0_OUT_DATA_PHASE",
+        "EP0_END_XFER",
+        "EP0_STALL",
+};
+
+struct s3c2410_udc {
+	spinlock_t			lock;
+
+	struct s3c2410_ep		ep[S3C2410_ENDPOINTS];
+	int				address;
+	struct usb_gadget		gadget;
+	struct usb_gadget_driver	*driver;
+	struct s3c2410_request		fifo_req;
+	u8				fifo_buf[EP_FIFO_SIZE];
+	u16				devstatus;
+	
+	u32				port_status;
+    	int 	    	    	    	ep0state;
+
+	unsigned			got_irq : 1;
+	
+	unsigned			req_std : 1;
+	unsigned			req_config : 1;
+	unsigned			req_pending : 1;
+};
+
+/****************** MACROS ******************/
+/* #define BIT_MASK	BIT_MASK*/
+#define BIT_MASK	0xFF
+
+#define __raw_maskb(v,m,a)      \
+	        __raw_writeb((__raw_readb(a) & ~(m))|((v)&(m)), (a))
+
+#define __raw_maskw(v,m,a)      \
+	        __raw_writew((__raw_readw(a) & ~(m))|((v)&(m)), (a))
+
+#define __raw_maskl(v,m,a)      \
+	        __raw_writel((__raw_readl(a) & ~(m))|((v)&(m)), (a))
+
+#define clear_ep0_sst() do { 				\
+    	S3C2410_UDC_SETIX(EP0); 			\
+	__raw_writel(0x00, S3C2410_UDC_EP0_CSR_REG); 	\
+} while(0)
+
+#define clear_ep0_se() do {				\
+    	S3C2410_UDC_SETIX(EP0); 			\
+	__raw_maskl(S3C2410_UDC_EP0_CSR_SSE,		\
+	    	BIT_MASK, S3C2410_UDC_EP0_CSR_REG); 	\
+} while(0)
+
+#define clear_ep0_opr() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl(S3C2410_UDC_EP0_CSR_SOPKTRDY,	\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG); 	\
+} while(0)
+
+#define set_ep0_ipr() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl(S3C2410_UDC_EP0_CSR_IPKRDY,		\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG); 	\
+} while(0)
+
+#define set_ep0_de() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl(S3C2410_UDC_EP0_CSR_DE,		\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);		\
+} while(0)
+
+#define set_ep0_ss() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl(S3C2410_UDC_EP0_CSR_SENDSTL,	\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);	\
+} while(0)
+
+#define set_ep0_de_out() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY 	\
+		| S3C2410_UDC_EP0_CSR_DE),		\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);		\
+} while(0)
+
+#define set_ep0_sse_out() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY 	\
+		| S3C2410_UDC_EP0_CSR_SSE),		\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);		\
+} while(0)
+
+#define set_ep0_de_in() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl((S3C2410_UDC_EP0_CSR_IPKRDY		\
+		| S3C2410_UDC_EP0_CSR_DE),		\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);		\
+} while(0)
+
+#define set_ep0_caramba() do {				\
+   	S3C2410_UDC_SETIX(EP0);				\
+	__raw_maskl((S3C2410_UDC_EP0_CSR_IPKRDY		\
+		| S3C2410_UDC_EP0_CSR_SOPKTRDY		\
+		| S3C2410_UDC_EP0_CSR_DE),		\
+		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);		\
+} while(0)
+
+
+
+#define clear_stall_ep1_out() do {			\
+   	S3C2410_UDC_SETIX(EP1);				\
+	__raw_orl(0, S3C2410_UDC_OUT_CSR1_REG);		\
+} while(0)
+
+
+#define clear_stall_ep2_out() do {			\
+   	S3C2410_UDC_SETIX(EP2);				\
+	__raw_orl(0, S3C2410_UDC_OUT_CSR1_REG);		\
+} while(0)
+
+
+#define clear_stall_ep3_out() do {			\
+   	S3C2410_UDC_SETIX(EP3);				\
+	__raw_orl(0, S3C2410_UDC_OUT_CSR1_REG);		\
+} while(0)
+
+
+#define clear_stall_ep4_out() do {			\
+   	S3C2410_UDC_SETIX(EP4);				\
+	__raw_orl(0, S3C2410_UDC_OUT_CSR1_REG);		\
+} while(0)
+
+/*************************** DEBUG FUNCTION ***************************/
+// #define DEBUG
+
+#ifdef DEBUG
+uint32_t s3c2410_ticks=0;
+static int dprintk(const char *fmt, ...)
+{
+	static char printk_buf[1024];
+	static long prevticks;
+	static int invocation;
+	va_list args;
+	int len;
+	
+	if (s3c2410_ticks != prevticks) {
+		prevticks = s3c2410_ticks;
+		invocation = 0;
+	}
+	
+	len = scnprintf(printk_buf, \
+			sizeof(printk_buf), "%1lu.%02d USB: ", \
+			prevticks, invocation++);
+
+	va_start(args, fmt);
+	len = vscnprintf(printk_buf+len, \
+			sizeof(printk_buf)-len, fmt, args);
+	va_end(args);
+	
+	return printk("%s", printk_buf);
+}
+#else
+static int dprintk(const char *fmt, ...)  { return 0; }
+#endif
+
+#endif
+
+
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/serial.c linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/serial.c
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/serial.c	2004-11-09 20:22:16.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/serial.c	2004-11-09 21:18:11.000000000 +0100
@@ -486,7 +486,11 @@
 static struct usb_device_descriptor gs_device_desc = {
 	.bLength =		USB_DT_DEVICE_SIZE,
 	.bDescriptorType =	USB_DT_DEVICE,
-	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+ 	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+#else
+	.bcdUSB =		__constant_cpu_to_le16(0x0110),
+#endif
 	.bDeviceSubClass =	0,
 	.bDeviceProtocol =	0,
 	.idVendor =		__constant_cpu_to_le16(GS_VENDOR_ID),
@@ -1529,6 +1533,9 @@
 	} else if (gadget_is_n9604(gadget)) {
 		gs_device_desc.bcdDevice =
 			__constant_cpu_to_le16(GS_VERSION_NUM|0x0009);
+ 	} else if (gadget_is_s3c2410(gadget)) {
+ 		gs_device_desc.bcdDevice =
+ 			__constant_cpu_to_le16(GS_VERSION_NUM|0x000A);
 	} else {
 		printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
 			gadget->name);
diff -Nur linux-2.6.10-rc1-bk19/drivers/usb/gadget/zero.c linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/zero.c
--- linux-2.6.10-rc1-bk19/drivers/usb/gadget/zero.c	2004-11-09 20:22:16.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/usb/gadget/zero.c	2004-11-09 21:18:11.000000000 +0100
@@ -227,7 +227,11 @@
 	.bLength =		sizeof device_desc,
 	.bDescriptorType =	USB_DT_DEVICE,
 
+#ifdef	CONFIG_USB_GADGET_DUALSPEED
 	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
+#else
+	.bcdUSB =               __constant_cpu_to_le16 (0x0110),
+#endif
 	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
 
 	.idVendor =		__constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
@@ -1190,6 +1194,8 @@
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
 	} else if (gadget_is_n9604(gadget)) {
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
+	} else if (gadget_is_s3c2410(gadget)) {
+ 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x020A);
 	} else {
 		/* gadget zero is so simple (for now, no altsettings) that
 		 * it SHOULD NOT have problems with bulk-capable hardware.
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/console/font_clean_4x6.c linux-2.6.10-rc1-bk19-h1940/drivers/video/console/font_clean_4x6.c
--- linux-2.6.10-rc1-bk19/drivers/video/console/font_clean_4x6.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/console/font_clean_4x6.c	2004-11-09 21:32:56.000000000 +0100
@@ -0,0 +1,1059 @@
+/*       Font file generated by Jay Carlson from clR4x6.bdf */
+
+/*
+COMMENT  Copyright 1989 Dale Schumacher, dal@syntel.mn.org
+COMMENT                 399 Beacon Ave.
+COMMENT                 St. Paul, MN  55104-3527
+COMMENT
+COMMENT  Permission to use, copy, modify, and distribute this software and
+COMMENT  its documentation for any purpose and without fee is hereby
+COMMENT  granted, provided that the above copyright notice appear in all
+COMMENT  copies and that both that copyright notice and this permission
+COMMENT  notice appear in supporting documentation, and that the name of
+COMMENT  Dale Schumacher not be used in advertising or publicity pertaining to
+COMMENT  distribution of the software without specific, written prior
+COMMENT  permission.  Dale Schumacher makes no representations about the
+COMMENT  suitability of this software for any purpose.  It is provided "as
+COMMENT  is" without express or implied warranty.
+*/
+
+#include <linux/font.h>
+
+#define FONTDATAMAX (6 * 256)
+
+static unsigned char fontdata_clean_4x6[FONTDATAMAX] = {
+
+	 /* 0 0x00 C000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0xf0, /* 11110000 */
+
+	 /* 1 0x01 C001 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 2 0x02 C002 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 3 0x03 C003 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 4 0x04 C004 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 5 0x05 C005 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 6 0x06 C006 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 7 0x07 C007 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 8 0x08 C010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 9 0x09 C011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 10 0x0a C012 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 11 0x0b C013 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 12 0x0c C014 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 13 0x0d C015 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 14 0x0e C016 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 15 0x0f C017 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 16 0x10 C020 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 17 0x11 C021 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 18 0x12 C022 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 19 0x13 C023 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 20 0x14 C024 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 21 0x15 C025 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 22 0x16 C026 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 23 0x17 C027 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 24 0x18 C030 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 25 0x19 C031 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 26 0x1a C032 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 27 0x1b C033 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 28 0x1c C034 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 29 0x1d C035 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 30 0x1e C036 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 31 0x1f C037 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 32 0x20 C040 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 33 0x21 ! */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 34 0x22 " */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 35 0x23 # */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 36 0x24 $ */
+	0xe0, /* 11100000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 37 0x25 % */
+	0xa0, /* 10100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x80, /* 10000000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 38 0x26 & */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 39 0x27 ' */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 40 0x28 ( */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 41 0x29 ) */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 42 0x2a * */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 43 0x2b + */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 44 0x2c , */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 45 0x2d - */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 46 0x2e . */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 47 0x2f / */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	 /* 48 0x30 0 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 49 0x31 1 */
+	0x40, /* 01000000 */
+	0xc0, /* 11000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 50 0x32 2 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 51 0x33 3 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 52 0x34 4 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 53 0x35 5 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 54 0x36 6 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 55 0x37 7 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 56 0x38 8 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 57 0x39 9 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 58 0x3a : */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 59 0x3b ; */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 60 0x3c < */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x80, /* 10000000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 61 0x3d = */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 62 0x3e > */
+	0x80, /* 10000000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	 /* 63 0x3f ? */
+	0xc0, /* 11000000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 64 0x40 @ */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 65 0x41 A */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 66 0x42 B */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	 /* 67 0x43 C */
+	0x60, /* 01100000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 68 0x44 D */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	 /* 69 0x45 E */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 70 0x46 F */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	 /* 71 0x47 G */
+	0x60, /* 01100000 */
+	0x80, /* 10000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 72 0x48 H */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 73 0x49 I */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 74 0x4a J */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 75 0x4b K */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 76 0x4c L */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 77 0x4d M */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 78 0x4e N */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 79 0x4f O */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 80 0x50 P */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	 /* 81 0x51 Q */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 82 0x52 R */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 83 0x53 S */
+	0x60, /* 01100000 */
+	0x80, /* 10000000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	 /* 84 0x54 T */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 85 0x55 U */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 86 0x56 V */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 87 0x57 W */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 88 0x58 X */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 89 0x59 Y */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 90 0x5a Z */
+	0xe0, /* 11100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 91 0x5b [ */
+	0x60, /* 01100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 92 0x5c \ */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 93 0x5d ] */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 94 0x5e ^ */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 95 0x5f _ */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 96 0x60 ` */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 97 0x61 a */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 98 0x62 b */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	 /* 99 0x63 c */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 100 0x64 d */
+	0x20, /* 00100000 */
+	0x60, /* 01100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 101 0x65 e */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 102 0x66 f */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 103 0x67 g */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xa0, /* 10100000 */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0xc0, /* 11000000 */
+
+	 /* 104 0x68 h */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 105 0x69 i */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 106 0x6a j */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+
+	 /* 107 0x6b k */
+	0x80, /* 10000000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 108 0x6c l */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 109 0x6d m */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 110 0x6e n */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 111 0x6f o */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 112 0x70 p */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+
+	 /* 113 0x71 q */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xa0, /* 10100000 */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+
+	 /* 114 0x72 r */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xa0, /* 10100000 */
+	0x80, /* 10000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	 /* 115 0x73 s */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	 /* 116 0x74 t */
+	0x40, /* 01000000 */
+	0xe0, /* 11100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 117 0x75 u */
+	0x00, /* 00000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 118 0x76 v */
+	0x00, /* 00000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 119 0x77 w */
+	0x00, /* 00000000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 120 0x78 x */
+	0x00, /* 00000000 */
+	0xa0, /* 10100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0x00, /* 00000000 */
+
+	 /* 121 0x79 y */
+	0x00, /* 00000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0xc0, /* 11000000 */
+
+	 /* 122 0x7a z */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+	 /* 123 0x7b { */
+	0x60, /* 01100000 */
+	0x40, /* 01000000 */
+	0xc0, /* 11000000 */
+	0x40, /* 01000000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	 /* 124 0x7c | */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 125 0x7d } */
+	0xc0, /* 11000000 */
+	0x40, /* 01000000 */
+	0x60, /* 01100000 */
+	0x40, /* 01000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	 /* 126 0x7e ~ */
+	0x20, /* 00100000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 127 0x7f C177 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0xa0, /* 10100000 */
+	0xa0, /* 10100000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+
+};
+
+struct font_desc font_clean_4x6 = {
+	CLEAN4x6_IDX,
+	"Clean4x6",
+	4,
+	6,
+	fontdata_clean_4x6,
+	3
+};
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/console/font_clean_5x8.c linux-2.6.10-rc1-bk19-h1940/drivers/video/console/font_clean_5x8.c
--- linux-2.6.10-rc1-bk19/drivers/video/console/font_clean_5x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/console/font_clean_5x8.c	2004-11-09 21:32:56.000000000 +0100
@@ -0,0 +1,1314 @@
+/*       Font file generated by Jay Carlson from clR5x8.bdf */
+
+/*
+COMMENT  Copyright 1989 Dale Schumacher, dal@syntel.mn.org
+COMMENT                 399 Beacon Ave.
+COMMENT                 St. Paul, MN  55104-3527
+COMMENT
+COMMENT  Permission to use, copy, modify, and distribute this software and
+COMMENT  its documentation for any purpose and without fee is hereby
+COMMENT  granted, provided that the above copyright notice appear in all
+COMMENT  copies and that both that copyright notice and this permission
+COMMENT  notice appear in supporting documentation, and that the name of
+COMMENT  Dale Schumacher not be used in advertising or publicity pertaining to
+COMMENT  distribution of the software without specific, written prior
+COMMENT  permission.  Dale Schumacher makes no representations about the
+COMMENT  suitability of this software for any purpose.  It is provided "as
+COMMENT  is" without express or implied warranty.
+*/
+
+#include <linux/font.h>
+
+#define FONTDATAMAX (8 * 256)
+
+static unsigned char fontdata_clean_5x8[FONTDATAMAX] = {
+
+	 /* 0 0x00 C000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 1 0x01 C001 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 2 0x02 C002 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 3 0x03 C003 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 4 0x04 C004 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 5 0x05 C005 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 6 0x06 C006 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 7 0x07 C007 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x40, /* 01000000 */
+	0x58, /* 01011000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 8 0x08 C010 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 9 0x09 C011 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 10 0x0a C012 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 11 0x0b C013 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x50, /* 01010000 */
+	0x60, /* 01100000 */
+	0x50, /* 01010000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 12 0x0c C014 */
+	0x00, /* 00000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 13 0x0d C015 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 14 0x0e C016 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x68, /* 01101000 */
+	0x58, /* 01011000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 15 0x0f C017 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 16 0x10 C020 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 17 0x11 C021 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	 /* 18 0x12 C022 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x50, /* 01010000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 19 0x13 C023 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x40, /* 01000000 */
+	0x30, /* 00110000 */
+	0x08, /* 00001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 20 0x14 C024 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 21 0x15 C025 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 22 0x16 C026 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 23 0x17 C027 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 24 0x18 C030 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 25 0x19 C031 */
+	0x00, /* 00000000 */
+	0x88, /* 10001000 */
+	0x50, /* 01010000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 26 0x1a C032 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 27 0x1b C033 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 28 0x1c C034 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 29 0x1d C035 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 30 0x1e C036 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 31 0x1f C037 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 32 0x20 C040 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 33 0x21 ! */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 34 0x22 " */
+	0x28, /* 00101000 */
+	0x28, /* 00101000 */
+	0x28, /* 00101000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 35 0x23 # */
+	0x50, /* 01010000 */
+	0x50, /* 01010000 */
+	0xf8, /* 11111000 */
+	0x50, /* 01010000 */
+	0xf8, /* 11111000 */
+	0x50, /* 01010000 */
+	0x50, /* 01010000 */
+	0x00, /* 00000000 */
+
+	 /* 36 0x24 $ */
+	0x20, /* 00100000 */
+	0x78, /* 01111000 */
+	0xa0, /* 10100000 */
+	0x70, /* 01110000 */
+	0x28, /* 00101000 */
+	0xf0, /* 11110000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 37 0x25 % */
+	0x60, /* 01100000 */
+	0x68, /* 01101000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x58, /* 01011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 38 0x26 & */
+	0x30, /* 00110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x28, /* 00101000 */
+	0x50, /* 01010000 */
+	0x50, /* 01010000 */
+	0x28, /* 00101000 */
+	0x00, /* 00000000 */
+
+	 /* 39 0x27 ' */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 40 0x28 ( */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x08, /* 00001000 */
+	0x00, /* 00000000 */
+
+	 /* 41 0x29 ) */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 42 0x2a * */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 43 0x2b + */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0xf8, /* 11111000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 44 0x2c , */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+
+	 /* 45 0x2d - */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 46 0x2e . */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 47 0x2f / */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+
+	 /* 48 0x30 0 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x58, /* 01011000 */
+	0x68, /* 01101000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 49 0x31 1 */
+	0x20, /* 00100000 */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 50 0x32 2 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	 /* 51 0x33 3 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x08, /* 00001000 */
+	0x30, /* 00110000 */
+	0x08, /* 00001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 52 0x34 4 */
+	0x08, /* 00001000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x28, /* 00101000 */
+	0x28, /* 00101000 */
+	0x78, /* 01111000 */
+	0x08, /* 00001000 */
+	0x00, /* 00000000 */
+
+	 /* 53 0x35 5 */
+	0x78, /* 01111000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 54 0x36 6 */
+	0x30, /* 00110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 55 0x37 7 */
+	0x78, /* 01111000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 56 0x38 8 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 57 0x39 9 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 58 0x3a : */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 59 0x3b ; */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+
+	 /* 60 0x3c < */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x08, /* 00001000 */
+	0x00, /* 00000000 */
+
+	 /* 61 0x3d = */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 62 0x3e > */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 63 0x3f ? */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 64 0x40 @ */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x58, /* 01011000 */
+	0x58, /* 01011000 */
+	0x40, /* 01000000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 65 0x41 A */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 66 0x42 B */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 67 0x43 C */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 68 0x44 D */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 69 0x45 E */
+	0x78, /* 01111000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	 /* 70 0x46 F */
+	0x78, /* 01111000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 71 0x47 G */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x40, /* 01000000 */
+	0x58, /* 01011000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	 /* 72 0x48 H */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 73 0x49 I */
+	0x70, /* 01110000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 74 0x4a J */
+	0x18, /* 00011000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 75 0x4b K */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x50, /* 01010000 */
+	0x60, /* 01100000 */
+	0x50, /* 01010000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 76 0x4c L */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	 /* 77 0x4d M */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 78 0x4e N */
+	0x48, /* 01001000 */
+	0x68, /* 01101000 */
+	0x68, /* 01101000 */
+	0x58, /* 01011000 */
+	0x58, /* 01011000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 79 0x4f O */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 80 0x50 P */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 81 0x51 Q */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+
+	 /* 82 0x52 R */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x50, /* 01010000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 83 0x53 S */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x40, /* 01000000 */
+	0x30, /* 00110000 */
+	0x08, /* 00001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 84 0x54 T */
+	0xf8, /* 11111000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 85 0x55 U */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 86 0x56 V */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 87 0x57 W */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 88 0x58 X */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 89 0x59 Y */
+	0x88, /* 10001000 */
+	0x88, /* 10001000 */
+	0x50, /* 01010000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 90 0x5a Z */
+	0x78, /* 01111000 */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	 /* 91 0x5b [ */
+	0x38, /* 00111000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	 /* 92 0x5c \ */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+
+	 /* 93 0x5d ] */
+	0x70, /* 01110000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 94 0x5e ^ */
+	0x20, /* 00100000 */
+	0x50, /* 01010000 */
+	0x88, /* 10001000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 95 0x5f _ */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+
+	 /* 96 0x60 ` */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 97 0x61 a */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x58, /* 01011000 */
+	0x28, /* 00101000 */
+	0x00, /* 00000000 */
+
+	 /* 98 0x62 b */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 99 0x63 c */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	 /* 100 0x64 d */
+	0x08, /* 00001000 */
+	0x08, /* 00001000 */
+	0x38, /* 00111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	 /* 101 0x65 e */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x78, /* 01111000 */
+	0x40, /* 01000000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 102 0x66 f */
+	0x18, /* 00011000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x70, /* 01110000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 103 0x67 g */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x08, /* 00001000 */
+	0x30, /* 00110000 */
+
+	 /* 104 0x68 h */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 105 0x69 i */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 106 0x6a j */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x60, /* 01100000 */
+
+	 /* 107 0x6b k */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x48, /* 01001000 */
+	0x50, /* 01010000 */
+	0x60, /* 01100000 */
+	0x50, /* 01010000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 108 0x6c l */
+	0x60, /* 01100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 109 0x6d m */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xd0, /* 11010000 */
+	0xa8, /* 10101000 */
+	0xa8, /* 10101000 */
+	0xa8, /* 10101000 */
+	0x88, /* 10001000 */
+	0x00, /* 00000000 */
+
+	 /* 110 0x6e n */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 111 0x6f o */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 112 0x70 p */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x70, /* 01110000 */
+	0x40, /* 01000000 */
+
+	 /* 113 0x71 q */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x08, /* 00001000 */
+
+	 /* 114 0x72 r */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x58, /* 01011000 */
+	0x60, /* 01100000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 115 0x73 s */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x40, /* 01000000 */
+	0x30, /* 00110000 */
+	0x08, /* 00001000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	 /* 116 0x74 t */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x78, /* 01111000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	 /* 117 0x75 u */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	 /* 118 0x76 v */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	 /* 119 0x77 w */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x88, /* 10001000 */
+	0xa8, /* 10101000 */
+	0xa8, /* 10101000 */
+	0xa8, /* 10101000 */
+	0x50, /* 01010000 */
+	0x00, /* 00000000 */
+
+	 /* 120 0x78 x */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x30, /* 00110000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x00, /* 00000000 */
+
+	 /* 121 0x79 y */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x48, /* 01001000 */
+	0x38, /* 00111000 */
+	0x08, /* 00001000 */
+	0x30, /* 00110000 */
+
+	 /* 122 0x7a z */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	 /* 123 0x7b { */
+	0x08, /* 00001000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x10, /* 00010000 */
+	0x08, /* 00001000 */
+	0x00, /* 00000000 */
+
+	 /* 124 0x7c | */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x00, /* 00000000 */
+
+	 /* 125 0x7d } */
+	0x40, /* 01000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x10, /* 00010000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x40, /* 01000000 */
+	0x00, /* 00000000 */
+
+	 /* 126 0x7e ~ */
+	0x28, /* 00101000 */
+	0x50, /* 01010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	 /* 127 0x7f C177 */
+	0x00, /* 00000000 */
+	0x20, /* 00100000 */
+	0x20, /* 00100000 */
+	0x50, /* 01010000 */
+	0x50, /* 01010000 */
+	0x88, /* 10001000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+};
+
+struct font_desc font_clean_5x8 = {
+	CLEAN5x8_IDX,
+	"Clean5x8",
+	5,
+	8,
+	fontdata_clean_5x8,
+	3
+};
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/console/fonts.c linux-2.6.10-rc1-bk19-h1940/drivers/video/console/fonts.c
--- linux-2.6.10-rc1-bk19/drivers/video/console/fonts.c	2004-10-18 23:54:55.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/console/fonts.c	2004-11-09 21:32:56.000000000 +0100
@@ -56,6 +56,14 @@
 #undef NO_FONTS
     &font_mini_4x6,
 #endif
+#ifdef CONFIG_FONT_CLEAN_4x6
+#undef NO_FONTS
+    &font_clean_4x6,
+#endif
+#ifdef CONFIG_FONT_CLEAN_5x8
+#undef NO_FONTS
+    &font_clean_5x8,
+#endif
 };
 
 #define num_fonts (sizeof(fonts)/sizeof(*fonts))
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/console/Kconfig linux-2.6.10-rc1-bk19-h1940/drivers/video/console/Kconfig
--- linux-2.6.10-rc1-bk19/drivers/video/console/Kconfig	2004-10-18 23:53:43.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/console/Kconfig	2004-11-09 21:32:56.000000000 +0100
@@ -170,6 +170,20 @@
 config FONT_MINI_4x6
 	bool "Mini 4x6 font"
 	depends on !SPARC32 && !SPARC64 && FONTS
+	help
+          Mini console font for tiny displays
+
+config FONT_CLEAN_4x6
+	bool "Clean 4x6 font"
+	depends on !SPARC32 && !SPARC64 && FONTS
+	help
+          Mini console font for tiny displays
+
+config FONT_CLEAN_5x8
+	bool "Clean 5x8 font"
+	depends on !SPARC32 && !SPARC64 && FONTS
+	help
+          Small console font for small displays
 
 config FONT_SUN8x16
 	bool "Sparc console 8x16 font"
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/console/Makefile linux-2.6.10-rc1-bk19-h1940/drivers/video/console/Makefile
--- linux-2.6.10-rc1-bk19/drivers/video/console/Makefile	2004-11-09 20:21:42.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/console/Makefile	2004-11-09 21:32:56.000000000 +0100
@@ -13,6 +13,8 @@
 font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
 font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
 font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
+font-objs-$(CONFIG_FONT_CLEAN_4x6) += font_clean_4x6.o
+font-objs-$(CONFIG_FONT_CLEAN_5x8) += font_clean_5x8.o
 
 font-objs += $(font-objs-y)
 
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/Kconfig linux-2.6.10-rc1-bk19-h1940/drivers/video/Kconfig
--- linux-2.6.10-rc1-bk19/drivers/video/Kconfig	2004-11-09 20:22:16.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/Kconfig	2004-11-09 21:18:22.000000000 +0100
@@ -1069,6 +1069,20 @@
 
 	  Documentation/fb/pxafb.txt describes the available parameters.
 
+config FB_S3C2410
+	tristate "S3C2410 LCD framebuffer support"
+	depends on FB && ARCH_S3C2410
+	---help---
+	  Frame buffer driver for the built-in LCD controller in the Samsung
+	  S3C2410 processor.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called s3c2410fb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_VIRTUAL
 	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
 	depends on FB
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/Makefile linux-2.6.10-rc1-bk19-h1940/drivers/video/Makefile
--- linux-2.6.10-rc1-bk19/drivers/video/Makefile	2004-11-09 20:22:16.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/Makefile	2004-11-09 21:18:22.000000000 +0100
@@ -94,6 +94,7 @@
 obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PXA)		  += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
+obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/s3c2410fb.c linux-2.6.10-rc1-bk19-h1940/drivers/video/s3c2410fb.c
--- linux-2.6.10-rc1-bk19/drivers/video/s3c2410fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/s3c2410fb.c	2004-11-09 21:15:27.000000000 +0100
@@ -0,0 +1,683 @@
+/*
+ * linux/drivers/s3c2410fb.c
+ * Copyright (c) Arnaud Patard
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *	    S3C2410 LCD Controller Frame Buffer Driver
+ *	    based on skeletonfb.c, sa1100fb.c
+ *
+ * ChangeLog
+ *
+ * 2004-11-09: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * 	- Removed the use of currcon as it no more exist
+ *
+ * 2004-11-03: Ben Dooks <ben-linux@fluff.org>
+ *	- minor cleanups
+ *	- add suspend/resume support
+ *	- s3c2410fb_setcolreg() not valid in >8bpp modes
+ *	- removed last CONFIG_FB_S3C2410_FIXED
+ *	- ensure lcd controller stopped before cleanup
+ *	- added sysfs interface for backlight power
+ *	- added mask for gpio configuration
+ *	- ensured IRQs disabled during GPIO configuration
+ *	- disable TPAL before enabling video
+ *
+ * 2004-09-20: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - Suppress command line options
+ *
+ * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * 	- code cleanup
+ *
+ * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * 	- Renamed from h1940fb.c to s3c2410fb.c
+ * 	- Add support for different devices
+ * 	- Backlight support
+ *
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ *	- added clock (de-)allocation code
+ *	- added fixem fbmem option
+ *
+ * 2004-07-27: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *	- code cleanup
+ *	- added a forgotten return in h1940fb_init
+ *
+ * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
+ *	- code cleanup and extended debugging
+ *
+ * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *	- First version
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/string.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <asm/mach/map.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/s3c2410fb.h>
+#include <asm/hardware/clock.h>
+
+#include "s3c2410fb.h"
+
+#define S3C2410_FBIO_SETBRIGHTNESS	_IOW('F', 0x50, int)
+#define DEFAULT_BACKLIGHT_LEVEL		2
+
+static struct s3c2410fb_info info;
+static struct s3c2410fb_mach_info *mach_info;
+
+/* backlight and power control functions */
+
+static int backlight_level = DEFAULT_BACKLIGHT_LEVEL;
+static int backlight_power = 1;
+
+
+static inline void s3c2410fb_lcd_power(int to)
+{
+	if (mach_info == NULL)
+		return;
+
+	if (mach_info->lcd_power)
+		(mach_info->lcd_power)(to);
+}
+
+static inline void s3c2410fb_backlight_power(int to)
+{
+	if (mach_info == NULL)
+		return;
+
+	backlight_power = to;
+	
+	if (mach_info->backlight_power)
+		(mach_info->backlight_power)(to);
+}
+
+static inline void s3c2410fb_backlight_level(int to)
+{
+	if (mach_info == NULL)
+		return;
+
+	backlight_level = to;
+
+	if (mach_info->set_brightness)
+		(mach_info->set_brightness)(to);
+}
+
+/*
+ *	s3c2410fb_check_var():
+ *	Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *	if it's too big, return -EINVAL.
+ *
+ */
+static int s3c2410fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	dprintk("check_var(var=%p, info=%p)\n", var, info);
+	
+	var->red.offset		= 11;
+	var->green.offset	= 5;
+	var->blue.offset	= 0;
+ 	var->red.length		= 5;
+	var->green.length	= 6;
+	var->blue.length	= 5;
+
+	return 0;
+}
+
+/*
+ *      s3c2410fb_set_par - Optional function. Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ */
+static int s3c2410fb_set_par(struct fb_info *info)
+{
+	struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
+	struct fb_var_screeninfo *var = &info->var;
+
+	/* We support only 16BPP true color */
+	fbi->fb.fix.visual	    = FB_VISUAL_TRUECOLOR;
+	fbi->fb.fix.line_length     = (var->width*var->bits_per_pixel)/8;
+	return 0;
+}
+
+
+static int s3c2410fb_setcolreg(unsigned regno,
+			       unsigned red, unsigned green, unsigned blue,
+			       unsigned transp, struct fb_info *info)
+{
+	struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
+	int bpp, m = 0;
+
+	bpp = fbi->fb.var.bits_per_pixel;
+	m = 1 << bpp;
+
+	if (regno >= m) {
+		return -EINVAL;
+	}
+
+	switch (bpp) {
+	case 16:
+		/* RGB 565 */
+		fbi->pseudo_pal[regno] = ((red & 0xF800)
+			| ((green & 0xFC00) >> 5)
+			| ((blue & 0xF800) >> 11));
+		break;
+	}
+
+	return 0;
+}
+
+
+/**
+ *	s3c2410fb_pan_display
+ *	@var: frame buffer variable screen structure
+ *	@info: frame buffer structure that represents a single frame buffer
+ *
+ *	Pan (or wrap, depending on the `vmode' field) the display using the
+ *	`xoffset' and `yoffset' fields of the `var' structure.
+ *	If the values don't fit, return -EINVAL.
+ *
+ *	Returns negative errno on error, or zero on success.
+ */
+static int s3c2410fb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	dprintk("pan_display(var=%p, info=%p)\n", var, info);
+	return 0;
+}
+
+/**
+ *      s3c2410fb_blank
+ *	@blank_mode: the blank mode we want.
+ *	@info: frame buffer structure that represents a single frame buffer
+ *
+ *	Blank the screen if blank_mode != 0, else unblank. Return 0 if
+ *	blanking succeeded, != 0 if un-/blanking failed due to e.g. a
+ *	video mode which doesn't support it. Implements VESA suspend
+ *	and powerdown modes on hardware that supports disabling hsync/vsync:
+ *	blank_mode == 2: suspend vsync
+ *	blank_mode == 3: suspend hsync
+ *	blank_mode == 4: powerdown
+ *
+ *	Returns negative errno on error, or zero on success.
+ *
+ */
+static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
+{
+	dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
+	
+	if (mach_info == NULL)
+		return -EINVAL;
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:	/* lcd on, backlight on */
+		s3c2410fb_lcd_power(1);
+		s3c2410fb_backlight_power(1);
+		break;
+
+	case VESA_VSYNC_SUSPEND: /* lcd on, backlight off */
+	case VESA_HSYNC_SUSPEND:
+		s3c2410fb_lcd_power(1);
+		s3c2410fb_backlight_power(0);
+		break;
+
+	case VESA_POWERDOWN: /* lcd and backlight off */
+		s3c2410fb_lcd_power(0);
+		s3c2410fb_backlight_power(0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * s3c2410fb_ioctl - non standard ioctls (atm, only level)
+ */
+static int s3c2410fb_ioctl(struct inode *inode, struct file *file,
+			   u_int cmd, u_long arg,
+			   struct fb_info *info)
+{
+	int value;
+
+	switch(cmd)
+	{
+		case S3C2410_FBIO_SETBRIGHTNESS:
+			if (copy_from_user(&value, (__user void *)arg,
+					   sizeof(int)))
+				return(-EFAULT);
+			s3c2410fb_backlight_level(value);
+			return(0);
+			break;
+		default:
+			return(-EINVAL);
+	}
+}
+
+/* sysfs export of baclight control */
+
+static int s3c2410fb_backlight_level_show(struct device *dev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", backlight_level);
+}
+
+static int s3c2410fb_backlight_power_show(struct device *dev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", backlight_power);
+}
+
+static int s3c2410fb_backlight_level_store(struct device *dev,
+					   const char *buf, size_t len)
+{
+	unsigned long value = simple_strtoul(buf, NULL, 10);
+
+	if (mach_info == NULL)
+		return -EINVAL;
+
+	if (value < mach_info->backlight_min ||
+	    value > mach_info->backlight_max)
+		return -ERANGE;
+
+	s3c2410fb_backlight_level(value);
+	return len;
+}
+
+static int s3c2410fb_backlight_power_store(struct device *dev,
+					   const char *buf, size_t len)
+{
+	if (mach_info == NULL)
+		return -EINVAL;
+
+	if (len < 1)
+		return -EINVAL;
+
+	if (strnicmp(buf, "on", 2) == 0 ||
+	    strnicmp(buf, "1", 1) == 0) {
+		s3c2410fb_backlight_power(1);
+	} else if (strnicmp(buf, "off", 3) == 0 ||
+		   strnicmp(buf, "0", 1) == 0) {
+		s3c2410fb_backlight_power(0);
+	} else {
+		return -EINVAL;
+	}
+
+	return len;
+}
+
+static DEVICE_ATTR(backlight_level, 0644,
+		   s3c2410fb_backlight_level_show,
+		   s3c2410fb_backlight_level_store);
+
+static DEVICE_ATTR(backlight_power, 0644,
+		   s3c2410fb_backlight_power_show,
+		   s3c2410fb_backlight_power_store);
+
+
+
+static struct fb_ops s3c2410fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= s3c2410fb_check_var,
+	.fb_set_par	= s3c2410fb_set_par,	
+	.fb_blank	= s3c2410fb_blank,
+	.fb_pan_display	= s3c2410fb_pan_display,	
+	.fb_setcolreg	= s3c2410fb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,	
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,	
+	.fb_ioctl	= s3c2410fb_ioctl,
+};
+
+
+/* Fake monspecs to fill in fbinfo structure */
+/* Don't know if the values are important    */
+static struct fb_monspecs monspecs __initdata = {
+	.hfmin	= 30000,
+	.hfmax	= 70000,
+	.vfmin	= 50,
+	.vfmax	= 65,
+};
+
+/*
+ * s3c2410fb_map_video_memory():
+ *	Allocates the DRAM memory for the frame buffer.  This buffer is
+ *	remapped into a non-cached, non-buffered, memory region to
+ *	allow palette and pixel writes to occur without flushing the
+ *	cache.  Once this area is remapped, all virtual memory
+ *	access to the video memory should occur at the new region.
+ */
+static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi)
+{
+	dprintk("map_video_memory(fbi=%p)\n", fbi);
+
+	fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
+	fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
+					      &fbi->map_dma, GFP_KERNEL);
+
+	fbi->map_size = fbi->fb.fix.smem_len;
+
+	if (fbi->map_cpu) {
+		/* prevent initial garbage on screen */
+		dprintk("map_video_memory: clear %p:%08x\n",
+			fbi->map_cpu, fbi->map_size);
+		memset(fbi->map_cpu, 0xf0, fbi->map_size);
+
+		fbi->screen_dma = fbi->map_dma;
+		fbi->fb.screen_base = fbi->map_cpu;
+		fbi->fb.fix.smem_start = fbi->screen_dma;
+
+		dprintk("map_video_memory: dma=%08x cpu=%p size=%08x\n",
+			fbi->map_dma, fbi->map_cpu, fbi->fb.fix.smem_len);
+	}
+
+	return fbi->map_cpu ? 0 : -ENOMEM;
+}
+
+static inline void modify_gpio(unsigned long reg,
+			       unsigned long set, unsigned long mask)
+{
+	unsigned long tmp;
+	
+	tmp = __raw_readl(reg) & ~mask;
+	__raw_writel(tmp | set, reg);
+
+	dprintk("%08lx set to %08x\n", reg, __raw_readl(reg)); 
+}
+
+/*
+ * s3c2410fb_init_registers - Initialise all LCD-related registers
+ */
+int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
+{	
+	unsigned long saddr1, saddr2, saddr3;
+	unsigned long flags;
+
+	/* Initialise LCD with values from haret */
+
+	local_irq_save(flags);
+
+	/* modify the gpio(s) with interrupts set (bjd) */
+
+	modify_gpio(S3C2410_GPCUP, mach_info->gpcup, mach_info->gpcup_mask);
+	modify_gpio(S3C2410_GPCCON, mach_info->gpccon, mach_info->gpccon_mask);
+	modify_gpio(S3C2410_GPDUP, mach_info->gpdup, mach_info->gpdup_mask);
+	modify_gpio(S3C2410_GPDCON, mach_info->gpdcon, mach_info->gpdcon_mask);
+
+	local_irq_restore(flags);
+
+	__raw_writel(mach_info->lcdcon1, S3C2410_LCDCON1);
+	__raw_writel(mach_info->lcdcon2, S3C2410_LCDCON2);
+	__raw_writel(mach_info->lcdcon3, S3C2410_LCDCON3);
+	__raw_writel(mach_info->lcdcon4, S3C2410_LCDCON4);
+	__raw_writel(mach_info->lcdcon5, S3C2410_LCDCON5);
+
+
+	saddr1 =  S3C2410_LCDBANK(fbi->fb.fix.smem_start >> 22)
+		| S3C2410_LCDBASEU(fbi->fb.fix.smem_start >> 1);
+	saddr2 = (fbi->fb.fix.smem_start+(mach_info->width*mach_info->height*2)) >> 1;
+	saddr3 =  S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(mach_info->width);
+	
+	
+	dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
+	__raw_writel(saddr1, S3C2410_LCDSADDR1);
+
+	dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
+	__raw_writel(saddr2, S3C2410_LCDSADDR2);
+	
+	dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
+	__raw_writel(saddr3, S3C2410_LCDSADDR3);
+
+	dprintk("LPCSEL    = 0x%08lx\n", mach_info->lpcsel);
+	__raw_writel(mach_info->lpcsel, S3C2410_LPCSEL);
+
+	dprintk("replacing TPAL %08x\n", __raw_readl(S3C2410_TPAL));
+
+	/* ensure temporary palette disabled */
+	__raw_writel(0x00, S3C2410_TPAL);
+
+	/* probably not required */
+	msleep(10);
+
+	/* Enable video by setting the ENVID bit to 1 */
+	__raw_writel(mach_info->lcdcon1|S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
+	return 0;
+}
+
+static struct clk      *lcd_clock;
+
+int __init s3c2410fb_probe(struct device *dev)
+{
+	char driver_name[]="s3c2410fb";
+	int ret;
+
+	mach_info = dev->platform_data;
+	if (mach_info == NULL)
+	{
+		printk(KERN_ERR "no platform data for lcd, cannot attach\n");
+		return -EINVAL;
+	}
+	
+	s3c2410fb_backlight_power(1);
+	s3c2410fb_lcd_power(1);
+
+	s3c2410fb_backlight_level(DEFAULT_BACKLIGHT_LEVEL);
+
+	dprintk("devinit\n");
+
+	strcpy(info.fb.fix.id, driver_name);
+	info.fb.fix.type	    = FB_TYPE_PACKED_PIXELS;
+	info.fb.fix.type_aux	    = 0;
+	info.fb.fix.xpanstep	    = 0;
+	info.fb.fix.ypanstep	    = 0;
+	info.fb.fix.ywrapstep	    = 0;
+	info.fb.fix.accel	    = FB_ACCEL_NONE;
+
+	info.fb.var.nonstd	    = 0;
+	info.fb.var.activate	    = FB_ACTIVATE_NOW;
+	info.fb.var.height	    = mach_info->height;
+	info.fb.var.width	    = mach_info->width;
+	info.fb.var.accel_flags     = 0;
+	info.fb.var.vmode	    = FB_VMODE_NONINTERLACED;
+
+	info.fb.fbops		    = &s3c2410fb_ops;
+	info.fb.flags		    = FBINFO_FLAG_DEFAULT;
+	info.fb.monspecs	    = monspecs;
+	info.fb.pseudo_palette      = &info.pseudo_pal;
+
+
+	info.fb.var.xres	    = mach_info->xres;
+	info.fb.var.xres_virtual    = mach_info->xres;
+	info.fb.var.yres	    = mach_info->yres;
+	info.fb.var.yres_virtual    = mach_info->yres;
+	info.fb.var.bits_per_pixel  = mach_info->bpp;
+
+
+	info.fb.var.red.offset      = 11;
+	info.fb.var.green.offset    = 5;
+	info.fb.var.blue.offset     = 0;
+	info.fb.var.transp.offset   = 0;
+	info.fb.var.red.length      = 5;
+	info.fb.var.green.length    = 6;
+	info.fb.var.blue.length     = 5;
+	info.fb.var.transp.length   = 0;
+
+	info.fb.fix.smem_len	    = info.fb.var.xres * info.fb.var.yres *
+				      info.fb.var.bits_per_pixel / 8;
+
+	if (!request_mem_region(S3C2410_VA_LCD, SZ_1M, "s3c2410-lcd"))
+		return -EBUSY;
+	dprintk("got LCD region\n");
+
+	lcd_clock = clk_get(NULL, "lcd");
+	if (!lcd_clock) {
+		printk(KERN_INFO "failed to get lcd clock source\n");
+		return -ENOENT;
+	}
+	clk_use(lcd_clock);
+	clk_enable(lcd_clock);
+	dprintk("got and enabled clock\n");
+
+	/* maybe not required */
+	msleep(10);
+
+
+	/* Initialize video memory */
+	ret = s3c2410fb_map_video_memory(&info);
+	if (ret) {
+		printk("Failed to allocate video RAM: %d\n", ret);
+		ret = -ENOMEM;
+		goto failed;
+	}
+	dprintk("got video memory\n");
+
+	ret = s3c2410fb_init_registers(&info);
+	s3c2410fb_lcd_power(1);
+
+	ret = s3c2410fb_check_var(&info.fb.var, &info.fb);
+
+	ret = register_framebuffer(&info.fb);
+	if (ret < 0) {
+		printk("Failed to register framebuffer device: %d\n", ret);
+		goto failed;
+	}
+
+	/* create device files */
+
+	device_create_file(dev, &dev_attr_backlight_power);
+	device_create_file(dev, &dev_attr_backlight_level);
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+		info.fb.node, info.fb.fix.id);
+
+	return 0;
+failed:
+	release_mem_region(S3C2410_VA_LCD, S3C2410_SZ_LCD);
+	return ret;
+}
+
+/* s3c2410fb_stop_lcd
+ *
+ * shutdown the lcd controller 
+*/
+
+static void s3c2410fb_stop_lcd(void)
+{
+	unsigned long flags;
+	unsigned long tmp;
+
+	local_irq_save(flags);
+	
+	tmp = __raw_readl(S3C2410_LCDCON1);
+	__raw_writel(tmp & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
+	
+	local_irq_restore(flags);
+}
+
+/*
+ *  Cleanup
+ */
+static void __exit s3c2410fb_cleanup(void)
+{
+	s3c2410fb_stop_lcd();
+	msleep(1);
+
+	if (lcd_clock) {
+		clk_disable(lcd_clock);
+		clk_unuse(lcd_clock);
+		clk_put(lcd_clock);
+		lcd_clock = NULL;
+	}
+
+	unregister_framebuffer(&info.fb);
+	release_mem_region(S3C2410_VA_LCD, S3C2410_SZ_LCD);
+}
+
+#ifdef CONFIG_PM
+
+/* suspend and resume support for the lcd controller */
+
+static int s3c2410fb_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) {
+		s3c2410fb_stop_lcd();
+
+		/* sleep before disabling the clock, we need to ensure
+		 * the LCD DMA engine is not going to get back on the bus
+		 * before the clock goes off again (bjd) */
+
+		if (mach_info != NULL) {
+			/* don't use our helper functions in this file,
+			   becuase we want to save the original values for
+			   when the system wakes up
+			*/
+
+			if (mach_info->lcd_power)
+				(mach_info->lcd_power)(0);
+
+			if (mach_info->backlight_power)
+				(mach_info->backlight_power)(0);
+		}
+
+		msleep(1);
+		clk_disable(lcd_clock);
+	}
+
+	return 0;
+}
+
+static int s3c2410fb_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_ENABLE) {
+		clk_enable(lcd_clock);
+		msleep(1);
+
+		s3c2410fb_init_registers(&info);
+		
+		/* resume the backlight level */
+		s3c2410fb_backlight_power(backlight_power);
+		s3c2410fb_backlight_level(backlight_level);
+	}
+
+	return 0;
+}
+
+#else
+#define s3c2410fb_suspend NULL
+#define s3c2410fb_resume  NULL
+#endif
+
+static struct device_driver s3c2410fb_driver = {
+	.name		= "s3c2410-lcd",
+	.bus		= &platform_bus_type,
+	.probe		= s3c2410fb_probe,
+	.suspend	= s3c2410fb_suspend,
+	.resume		= s3c2410fb_resume,
+};
+
+int __devinit s3c2410fb_init(void)
+{
+	return driver_register(&s3c2410fb_driver);
+}
+
+module_init(s3c2410fb_init);
+module_exit(s3c2410fb_cleanup);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
+MODULE_LICENSE("GPL");
diff -Nur linux-2.6.10-rc1-bk19/drivers/video/s3c2410fb.h linux-2.6.10-rc1-bk19-h1940/drivers/video/s3c2410fb.h
--- linux-2.6.10-rc1-bk19/drivers/video/s3c2410fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/drivers/video/s3c2410fb.h	2004-11-09 21:18:22.000000000 +0100
@@ -0,0 +1,47 @@
+#ifndef __S3C2410FB_H
+#define __S3C2410FB_H
+/*
+ * linux/drivers/s3c2410fb.h
+ * Copyright (c) Arnaud Patard
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *	    S3C2410 LCD Controller Frame Buffer Driver
+ *	    based on skeletonfb.c, sa1100fb.h
+ *
+ * ChangeLog
+ *
+ * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * 	- Renamed from h1940fb.h to s3c2410fb.h
+ * 	- Chenged h1940 to s3c2410
+ * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *	- First version
+ */
+
+struct s3c2410fb_info {
+	struct fb_info		fb;
+	struct device		*dev;
+
+	/* raw memory addresses */
+	dma_addr_t		map_dma;	/* physical */
+	u_char *		map_cpu;	/* virtual */
+	u_int			map_size;
+
+	/* addresses of pieces placed in raw buffer */
+	u_char *		screen_cpu;	/* virtual address of frame buffer */
+	dma_addr_t		screen_dma;	/* physical address of frame buffer */
+
+	u32 pseudo_pal[16];
+};
+
+int s3c2410fb_init(void);
+
+#if 1
+#define dprintk(msg...)	printk(KERN_INFO "s3c2410fb: " msg)
+#else
+#define dprintk(msg...) while (0) { }
+#endif
+
+#endif
diff -Nur linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/regs-adc.h linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/regs-adc.h
--- linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/regs-adc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/regs-adc.h	2004-11-09 21:18:18.000000000 +0100
@@ -0,0 +1,36 @@
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H
+
+#define S3C2410_ADCREG(x) ((x) + S3C2410_VA_ADC)
+
+#define S3C2410_ADCCON		S3C2410_ADCREG(0x00)
+#define S3C2410_ECFLG		(1<<15)
+#define S3C2410_PRSCEN		(1<<14)
+#define S3C2410_PRSCVL(x)	((x)<<6)
+#define S3C2410_SEL_MUX(x)	((x)<<3)
+#define S3C2410_STDBM		(1<<2)
+#define S3C2410_READ_START	(1<<1)
+#define S3C2410_ENABLE_START	(1<<0)
+
+#define S3C2410_ADCTSC		S3C2410_ADCREG(0x04)
+#define S3C2410_YM_SEN		(1<<7)
+#define S3C2410_YP_SEN		(1<<6)
+#define S3C2410_XM_SEN		(1<<5)
+#define S3C2410_XP_SEN		(1<<4)
+#define S3C2410_PULL_UP		(1<<3)
+#define S3C2410_AUTO_PST	(1<<2)
+#define S3C2410_XY_PST(x)	(x)
+
+#define S3C2410_ADCDLY		S3C2410_ADCREG(0x08)
+#define S3C2410_DELAY(x)	(x)
+
+#define S3C2410_ADCDAT0		S3C2410_ADCREG(0x0C)
+#define S3C2410_ADCDAT1		S3C2410_ADCREG(0x10)
+#define S3C2410_DAT_UPDOWN	(1<<15)
+#define S3C2410_DAT_AUTO_PST	(1<<14)
+#define S3C2410_DAT_XY_PST(x)	((x)<<12)
+
+
+#endif
+
+
diff -Nur linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/regs-serial.h linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/regs-serial.h
--- linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/regs-serial.h	2004-11-09 20:22:17.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/regs-serial.h	2004-11-09 21:33:00.000000000 +0100
@@ -68,6 +68,12 @@
 #define S3C2410_LCON_STOPB	  (1<<2)
 #define S3C2410_LCON_IRM          (1<<6)
 
+#define S3C2440_UCON_CLKMASK	  (3<<10)
+#define S3C2440_UCON_PCLK	  (0<<10)
+#define S3C2440_UCON_UCLK	  (1<<10)
+#define S3C2440_UCON_PCLK2	  (2<<10)
+#define S3C2440_UCON_FCLK	  (3<<10)
+
 #define S3C2410_UCON_UCLK	  (1<<10)
 #define S3C2410_UCON_SBREAK	  (1<<4)
 
@@ -77,19 +83,35 @@
 #define S3C2410_UCON_RXIRQMODE	  (1<<0)
 #define S3C2410_UCON_RXFIFO_TOI	  (1<<7)
 
-#define S3C2410_UCON_DEFAULT	  (S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL \
-				   | S3C2410_UCON_TXIRQMODE | S3C2410_UCON_RXIRQMODE \
-				   | S3C2410_UCON_RXFIFO_TOI)
+#define S3C2410_UCON_DEFAULT	  (S3C2410_UCON_TXILEVEL  | \
+				   S3C2410_UCON_RXILEVEL  | \
+				   S3C2410_UCON_TXIRQMODE | \
+				   S3C2410_UCON_RXIRQMODE | \
+				   S3C2410_UCON_RXFIFO_TOI)
 
 #define S3C2410_UFCON_FIFOMODE	  (1<<0)
 #define S3C2410_UFCON_TXTRIG0	  (0<<6)
 #define S3C2410_UFCON_RXTRIG8	  (1<<4)
 #define S3C2410_UFCON_RXTRIG12	  (2<<4)
 
+/* S3C2440 FIFO trigger levels */
+#define S3C2440_UFCON_RXTRIG1	  (0<<4)
+#define S3C2440_UFCON_RXTRIG8	  (1<<4)
+#define S3C2440_UFCON_RXTRIG16	  (2<<4)
+#define S3C2440_UFCON_RXTRIG32	  (3<<4)
+
+#define S3C2440_UFCON_TXTRIG0	  (0<<6)
+#define S3C2440_UFCON_TXTRIG16	  (1<<6)
+#define S3C2440_UFCON_TXTRIG32	  (2<<6)
+#define S3C2440_UFCON_TXTRIG48	  (3<<6)
+
 #define S3C2410_UFCON_RESETBOTH	  (3<<1)
+#define S3C2410_UFCON_RESETTX	  (1<<2)
+#define S3C2410_UFCON_RESETRX	  (1<<1)
 
-#define S3C2410_UFCON_DEFAULT	  (S3C2410_UFCON_FIFOMODE | S3C2410_UFCON_TXTRIG0 \
-				  | S3C2410_UFCON_RXTRIG8 )
+#define S3C2410_UFCON_DEFAULT	  (S3C2410_UFCON_FIFOMODE | \
+				   S3C2410_UFCON_TXTRIG0  | \
+				   S3C2410_UFCON_RXTRIG8 )
 
 #define S3C2410_UFSTAT_TXFULL	  (1<<9)
 #define S3C2410_UFSTAT_RXFULL	  (1<<8)
@@ -111,32 +133,36 @@
 
 #define S3C2410_UERSTAT_OVERRUN	  (1<<0)
 #define S3C2410_UERSTAT_FRAME	  (1<<2)
-#define S3C2410_UERSTAT_ANY	  (S3C2410_UERSTAT_OVERRUN | S3C2410_UERSTAT_FRAME)
+#define S3C2410_UERSTAT_BREAK	  (1<<3)
+#define S3C2410_UERSTAT_ANY	  (S3C2410_UERSTAT_OVERRUN | \
+				   S3C2410_UERSTAT_FRAME | \
+				   S3C2410_UERSTAT_BREAK)
 
-/* fifo size information */
+#define S3C2410_UMSTAT_CTS	  (1<<0)
+#define S3C2410_UMSTAT_DeltaCTS	  (1<<2)
 
 #ifndef __ASSEMBLY__
-static inline int S3C2410_UFCON_RXC(int fcon)
-{
-	if (fcon & S3C2410_UFSTAT_RXFULL)
-		return 16;
-
-	return ((fcon) & S3C2410_UFSTAT_RXMASK) >> S3C2410_UFSTAT_RXSHIFT;
-}
-
-static inline int S3C2410_UFCON_TXC(int fcon)
-{
-	if (fcon & S3C2410_UFSTAT_TXFULL)
-		return 16;
 
-	return ((fcon) & S3C2410_UFSTAT_TXMASK) >> S3C2410_UFSTAT_TXSHIFT;
-}
-#endif /* __ASSEMBLY__ */
+/* struct s3c24xx_uart_clksrc
+ *
+ * this structure defines a named clock source that can be used for the
+ * uart, so that the best clock can be selected for the requested baud
+ * rate.
+ *
+ * min_baud and max_baud define the range of baud-rates this clock is
+ * acceptable for, if they are both zero, it is assumed any baud rate that
+ * can be generated from this clock will be used.
+ *
+ * divisor gives the divisor from the clock to the one seen by the uart
+*/
 
-#define S3C2410_UMSTAT_CTS	  (1<<0)
-#define S3C2410_UMSTAT_DeltaCTS	  (1<<2)
+struct s3c24xx_uart_clksrc {
+	const char	*name;
+	unsigned int	 divisor;
+	unsigned int	 min_baud;
+	unsigned int	 max_baud;
+};
 
-#ifndef __ASSEMBLY__
 /* configuration structure for per-machine configurations for the
  * serial port
  *
@@ -148,15 +174,23 @@
 	unsigned char	   hwport;	 /* hardware port number */
 	unsigned char	   unused;
 	unsigned short	   flags;
-
-	unsigned long	  *clock;	 /* pointer to clock rate */
+	unsigned long	   uart_flags;	 /* default uart flags */
 
 	unsigned long	   ucon;	 /* value of ucon for port */
 	unsigned long	   ulcon;	 /* value of ulcon for port */
 	unsigned long	   ufcon;	 /* value of ufcon for port */
+
+	struct s3c24xx_uart_clksrc *clocks;
+	unsigned int		    clocks_size;
 };
 
-extern struct s3c2410_uartcfg *s3c2410_uartcfgs;
+/* s3c24xx_uart_devs
+ *
+ * this is exported from the core as we cannot use driver_register(),
+ * or platform_add_device() before the console_initcall()
+*/
+
+extern struct platform_device *s3c24xx_uart_devs[3];
 
 #endif /* __ASSEMBLY__ */
 
diff -Nur linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/s3c2410fb.h linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/s3c2410fb.h
--- linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/s3c2410fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/s3c2410fb.h	2004-11-09 21:18:22.000000000 +0100
@@ -0,0 +1,64 @@
+/* linux/include/asm/arch-s3c2410/s3c2410fb.h
+ *
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * Inspired by pxafb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ *  Changelog:
+ *	07-Sep-2004	RTP	Created file
+ *	03-Nov-2004	BJD	Updated and minor cleanups      
+*/
+
+#ifndef __ASM_ARM_S3C2410FB_H
+#define __ASM_ARM_S3C2410FB_H
+
+#include <asm/arch/regs-lcd.h>
+
+struct s3c2410fb_mach_info {
+	
+	/* Screen size */
+	int		width;
+	int		height;
+
+	/* Screen info */
+	int		xres;
+	int		yres;
+	int		bpp;
+	
+	/* lcd configuration registers */
+	unsigned long	lcdcon1;
+	unsigned long	lcdcon2;
+	unsigned long	lcdcon3;
+	unsigned long	lcdcon4;
+	unsigned long	lcdcon5;
+
+	/* GPIOs */
+	unsigned long	gpcup;
+	unsigned long	gpcup_mask;
+	unsigned long	gpccon;
+	unsigned long	gpccon_mask;
+	unsigned long	gpdup;
+	unsigned long	gpdup_mask;
+	unsigned long	gpdcon;
+	unsigned long	gpdcon_mask;
+	
+	/* lpc3600 control register */
+	unsigned long	lpcsel;
+
+	/* backlight info */
+	int		backlight_min;
+	int		backlight_max;
+	int		backlight_default;
+	
+	/* Utility fonctions */
+	void		(*backlight_power)(int);
+	void		(*lcd_power)(int);
+	void		(*set_brightness)(int);
+};
+
+#endif /* __ASM_ARM_S3C2410FB_H */
diff -Nur linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/uncompress.h linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/uncompress.h
--- linux-2.6.10-rc1-bk19/include/asm-arm/arch-s3c2410/uncompress.h	2004-11-09 20:22:17.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/include/asm-arm/arch-s3c2410/uncompress.h	2004-11-09 21:18:06.000000000 +0100
@@ -19,7 +19,9 @@
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
+#ifdef CONFIG_DEBUG_S3C2410_PORT
 #include <config/debug/s3c2410/port.h>
+#endif
 
 /* defines for UART registers */
 #include "asm/arch/regs-serial.h"
diff -Nur linux-2.6.10-rc1-bk19/include/linux/font.h linux-2.6.10-rc1-bk19-h1940/include/linux/font.h
--- linux-2.6.10-rc1-bk19/include/linux/font.h	2004-10-18 23:53:51.000000000 +0200
+++ linux-2.6.10-rc1-bk19-h1940/include/linux/font.h	2004-11-09 21:32:56.000000000 +0100
@@ -29,6 +29,8 @@
 #define SUN12x22_IDX	5
 #define ACORN8x8_IDX	6
 #define	MINI4x6_IDX	7
+#define	CLEAN4x6_IDX	8
+#define	CLEAN5x8_IDX	9
 
 extern struct font_desc	font_vga_8x8,
 				font_vga_8x16,
@@ -37,7 +39,9 @@
 				font_sun_8x16,
 				font_sun_12x22,
 				font_acorn_8x8,
-				font_mini_4x6;
+				font_mini_4x6,
+				font_clean_4x6,
+				font_clean_5x8;
 
 /* Find a font with a specific name */
 
diff -Nur linux-2.6.10-rc1-bk19/include/linux/serial_core.h linux-2.6.10-rc1-bk19-h1940/include/linux/serial_core.h
--- linux-2.6.10-rc1-bk19/include/linux/serial_core.h	2004-11-09 20:22:18.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/include/linux/serial_core.h	2004-11-09 21:33:00.000000000 +0100
@@ -94,6 +94,9 @@
 /*IBM icom*/
 #define PORT_ICOM      60
 
+/* Samsung S3C2440 SoC */
+#define PORT_S3C2440	60
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
diff -Nur linux-2.6.10-rc1-bk19/kernel/Makefile linux-2.6.10-rc1-bk19-h1940/kernel/Makefile
--- linux-2.6.10-rc1-bk19/kernel/Makefile	2004-11-09 20:22:18.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/kernel/Makefile	2004-11-09 21:18:14.000000000 +0100
@@ -7,7 +7,7 @@
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o wait.o kfifo.o sys_ni.o
+	    kthread.o wait.o kfifo.o sys_ni.o mhelper.o
 
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
diff -Nur linux-2.6.10-rc1-bk19/kernel/mhelper.c linux-2.6.10-rc1-bk19-h1940/kernel/mhelper.c
--- linux-2.6.10-rc1-bk19/kernel/mhelper.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/kernel/mhelper.c	2004-11-09 21:18:14.000000000 +0100
@@ -0,0 +1,83 @@
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/errno.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/uaccess.h>
+#include <asm/mach/map.h>
+
+#include "mhelper.h"
+
+
+	
+#define IODESC_ENT(x) { S3C2410_VA_##x, S3C2410_PA_##x, S3C2410_SZ_##x, MT_DEVICE }
+
+extern struct map_desc s3c2410_iodesc[];
+extern unsigned long s3c2410_iodesc_size;
+
+static inline unsigned long
+map_io_to_va(unsigned long addr)
+{
+	int index;
+
+	for (index=0; index<s3c2410_iodesc_size; index++) {
+		unsigned long phys = s3c2410_iodesc[index].physical;
+		unsigned long len = s3c2410_iodesc[index].length;
+
+		if ((addr >= phys) & (addr < phys+len))
+			break;
+	}
+	if (index < s3c2410_iodesc_size) {
+		unsigned long phys = s3c2410_iodesc[index].physical;
+		unsigned long virt = s3c2410_iodesc[index].virtual;
+		
+		return (addr - phys + virt);
+	}
+	return 0;
+}
+
+
+extern asmlinkage long
+sys_mhelper(uint32_t cmd, uint32_t addr, uint32_t value)
+{
+	unsigned long vaddr = 0;
+
+	if (!(vaddr = map_io_to_va(addr)))
+		return -ENXIO;
+
+        switch (cmd) {
+
+	case CMD_READ_B:
+		value = __raw_readb(vaddr);
+		printk("0x%08x: 0x%02x (%d)\n", addr, value, value);
+		break;
+	case CMD_READ_W:
+		value = __raw_readw(vaddr);
+		printk("0x%08x: 0x%04x (%d)\n", addr, value, value);
+		break;
+	case CMD_READ_L:
+		value = __raw_readl(vaddr);
+		printk("0x%08x: 0x%08x (%d)\n", addr, value, value);
+		break;
+		
+	case CMD_WRITE_B:
+		__raw_writeb(value, vaddr);
+		break;
+	case CMD_WRITE_W:
+		__raw_writew(value, vaddr);
+		break;
+	case CMD_WRITE_L:
+		__raw_writel(value, vaddr);
+		break;
+
+	default:
+		return -EINVAL;
+		break;
+	}
+	
+	return 0;
+}
+
diff -Nur linux-2.6.10-rc1-bk19/kernel/mhelper.h linux-2.6.10-rc1-bk19-h1940/kernel/mhelper.h
--- linux-2.6.10-rc1-bk19/kernel/mhelper.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/kernel/mhelper.h	2004-11-09 21:18:14.000000000 +0100
@@ -0,0 +1,22 @@
+
+#define CAT_READ	0x10
+#define CAT_WRITE	0x20
+
+#define CAT_BYTE	0x01
+#define CAT_WORD	0x02
+#define CAT_LONG	0x03
+
+
+enum {
+	CMD_VERSION = 0,
+
+	CMD_READ_B  = 0x11,
+	CMD_READ_W,
+	CMD_READ_L,
+
+	CMD_WRITE_B = 0x21,
+	CMD_WRITE_W,
+	CMD_WRITE_L,
+
+};
+
diff -Nur linux-2.6.10-rc1-bk19/Makefile linux-2.6.10-rc1-bk19-h1940/Makefile
--- linux-2.6.10-rc1-bk19/Makefile	2004-11-09 20:22:13.000000000 +0100
+++ linux-2.6.10-rc1-bk19-h1940/Makefile	2004-11-09 21:18:03.000000000 +0100
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 10
-EXTRAVERSION = -rc1-bk19
+EXTRAVERSION = -rc1-bk19-h1940
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
@@ -190,8 +190,8 @@
 # Default value for CROSS_COMPILE is not to prefix executables
 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
 
-ARCH		?= $(SUBARCH)
-CROSS_COMPILE	?=
+ARCH		?= arm
+CROSS_COMPILE	?= arm-linux-
 
 # Architecture as present in compile.h
 UTS_MACHINE := $(ARCH)
