diff -Naurp -X dontdiff linux-2.6.11-bk1/arch/arm/kernel/calls.S linux-2.6.11-bk1-h1940/arch/arm/kernel/calls.S
--- linux-2.6.11-bk1/arch/arm/kernel/calls.S	2005-03-06 12:23:11.000000000 +0100
+++ linux-2.6.11-bk1-h1940/arch/arm/kernel/calls.S	2005-03-26 23:18:21.000000000 +0100
@@ -236,7 +236,7 @@ __syscall_start:
 		.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 -Naurp -X dontdiff linux-2.6.11-bk1/arch/arm/mach-s3c2410/devs.c linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/devs.c
--- linux-2.6.11-bk1/arch/arm/mach-s3c2410/devs.c	2005-03-06 12:23:12.000000000 +0100
+++ linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/devs.c	2005-03-26 23:18:32.000000000 +0100
@@ -28,12 +28,15 @@
 #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 <asm/arch/s3c2410_udc.h>
+#include <asm/arch/s3c2410_ts.h>
+#include <asm/arch/s3c2410_bl.h>
 
 #include "devs.h"
 
@@ -73,6 +76,15 @@ EXPORT_SYMBOL(s3c_device_usb);
 
 /* 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,
@@ -95,6 +107,7 @@ struct platform_device s3c_device_lcd = 
 	.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
 	}
@@ -102,6 +115,24 @@ struct platform_device s3c_device_lcd = 
 
 EXPORT_SYMBOL(s3c_device_lcd);
 
+static struct s3c2410_bl_mach_info s3c2410bl_info;
+
+void __init set_s3c2410bl_info(struct s3c2410_bl_mach_info *hard_s3c2410bl_info)
+{
+	memcpy(&s3c2410bl_info,hard_s3c2410bl_info,sizeof(struct s3c2410_bl_mach_info));
+}
+EXPORT_SYMBOL(set_s3c2410bl_info);
+
+struct platform_device s3c_device_bl = {
+	.name		  = "s3c2410-bl",
+	.id		  = -1,
+	.dev              = {
+ 		.platform_data	= &s3c2410bl_info,
+	}
+};
+
+EXPORT_SYMBOL(s3c_device_bl);
+
 /* NAND Controller */
 
 static struct resource s3c_nand_resource[] = {
@@ -121,7 +152,33 @@ struct platform_device s3c_device_nand =
 
 EXPORT_SYMBOL(s3c_device_nand);
 
+/* Touchscreen */
+static struct s3c2410_ts_mach_info s3c2410ts_info;
+
+void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
+{
+	memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));
+}
+EXPORT_SYMBOL(set_s3c2410ts_info);
+
+struct platform_device s3c_device_ts = {
+	.name		  = "s3c2410-ts",
+	.id		  = -1,
+	.dev              = {
+ 		.platform_data	= &s3c2410ts_info,
+	}
+};
+EXPORT_SYMBOL(s3c_device_ts);
+
 /* USB Device (Gadget)*/
+static struct s3c2410_udc_mach_info s3c2410udc_info;
+
+void __init set_s3c2410udc_info(struct s3c2410_udc_mach_info *hard_s3c2410udc_info)
+{
+	memcpy(&s3c2410udc_info,hard_s3c2410udc_info,sizeof(struct s3c2410_udc_mach_info));
+}
+EXPORT_SYMBOL(set_s3c2410udc_info);
+
 
 static struct resource s3c_usbgadget_resource[] = {
 	[0] = {
@@ -142,6 +199,10 @@ struct platform_device s3c_device_usbgad
 	.id		  = -1,
 	.num_resources	  = ARRAY_SIZE(s3c_usbgadget_resource),
 	.resource	  = s3c_usbgadget_resource,
+	.dev		  = {
+		.platform_data  = &s3c2410udc_info,
+	}
+	
 };
 
 EXPORT_SYMBOL(s3c_device_usbgadget);
diff -Naurp -X dontdiff linux-2.6.11-bk1/arch/arm/mach-s3c2410/devs.h linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/devs.h
--- linux-2.6.11-bk1/arch/arm/mach-s3c2410/devs.h	2005-03-06 12:23:12.000000000 +0100
+++ linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/devs.h	2005-03-26 23:18:32.000000000 +0100
@@ -20,6 +20,7 @@ extern struct platform_device *s3c24xx_u
 
 extern struct platform_device s3c_device_usb;
 extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_bl;
 extern struct platform_device s3c_device_wdt;
 extern struct platform_device s3c_device_i2c;
 extern struct platform_device s3c_device_iis;
@@ -38,6 +39,7 @@ extern struct platform_device s3c_device
 extern struct platform_device s3c_device_timer3;
 
 extern struct platform_device s3c_device_usbgadget;
+extern struct platform_device s3c_device_ts;
 
 /* s3c2440 specific devices */
 
diff -Naurp -X dontdiff linux-2.6.11-bk1/arch/arm/mach-s3c2410/irq.c linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/irq.c
--- linux-2.6.11-bk1/arch/arm/mach-s3c2410/irq.c	2005-03-06 12:23:12.000000000 +0100
+++ linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/irq.c	2005-03-26 23:18:48.000000000 +0100
@@ -39,6 +39,9 @@
  *
  *   04-Nov-2004  Ben Dooks
  *		  Fix standard IRQ wake for EINT0..4 and RTC
+ *
+ *   22-Feb-2004  Ben Dooks
+ *		  Fixed edge-triggering on ADC IRQ
 */
 
 #include <linux/init.h>
@@ -426,6 +429,23 @@ s3c_irqsub_maskack(unsigned int irqno, u
 	}
 }
 
+static inline void
+s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+	__raw_writel(bit, S3C2410_SUBSRCPND);
+
+	/* only ack parent if we've got all the irqs (seems we must
+	 * ack, all and hope that the irq system retriggers ok when
+	 * the interrupt goes off again)
+	 */
+
+	if (1) {
+		__raw_writel(parentmask, S3C2410_SRCPND);
+		__raw_writel(parentmask, S3C2410_INTPND);
+	}
+}
 
 /* UART0 */
 
@@ -522,7 +542,7 @@ s3c_irq_adc_unmask(unsigned int irqno)
 static void
 s3c_irq_adc_ack(unsigned int irqno)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_ADCPARENT, 3 << 9);
+	s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
 }
 
 static struct irqchip s3c_irq_adc = {
diff -Naurp -X dontdiff linux-2.6.11-bk1/arch/arm/mach-s3c2410/mach-h1940.c linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/mach-h1940.c
--- linux-2.6.11-bk1/arch/arm/mach-s3c2410/mach-h1940.c	2005-03-02 08:38:17.000000000 +0100
+++ linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/mach-h1940.c	2005-03-26 23:18:39.000000000 +0100
@@ -31,6 +31,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>
@@ -44,6 +45,14 @@
 
 //#include <asm/debug-ll.h>
 #include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-timer.h>
+
+#include <asm/arch/s3c2410fb.h>
+#include <asm/arch/s3c2410_udc.h>
+#include <asm/arch/s3c2410_ts.h>
+#include <asm/arch/s3c2410_bl.h>
 
 #include <linux/serial_core.h>
 
@@ -86,14 +95,147 @@ static struct s3c2410_uartcfg h1940_uart
 };
 
 
+static void pullup(unsigned char cmd)
+{
+	printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
+	switch (cmd)
+	{
+		case S3C2410_UDC_P_ENABLE :
+			break;
+		case S3C2410_UDC_P_DISABLE :
+			break;
+		case S3C2410_UDC_P_RESET :
+			break;
+		default: break;
+	}
+}
+
+static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
+		.udc_command = pullup,
+};
+
+
+static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
+		.delay = 10000,
+		.presc = 49,
+		.oversampling_shift = 2,
+};
+
+/**
+ * Set lcd on or off
+ **/
+static void h1940_lcd_power(int on)
+{
+	s3c2410_gpio_setpin(S3C2410_GPC0, on);
+}
+ 
+ 
+static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
+	.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,
+
+	.lcd_power		= h1940_lcd_power,
+};
 
 
+
+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);
+}
+
+static void h1940_set_brightness(int tcmpb0)
+{
+	unsigned long tcfg0;
+	unsigned long tcfg1;
+	unsigned long tcon;
+
+	/* configure power on/off */
+	h1940_backlight_power(tcmpb0 ? 1 : 0);
+
+	
+	tcfg0=readl(S3C2410_TCFG0);
+	tcfg1=readl(S3C2410_TCFG1);
+	
+	tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
+	tcfg0 |= 0x18;
+
+	tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
+	tcfg1 |= S3C2410_TCFG1_MUX0_DIV2;
+
+	writel(tcfg0, S3C2410_TCFG0);
+	writel(tcfg1, S3C2410_TCFG1);
+	writel(0x31, S3C2410_TCNTB(0));
+
+	tcon = readl(S3C2410_TCON);
+	tcon &= ~0x0F;
+	tcon |= S3C2410_TCON_T0RELOAD;
+	tcon |= S3C2410_TCON_T0MANUALUPD;
+
+	writel(tcon, S3C2410_TCON);
+	writel(0x31, S3C2410_TCNTB(0));
+	writel(tcmpb0, S3C2410_TCMPB(0));
+
+	/* start the timer running */
+	tcon |= S3C2410_TCON_T0START;
+	tcon &= ~S3C2410_TCON_T0MANUALUPD;
+	writel(tcon, S3C2410_TCON);
+}
+
+static struct s3c2410_bl_mach_info h1940_blcfg __initdata = {
+	
+	.backlight_max          = 0x2c,
+	.backlight_default      = 0x16,
+	.backlight_power	= h1940_backlight_power,
+	.set_brightness		= h1940_set_brightness
+};
+
 static struct platform_device *h1940_devices[] __initdata = {
 	&s3c_device_usb,
 	&s3c_device_lcd,
+	&s3c_device_bl,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&s3c_device_sdi,
+	&s3c_device_usbgadget,
+	&s3c_device_ts,
 };
 
 static struct s3c24xx_board h1940_board __initdata = {
@@ -115,11 +257,22 @@ void __init h1940_init_irq(void)
 
 }
 
+void __init h1940_init(void)
+{
+	set_s3c2410ts_info(&h1940_ts_cfg);
+	set_s3c2410udc_info(&h1940_udc_cfg);
+	/* Set pad to usb device and usbsuspend to 'normal' */
+	__raw_writel(__raw_readl(S3C2410_MISCCR)&~0x3008,S3C2410_MISCCR);
+	set_s3c2410fb_info(&h1940_lcdcfg);
+	set_s3c2410bl_info(&h1940_blcfg);
+}
+		
 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		= &s3c24xx_timer,
 MACHINE_END
diff -Naurp -X dontdiff linux-2.6.11-bk1/arch/arm/mach-s3c2410/s3c2410.c linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/s3c2410.c
--- linux-2.6.11-bk1/arch/arm/mach-s3c2410/s3c2410.c	2005-03-06 12:23:12.000000000 +0100
+++ linux-2.6.11-bk1-h1940/arch/arm/mach-s3c2410/s3c2410.c	2005-03-26 23:18:21.000000000 +0100
@@ -45,8 +45,9 @@
 
 /* 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),
@@ -55,6 +56,8 @@ static struct map_desc s3c2410_iodesc[] 
 	IODESC_ENT(WATCHDOG)
 };
 
+unsigned long s3c2410_iodesc_size = ARRAY_SIZE(s3c2410_iodesc);
+
 static struct resource s3c_uart0_resource[] = {
 	[0] = {
 		.start = S3C2410_PA_UART0,
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/input/touchscreen/Kconfig linux-2.6.11-bk1-h1940/drivers/input/touchscreen/Kconfig
--- linux-2.6.11-bk1/drivers/input/touchscreen/Kconfig	2005-03-02 08:38:09.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/input/touchscreen/Kconfig	2005-03-26 23:18:24.000000000 +0100
@@ -22,6 +22,24 @@ config TOUCHSCREEN_BITSY
 	  To compile this driver as a module, choose M here: the
 	  module will be called h3600_ts_input.
 
+config TOUCHSCREEN_S3C2410
+	tristate "Samsung S3C2410 touchscreen input driver"
+	depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN
+	select SERIO
+	help
+	  Say Y here if you have the s3c2410 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called s3c2410_ts.
+
+config TOUCHSCREEN_S3C2410_DEBUG
+	boolean "Samsung S3C2410 touchscreen debug messages"
+	depends on TOUCHSCREEN_S3C2410
+	help
+	  Select this if you want debug messages
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	depends on INPUT && INPUT_TOUCHSCREEN
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/input/touchscreen/Makefile linux-2.6.11-bk1-h1940/drivers/input/touchscreen/Makefile
--- linux-2.6.11-bk1/drivers/input/touchscreen/Makefile	2005-03-02 08:38:25.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/input/touchscreen/Makefile	2005-03-26 23:18:24.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_S3C2410) += s3c2410_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)	+= gunze.o
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/input/touchscreen/s3c2410_ts.c linux-2.6.11-bk1-h1940/drivers/input/touchscreen/s3c2410_ts.c
--- linux-2.6.11-bk1/drivers/input/touchscreen/s3c2410_ts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/input/touchscreen/s3c2410_ts.c	2005-03-26 23:18:24.000000000 +0100
@@ -0,0 +1,346 @@
+/*
+ * 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
+ *
+ * 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
+ *	
+ * 2005-03-06: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - h1940_ -> s3c2410 (this driver is now also used on the n30
+ *        machines :P)
+ *      - Debug messages are now enabled with the config option
+ *        TOUCHSCREEN_S3C2410_DEBUG
+ *      - Changed the way the value are read
+ *      - Input subsystem should now work
+ *      - Use ioremap and readl/writel
+ *
+ * 2005-03-23: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - Make use of some undocumented features of the touchscreen 
+ *        controller
+ *
+ */
+
+#include <linux/config.h>
+#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/arch/regs-gpio.h>
+#include <asm/arch/s3c2410_ts.h>
+#include <asm/hardware/clock.h>
+
+/* For ts.dev.id.version */
+#define S3C2410TSVERSION	0x0101
+
+#define WAIT4INT(x)  (((x)<<8) | \
+		     S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
+		     S3C2410_ADCTSC_XY_PST(3))
+
+#define AUTOPST	     (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
+		     S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))
+
+#define DEBUG_LVL    KERN_DEBUG
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("s3c2410 touchscreen driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+
+static char *s3c2410ts_name = "s3c2410 TouchScreen";
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct s3c2410ts {
+	struct input_dev dev;
+	long xp;
+	long yp;
+	int count;
+	int shift;
+	char phys[32];
+};
+
+static struct s3c2410ts ts;
+static void __iomem *base_addr;
+
+static inline void s3c2410_ts_connect(void)
+{
+	s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
+}
+
+static void touch_timer_fire(unsigned long data)
+{
+  	unsigned long data0;
+  	unsigned long data1;
+	int updown;
+
+  	data0 = readl(base_addr+S3C2410_ADCDAT0);
+  	data1 = readl(base_addr+S3C2410_ADCDAT1);
+  
+ 	updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
+	
+ 	if (updown) {
+ 		if (ts.count != 0) {
+ 			ts.xp >>= ts.shift;
+ 			ts.yp >>= ts.shift;
+ 
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+ 			{
+ 				struct timeval tv;
+ 				do_gettimeofday(&tv);
+ 				printk(DEBUG_LVL "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts.xp, ts.yp);
+ 			}
+#endif
+			
+ 			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_report_abs(&ts.dev, ABS_PRESSURE, 1);
+ 			input_sync(&ts.dev);
+ 		}
+		
+ 		ts.xp = 0;
+ 		ts.yp = 0;
+ 		ts.count = 0;
+ 
+ 		writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
+ 		writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
+ 	} else {
+ 		ts.count = 0;
+		
+ 		input_report_key(&ts.dev, BTN_TOUCH, 0);
+ 		input_report_abs(&ts.dev, ABS_PRESSURE, 0);
+ 		input_sync(&ts.dev);
+		
+ 		writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
+ 	}
+}
+
+static struct timer_list touch_timer =
+		TIMER_INITIALIZER(touch_timer_fire, 0, 0);
+
+static irqreturn_t stylus_updown(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long data0;
+	unsigned long data1;
+	int updown;
+
+	data0 = readl(base_addr+S3C2410_ADCDAT0);
+	data1 = readl(base_addr+S3C2410_ADCDAT1);
+
+	updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
+
+	/* TODO we should never get an interrupt with updown set while
+	 * the timer is running, but maybe we ought to verify that the
+	 * timer isn't running anyways. */
+  
+	if (updown)
+		touch_timer_fire(0);
+
+	return IRQ_HANDLED;
+}
+
+
+static irqreturn_t stylus_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long data0;
+	unsigned long data1;
+	
+	data0 = readl(base_addr+S3C2410_ADCDAT0);
+	data1 = readl(base_addr+S3C2410_ADCDAT1);
+
+	ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
+	ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
+	ts.count++;
+
+        if (ts.count < (1<<ts.shift)) {
+		writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
+		writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
+	} else {
+		mod_timer(&touch_timer, jiffies+1);
+		writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct clk	*adc_clock;
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init s3c2410ts_probe(struct device *dev)
+{
+	struct s3c2410_ts_mach_info *info;
+	
+	info = ( struct s3c2410_ts_mach_info *)dev->platform_data;
+
+	if (!info)
+	{
+		printk(KERN_ERR "Hm... too bad : no platform data for ts\n");
+		return -EINVAL;
+	}
+	
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+	printk(DEBUG_LVL "Entering s3c2410ts_init\n");
+#endif
+
+	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);
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+	printk(DEBUG_LVL "got and enabled clock\n");
+#endif
+
+	base_addr=ioremap(S3C2410_PA_ADC,0x20);
+	if (base_addr == NULL) {
+		printk(KERN_ERR "Failed to remap register block\n");
+		return -ENOMEM;
+	}
+		
+
+	/* Configure GPIOs */
+	s3c2410_ts_connect();
+
+	if ((info->presc&0xff) > 0)
+		writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
+			     base_addr+S3C2410_ADCCON);
+	else
+		writel(0,base_addr+S3C2410_ADCCON);
+
+
+	/* Initialise registers */
+	if ((info->delay&0xffff) > 0)
+		writel(info->delay & 0xffff,  base_addr+S3C2410_ADCDLY);
+	
+	writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
+	
+	/* Initialise input stuff */
+	memset(&ts, 0, sizeof(struct s3c2410ts));
+	init_input_dev(&ts.dev);
+	ts.dev.evbit[0] = ts.dev.evbit[0] = BIT(EV_SYN) | 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);
+	input_set_abs_params(&ts.dev, ABS_PRESSURE, 0, 1, 0, 0);
+
+	sprintf(ts.phys, "ts0");
+
+	ts.dev.private = &ts;
+	ts.dev.name = s3c2410ts_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 = S3C2410TSVERSION;
+
+	ts.shift = info->oversampling_shift;
+
+	/* Get irqs */
+	if (request_irq(IRQ_ADC, stylus_action, SA_SAMPLE_RANDOM,
+		"s3c2410_action", &ts.dev)) {
+		printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");
+		iounmap(base_addr);
+		return -EIO;
+	}
+	if (request_irq(IRQ_TC, stylus_updown, SA_SAMPLE_RANDOM,
+			"s3c2410_action", &ts.dev)) {
+		printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");
+		iounmap(base_addr);
+		return -EIO;
+	}
+
+	printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);
+
+	/* All went ok, so register to the input system */
+	input_register_device(&ts.dev);
+	
+	return 0;
+}
+
+static int s3c2410ts_remove(struct device *dev)
+{
+	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);
+	iounmap(base_addr);
+
+	return 0;
+}
+
+static struct device_driver s3c2410ts_driver = {
+       .name           = "s3c2410-ts",
+       .bus            = &platform_bus_type,
+       .probe          = s3c2410ts_probe,
+       .remove         = s3c2410ts_remove,
+};
+
+
+int __init s3c2410ts_init(void)
+{
+	return driver_register(&s3c2410ts_driver);
+}
+
+void __exit s3c2410ts_exit(void)
+{
+	driver_unregister(&s3c2410ts_driver);
+}
+
+module_init(s3c2410ts_init);
+module_exit(s3c2410ts_exit);
+
+/*
+    Local variables:
+        compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.."
+        c-basic-offset: 8
+    End:
+*/
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/Kconfig linux-2.6.11-bk1-h1940/drivers/mmc/Kconfig
--- linux-2.6.11-bk1/drivers/mmc/Kconfig	2005-03-02 08:38:33.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/Kconfig	2005-03-26 23:18:39.000000000 +0100
@@ -60,4 +60,13 @@ config MMC_WBSD
 
 	  If unsure, say N.
 
+config MMC_S3C2410
+	tristate "Samsung S3C2410 Multimedia Card Interface support"
+	depends on ARCH_S3C2410 && MMC
+	help
+	  This selects the Samsung S3C2410 Multimedia Card Interface 
+	  support. 
+
+	  If unsure, say N.
+
 endmenu
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/Makefile linux-2.6.11-bk1-h1940/drivers/mmc/Makefile
--- linux-2.6.11-bk1/drivers/mmc/Makefile	2005-03-02 08:38:12.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/Makefile	2005-03-26 23:18:39.000000000 +0100
@@ -18,5 +18,6 @@ obj-$(CONFIG_MMC_BLOCK)		+= mmc_block.o
 obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
+obj-$(CONFIG_MMC_S3C2410)	+= s3c2410mci.o
 
 mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/mmc_block.c linux-2.6.11-bk1-h1940/drivers/mmc/mmc_block.c
--- linux-2.6.11-bk1/drivers/mmc/mmc_block.c	2005-03-02 08:38:34.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/mmc_block.c	2005-03-26 23:18:39.000000000 +0100
@@ -3,6 +3,9 @@
  *
  * Copyright 2002 Hewlett-Packard Company
  *
+ *  SD-Card support:
+ *    Copyright (C) 2004 Thomas Kleffel, All Rights Reserved
+ *
  * Use consistent with the GNU GPL is permitted,
  * provided that this copyright notice is
  * preserved in its entirety in all copies and derived works.
@@ -30,11 +33,13 @@
 #include <linux/devfs_fs_kernel.h>
 
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+#include "mmc.h"
 #include "mmc_queue.h"
 
 /*
@@ -165,11 +170,17 @@ static int mmc_blk_issue_rq(struct mmc_q
 {
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
+	struct mmc_host *host = md->queue.card->host;
 	int ret;
 
 	if (mmc_card_claim_host(card))
 		goto cmd_err;
 
+	if((card->sd) && (host->flags & MMC_HOST_WIDEMODE) && (card->bus_width != 4)) {
+		if(sd_set_bus_width(host, card->rca, 4)) goto cmd_err;
+		card->bus_width=4;
+	}
+
 	do {
 		struct mmc_blk_request brq;
 		struct mmc_command cmd;
@@ -180,6 +191,7 @@ static int mmc_blk_issue_rq(struct mmc_q
 
 		brq.cmd.arg = req->sector << 9;
 		brq.cmd.flags = MMC_RSP_R1;
+		brq.data.req = req;
 		brq.data.timeout_ns = card->csd.tacc_ns * 10;
 		brq.data.timeout_clks = card->csd.tacc_clks * 10;
 		brq.data.blksz_bits = md->block_bits;
@@ -188,6 +200,9 @@ static int mmc_blk_issue_rq(struct mmc_q
 		brq.stop.arg = 0;
 		brq.stop.flags = MMC_RSP_R1B;
 
+		if(card->bus_width==4)
+			brq.data.flags |= MMC_DATA_WIDE;
+
 		if (rq_data_dir(req) == READ) {
 			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
 			brq.data.flags |= MMC_DATA_READ;
@@ -252,7 +267,7 @@ static int mmc_blk_issue_rq(struct mmc_q
 			/*
 			 * The whole request completed successfully.
 			 */
-			add_disk_randomness(req->rq_disk);
+			//add_disk_randomness(req->rq_disk);
 			blkdev_dequeue_request(req);
 			end_that_request_last(req);
 		}
@@ -347,7 +362,7 @@ static struct mmc_blk_data *mmc_blk_allo
 		sprintf(md->disk->disk_name, "mmcblk%d", devidx);
 		sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
 
-		md->block_bits = card->csd.read_blkbits;
+		md->block_bits = card->csd.read_bl_len;
 
 		blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
 		set_capacity(md->disk, card->csd.capacity);
@@ -364,7 +379,7 @@ mmc_blk_set_blksize(struct mmc_blk_data 
 
 	mmc_card_claim_host(card);
 	cmd.opcode = MMC_SET_BLOCKLEN;
-	cmd.arg = 1 << card->csd.read_blkbits;
+	cmd.arg = 1 << card->csd.read_bl_len;
 	cmd.flags = MMC_RSP_R1;
 	err = mmc_wait_for_cmd(card->host, &cmd, 5);
 	mmc_card_release_host(card);
@@ -383,12 +398,12 @@ static int mmc_blk_probe(struct mmc_card
 	struct mmc_blk_data *md;
 	int err;
 
-	if (card->csd.cmdclass & ~0x1ff)
+	if (card->csd.ccc & ~0x1ff)
 		return -ENODEV;
 
-	if (card->csd.read_blkbits < 9) {
+	if (card->csd.read_bl_len < 9) {
 		printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
-			mmc_card_id(card), 1 << card->csd.read_blkbits);
+			mmc_card_id(card), 1 << card->csd.read_bl_len);
 		return -ENODEV;
 	}
 
@@ -402,7 +417,7 @@ static int mmc_blk_probe(struct mmc_card
 
 	printk(KERN_INFO "%s: %s %s %dKiB\n",
 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
-		(card->csd.capacity << card->csd.read_blkbits) / 1024);
+		(card->csd.capacity << card->csd.read_bl_len) / 1024);
 
 	mmc_set_drvdata(card, md);
 	add_disk(md->disk);
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/mmc.c linux-2.6.11-bk1-h1940/drivers/mmc/mmc.c
--- linux-2.6.11-bk1/drivers/mmc/mmc.c	2005-03-02 08:38:38.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/mmc.c	2005-03-26 23:18:39.000000000 +0100
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 2003-2004 Russell King, All Rights Reserved.
  *
+ *  SD-Card support:
+ *    Copyright (C) 2004 Thomas Kleffel, All Rights Reserved
+ *
  * 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.
@@ -172,6 +175,34 @@ int mmc_wait_for_cmd(struct mmc_host *ho
 
 EXPORT_SYMBOL(mmc_wait_for_cmd);
 
+static int mmc_send_app_cmd(struct mmc_host *host,  u16 rca)
+{
+	struct mmc_command cmd;
+
+	cmd.opcode = MMC_APP_CMD;
+	cmd.arg =((u32)rca)<<16;
+	cmd.flags = MMC_RSP_R1;
+
+	return mmc_wait_for_cmd(host, &cmd, 0);
+}
+
+int mmc_wait_for_acmd(struct mmc_host *host, u16 rca, struct mmc_command *cmd, int retries)
+{
+	int err;
+
+	do {
+		err = mmc_send_app_cmd(host, rca);
+		if(err != MMC_ERR_NONE) continue;
+
+		err = mmc_wait_for_cmd(host, cmd, 0);
+		if(err == MMC_ERR_NONE) break;
+
+	} while (retries--);
+
+	return err;
+}
+
+
 
 
 /**
@@ -274,6 +305,7 @@ static inline void mmc_delay(unsigned in
 	}
 }
 
+#if 0 /* UNUSED */
 /*
  * Mask off any voltages we don't support and select
  * the lowest voltage
@@ -298,6 +330,7 @@ static u32 mmc_select_voltage(struct mmc
 
 	return ocr;
 }
+#endif
 
 #define UNSTUFF_BITS(resp,start,size)					\
 	({								\
@@ -322,48 +355,65 @@ static void mmc_decode_cid(struct mmc_ca
 
 	memset(&card->cid, 0, sizeof(struct mmc_cid));
 
-	/*
-	 * The selection of the format here is guesswork based upon
-	 * information people have sent to date.
-	 */
-	switch (card->csd.mmca_vsn) {
-	case 0: /* MMC v1.? */
-	case 1: /* MMC v1.4 */
-		card->cid.manfid	= UNSTUFF_BITS(resp, 104, 24);
-		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
-		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
-		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
-		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
-		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
-		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
-		card->cid.prod_name[6]	= UNSTUFF_BITS(resp, 48, 8);
-		card->cid.hwrev		= UNSTUFF_BITS(resp, 44, 4);
-		card->cid.fwrev		= UNSTUFF_BITS(resp, 40, 4);
-		card->cid.serial	= UNSTUFF_BITS(resp, 16, 24);
-		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
-		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
-		break;
-
-	case 2: /* MMC v2.x ? */
-	case 3: /* MMC v3.x ? */
-		card->cid.manfid	= UNSTUFF_BITS(resp, 120, 8);
-		card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
-		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
-		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
-		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
-		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
-		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
-		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
-		card->cid.serial	= UNSTUFF_BITS(resp, 16, 32);
-		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
-		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
-		break;
-
-	default:
-		printk("%s: card has unknown MMCA version %d\n",
-			card->host->host_name, card->csd.mmca_vsn);
-		mmc_card_set_bad(card);
-		break;
+	if(card->sd) {
+		if(card->csd.csd_vers != SD_CSDV_1) {
+			DBG("%s: card has unknown SD-MMCA version %d\n", card->host->host_name, card->csd.spec_vers);
+			mmc_card_set_bad(card);
+		} else {
+			card->cid.manfid	= UNSTUFF_BITS(resp, 120,  8);
+			card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
+			card->cid.prod_name[0]	= UNSTUFF_BITS(resp,  96,  8);
+			card->cid.prod_name[1]	= UNSTUFF_BITS(resp,  88,  8);
+			card->cid.prod_name[2]	= UNSTUFF_BITS(resp,  80,  8);
+			card->cid.prod_name[3]	= UNSTUFF_BITS(resp,  72,  8);
+			card->cid.prod_name[4]	= UNSTUFF_BITS(resp,  64,  8);
+			card->cid.prod_name[5]  = 0;
+			card->cid.prod_name[6]  = 0;
+			card->cid.hwrev		= UNSTUFF_BITS(resp,  60,  4);
+			card->cid.fwrev		= UNSTUFF_BITS(resp,  56,  4);
+			card->cid.serial	= UNSTUFF_BITS(resp,  24, 32);
+			card->cid.month		= UNSTUFF_BITS(resp,  12,  4);
+			card->cid.year		= UNSTUFF_BITS(resp,   8,  4) + 2000;
+		}
+	} else {
+		switch (card->csd.csd_vers) {
+		case MMC_CSDV_1: /* MMC v1.? */
+		case MMC_CSDV_14: /* MMC v1.4 */
+			card->cid.manfid	= UNSTUFF_BITS(resp, 104, 24);
+			card->cid.prod_name[0]	= UNSTUFF_BITS(resp,  96,  8);
+			card->cid.prod_name[1]	= UNSTUFF_BITS(resp,  88,  8);
+			card->cid.prod_name[2]	= UNSTUFF_BITS(resp,  80,  8);
+			card->cid.prod_name[3]	= UNSTUFF_BITS(resp,  72,  8);
+			card->cid.prod_name[4]	= UNSTUFF_BITS(resp,  64,  8);
+			card->cid.prod_name[5]	= UNSTUFF_BITS(resp,  56,  8);
+			card->cid.prod_name[6]	= UNSTUFF_BITS(resp,  48,  8);
+			card->cid.hwrev		= UNSTUFF_BITS(resp,  44,  4);
+			card->cid.fwrev		= UNSTUFF_BITS(resp,  40,  4);
+			card->cid.serial	= UNSTUFF_BITS(resp,  16, 24);
+			card->cid.month		= UNSTUFF_BITS(resp,  12,  4);
+			card->cid.year		= UNSTUFF_BITS(resp,   8,  4) + 1997;
+			break;
+
+		case MMC_CSDV_2: /* MMC v2.x ? */
+		case MMC_CSDV_3: /* MMC v3.x ? */
+			card->cid.manfid	= UNSTUFF_BITS(resp, 120,  8);
+			card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
+			card->cid.prod_name[0]	= UNSTUFF_BITS(resp,  96,  8);
+			card->cid.prod_name[1]	= UNSTUFF_BITS(resp,  88,  8);
+			card->cid.prod_name[2]	= UNSTUFF_BITS(resp,  80,  8);
+			card->cid.prod_name[3]	= UNSTUFF_BITS(resp,  72,  8);
+			card->cid.prod_name[4]	= UNSTUFF_BITS(resp,  64,  8);
+			card->cid.prod_name[5]	= UNSTUFF_BITS(resp,  56,  8);
+			card->cid.serial	= UNSTUFF_BITS(resp,  16, 32);
+			card->cid.month		= UNSTUFF_BITS(resp,  12,  4);
+			card->cid.year		= UNSTUFF_BITS(resp,   8,  4) + 1997;
+			break;
+
+		default:
+			printk(KERN_WARNING "%s: card has unknown MMC-MMCA version %d\n", card->host->host_name, card->csd.spec_vers);
+			mmc_card_set_bad(card);
+			break;
+		}
 	}
 }
 
@@ -373,37 +423,95 @@ static void mmc_decode_cid(struct mmc_ca
 static void mmc_decode_csd(struct mmc_card *card)
 {
 	struct mmc_csd *csd = &card->csd;
-	unsigned int e, m, csd_struct;
+	unsigned int e, m;
 	u32 *resp = card->raw_csd;
 
-	/*
-	 * We only understand CSD structure v1.1 and v2.
-	 * v2 has extra information in bits 15, 11 and 10.
-	 */
-	csd_struct = UNSTUFF_BITS(resp, 126, 2);
-	if (csd_struct != 1 && csd_struct != 2) {
-		printk("%s: unrecognised CSD structure version %d\n",
-			card->host->host_name, csd_struct);
-		mmc_card_set_bad(card);
-		return;
-	}
-
-	csd->mmca_vsn	 = UNSTUFF_BITS(resp, 122, 4);
-	m = UNSTUFF_BITS(resp, 115, 4);
-	e = UNSTUFF_BITS(resp, 112, 3);
-	csd->tacc_ns	 = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
-	csd->tacc_clks	 = UNSTUFF_BITS(resp, 104, 8) * 100;
-
-	m = UNSTUFF_BITS(resp, 99, 4);
-	e = UNSTUFF_BITS(resp, 96, 3);
-	csd->max_dtr	  = tran_exp[e] * tran_mant[m];
-	csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12);
-
-	e = UNSTUFF_BITS(resp, 47, 3);
-	m = UNSTUFF_BITS(resp, 62, 12);
-	csd->capacity	  = (1 + m) << (e + 2);
+	if(card->sd) {
+		/*
+		* We only understand SD-CSD structure v1.0.
+		*/
+		csd->sd=1;
+		csd->csd_vers = UNSTUFF_BITS(resp, 126, 2);
+		if(csd->csd_vers != SD_CSDV_1) {
+			printk("%s: unrecognised SD-CSD structure version %d\n",
+				card->host->host_name, csd->csd_vers);
+			mmc_card_set_bad(card);
+			return;
+		}
+
+		csd->spec_vers 		= 0;
+		csd->taac		= UNSTUFF_BITS(resp, 112, 8);
+		csd->nsac		= UNSTUFF_BITS(resp, 104, 8);
+		csd->tran_speed		= UNSTUFF_BITS(resp,  96, 8);
+		csd->ccc		= UNSTUFF_BITS(resp,  84,12);
+		csd->read_bl_len	= UNSTUFF_BITS(resp,  80, 4);
+		csd->read_bl_partial	= UNSTUFF_BITS(resp,  79, 1);
+		csd->write_blk_misalign	= UNSTUFF_BITS(resp,  78, 1);
+		csd->read_blk_misalign	= UNSTUFF_BITS(resp,  77, 1);
+		csd->dsr_imp		= UNSTUFF_BITS(resp,  76, 1);
+		csd->c_size		= UNSTUFF_BITS(resp,  62,12);
+		csd->vdd_r_curr_min	= UNSTUFF_BITS(resp,  69, 3);
+		csd->vdd_r_curr_max	= UNSTUFF_BITS(resp,  56, 3);
+		csd->vdd_w_curr_min	= UNSTUFF_BITS(resp,  53, 3);
+		csd->vdd_w_curr_max	= UNSTUFF_BITS(resp,  50, 3);
+		csd->c_size_mult	= UNSTUFF_BITS(resp,  47, 3);
+		csd->erase.sd10.erase_blk_en	= UNSTUFF_BITS(resp,  46, 1);
+		csd->erase.sd10.erase_blk_size= UNSTUFF_BITS(resp,  39, 7);
+		csd->wp_grp_size	= UNSTUFF_BITS(resp,  32, 7);
+		csd->wp_grp_enable	= UNSTUFF_BITS(resp,  31, 1);
+		csd->r2w_factor		= UNSTUFF_BITS(resp,  26, 3);
+		csd->write_bl_len	= UNSTUFF_BITS(resp,  22, 4);
+		csd->write_bl_partial	= UNSTUFF_BITS(resp,  21, 1);
+		csd->file_format_grp	= UNSTUFF_BITS(resp,  15, 1);
+		csd->copy		= UNSTUFF_BITS(resp,  14, 1);
+		csd->perm_write_protect	= UNSTUFF_BITS(resp,  13, 1);
+		csd->tmp_write_protect	= UNSTUFF_BITS(resp,  12, 1);
+		csd->file_format	= UNSTUFF_BITS(resp,  10, 1);
+		csd->ecc		= UNSTUFF_BITS(resp,   1, 7);
+
+		m = UNSTUFF_BITS(resp, 115, 4);
+		e = UNSTUFF_BITS(resp, 112, 3);
+		csd->tacc_ns	 = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
+		csd->tacc_clks	 = UNSTUFF_BITS(resp, 104, 8) * 100;
+
+		m = UNSTUFF_BITS(resp, 99, 4);
+		e = UNSTUFF_BITS(resp, 96, 3);
+		csd->max_dtr	  = tran_exp[e] * tran_mant[m];
+
+		e = UNSTUFF_BITS(resp, 47, 3);
+		m = UNSTUFF_BITS(resp, 62, 12);
+		csd->capacity	  = (1 + m) << (e + 2);
+	} else {
+		/*
+		* We only understand MMC-CSD structure v1.1 and v2.
+		* v2 has extra information in bits 15, 11 and 10.
+		*/
+		csd->sd=0;
+		csd->csd_vers = UNSTUFF_BITS(resp, 126, 2);
+		if (csd->csd_vers != MMC_CSDV_14 && csd->csd_vers != MMC_CSDV_2) {
+			printk("%s: unrecognised MMC-CSD structure version %d\n",
+				card->host->host_name, csd->csd_vers);
+			mmc_card_set_bad(card);
+			return;
+		}
 
-	csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+		csd->spec_vers	 = UNSTUFF_BITS(resp, 122, 4);
+		m = UNSTUFF_BITS(resp, 115, 4);
+		e = UNSTUFF_BITS(resp, 112, 3);
+		csd->tacc_ns	 = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
+		csd->tacc_clks	 = UNSTUFF_BITS(resp, 104, 8) * 100;
+
+		m = UNSTUFF_BITS(resp, 99, 4);
+		e = UNSTUFF_BITS(resp, 96, 3);
+		csd->max_dtr	  = tran_exp[e] * tran_mant[m];
+		csd->ccc	  = UNSTUFF_BITS(resp, 84, 12);
+
+		e = UNSTUFF_BITS(resp, 47, 3);
+		m = UNSTUFF_BITS(resp, 62, 12);
+		csd->capacity	  = (1 + m) << (e + 2);
+
+		csd->read_bl_len = UNSTUFF_BITS(resp, 80, 4);
+	}
 }
 
 /*
@@ -424,7 +532,7 @@ static struct mmc_card *mmc_find_card(st
  * Allocate a new MMC card, and assign a unique RCA.
  */
 static struct mmc_card *
-mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca)
+mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, u8 sd, unsigned int *frca)
 {
 	struct mmc_card *card, *c;
 	unsigned int rca = *frca;
@@ -435,6 +543,7 @@ mmc_alloc_card(struct mmc_host *host, u3
 
 	mmc_init_card(card, host);
 	memcpy(card->raw_cid, raw_cid, sizeof(card->raw_cid));
+	card->sd = sd;
 
  again:
 	list_for_each_entry(c, &host->cards, node)
@@ -456,6 +565,7 @@ mmc_alloc_card(struct mmc_host *host, u3
 static void mmc_idle_cards(struct mmc_host *host)
 {
 	struct mmc_command cmd;
+	struct mmc_card *card;
 
 	cmd.opcode = MMC_GO_IDLE_STATE;
 	cmd.arg = 0;
@@ -463,9 +573,83 @@ static void mmc_idle_cards(struct mmc_ho
 
 	mmc_wait_for_cmd(host, &cmd, 0);
 
-	mmc_delay(1);
+	//MMC_GO_IDLE_STATE resets all cards to bus width 1
+	list_for_each_entry(card, &host->cards, node) {
+		card->bus_width=1;
+	}
+
+
+	mmc_delay(100);
 }
 
+int sd_set_bus_width(struct mmc_host *host, u16 rca, u32 bus_width)
+{
+	struct mmc_command cmd;
+	int err;
+
+	cmd.opcode = MMC_ACMD_SD_SET_BUS_WIDTH;
+	cmd.flags  = MMC_RSP_R1;
+
+	switch(bus_width) {
+		case 1:	 cmd.arg = 00; break;
+		case 4:	 cmd.arg = 10; break;
+		default: return -EINVAL;
+	}
+
+	err = mmc_wait_for_acmd(host, rca, &cmd, 3);
+
+	if(err == MMC_ERR_TIMEOUT) {
+		printk(KERN_ERR "MMC: sd_set_bus_width timed out.\n");
+	} else if(err == MMC_ERR_BADCRC) {
+		printk(KERN_ERR "MMC: sd_set_bus_width yielded crc error.\n");
+	} else {
+		DBG("MMC: sd_app_op_cond done.\n");
+	}
+
+	return err;
+}
+
+EXPORT_SYMBOL(sd_set_bus_width);
+
+static int sd_app_op_cond(struct mmc_host *host, u16 rca, u32 parameter, u32 *response)
+{
+	struct mmc_command cmd;
+	int err;
+	int retries = 10;
+
+	cmd.opcode = MMC_ACMD_SD_APP_OP_COND;
+	cmd.arg = parameter;
+	cmd.flags = MMC_RSP_SHORT;
+
+	DBG("MMC: sd_app_op_cond to %08x\n",parameter);
+
+	while(retries--) {
+		err = mmc_wait_for_acmd(host, 0, &cmd, 0);
+		if(0 == (cmd.resp[0] & MMC_CARD_BUSY)) {
+			err=MMC_ERR_BUSY;
+			printk(KERN_ERR "MMC: sd_app_op_cond: at least one card is busy - trying again.\n");
+			mmc_delay(10);
+			continue;
+		}
+
+		if(err == MMC_ERR_NONE) {
+			if(response)*response = cmd.resp[0];
+			break;
+		}
+	}
+
+	if(err == MMC_ERR_TIMEOUT) {
+		printk(KERN_WARNING "MMC: sd_app_op_cond timed out. Probably no SD-Card here.\n");
+	} else if(err == MMC_ERR_BUSY) {
+		printk(KERN_ERR "MMC: sd_app_op_cond locked busy. Probably have broken SD-Card.\n");
+	} else {
+		DBG("MMC: sd_app_op_cond done. Results are: 0x%08x.\n",cmd.resp[0]);
+	}
+
+	return err;
+}
+
+
 /*
  * Apply power to the MMC stack.
  */
@@ -532,7 +716,7 @@ static int mmc_send_op_cond(struct mmc_h
  * Create a mmc_card entry for each discovered card, assigning
  * it an RCA, and save the raw CID for decoding later.
  */
-static void mmc_discover_cards(struct mmc_host *host)
+static void mmc_discover_cards(struct mmc_host *host, u8 sd)
 {
 	struct mmc_card *card;
 	unsigned int first_rca = 1, err;
@@ -542,7 +726,7 @@ static void mmc_discover_cards(struct mm
 
 		cmd.opcode = MMC_ALL_SEND_CID;
 		cmd.arg = 0;
-		cmd.flags = MMC_RSP_R2;
+		cmd.flags = MMC_RSP_LONG; //HACK! CRC currently not implemented
 
 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
 		if (err == MMC_ERR_TIMEOUT) {
@@ -550,14 +734,13 @@ static void mmc_discover_cards(struct mm
 			break;
 		}
 		if (err != MMC_ERR_NONE) {
-			printk(KERN_ERR "%s: error requesting CID: %d\n",
-				host->host_name, err);
+			printk(KERN_ERR "%s: error requesting CID: %d\n", host->host_name, err);
 			break;
 		}
 
 		card = mmc_find_card(host, cmd.resp);
 		if (!card) {
-			card = mmc_alloc_card(host, cmd.resp, &first_rca);
+			card = mmc_alloc_card(host, cmd.resp, sd, &first_rca);
 			if (IS_ERR(card)) {
 				err = PTR_ERR(card);
 				break;
@@ -574,6 +757,9 @@ static void mmc_discover_cards(struct mm
 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
 		if (err != MMC_ERR_NONE)
 			mmc_card_set_dead(card);
+
+		//SD-Cards choose their adresses themselfes (yuck!)
+		if(card->sd) card->rca = (cmd.resp[0] >> 16);
 	}
 }
 
@@ -590,7 +776,7 @@ static void mmc_read_csds(struct mmc_hos
 
 		cmd.opcode = MMC_SEND_CSD;
 		cmd.arg = card->rca << 16;
-		cmd.flags = MMC_RSP_R2;
+		cmd.flags = MMC_RSP_LONG; 	//HACK: No CRC check as s3c-Core is broken
 
 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
 		if (err != MMC_ERR_NONE) {
@@ -651,63 +837,22 @@ static void mmc_check_cards(struct mmc_h
 	}
 }
 
+
 static void mmc_setup(struct mmc_host *host)
 {
-	if (host->ios.power_mode != MMC_POWER_ON) {
-		int err;
-		u32 ocr;
-
-		mmc_power_up(host);
-		mmc_idle_cards(host);
-
-		err = mmc_send_op_cond(host, 0, &ocr);
-		if (err != MMC_ERR_NONE)
-			return;
-
-		host->ocr = mmc_select_voltage(host, ocr);
-
-		/*
-		 * Since we're changing the OCR value, we seem to
-		 * need to tell some cards to go back to the idle
-		 * state.  We wait 1ms to give cards time to
-		 * respond.
-		 */
-		if (host->ocr)
-			mmc_idle_cards(host);
-	} else {
-		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-		host->ios.clock = host->f_min;
-		host->ops->set_ios(host, &host->ios);
-
-		/*
-		 * We should remember the OCR mask from the existing
-		 * cards, and detect the new cards OCR mask, combine
-		 * the two and re-select the VDD.  However, if we do
-		 * change VDD, we should do an idle, and then do a
-		 * full re-initialisation.  We would need to notify
-		 * drivers so that they can re-setup the cards as
-		 * well, while keeping their queues at bay.
-		 *
-		 * For the moment, we take the easy way out - if the
-		 * new cards don't like our currently selected VDD,
-		 * they drop off the bus.
-		 */
-	}
-
-	if (host->ocr == 0)
-		return;
-
-	/*
-	 * Send the selected OCR multiple times... until the cards
-	 * all get the idea that they should be ready for CMD2.
-	 * (My SanDisk card seems to need this.)
-	 */
-	mmc_send_op_cond(host, host->ocr, NULL);
+	mmc_power_up(host);
+	mmc_idle_cards(host);
 
-	mmc_discover_cards(host);
+	// Wake and discover SD-Cards
+	sd_app_op_cond(host, 0, host->ocr_avail, NULL);
+	mmc_discover_cards(host, 1);
+
+	// Wake and discover MMC-Cards
+	mmc_send_op_cond(host, host->ocr_avail, NULL);
+	mmc_discover_cards(host, 0);
 
 	/*
-	 * Ok, now switch to push-pull mode.
+	 * switch to push-pull mode.
 	 */
 	host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
 	host->ops->set_ios(host, &host->ios);
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/mmc.h linux-2.6.11-bk1-h1940/drivers/mmc/mmc.h
--- linux-2.6.11-bk1/drivers/mmc/mmc.h	2005-03-02 08:37:50.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/mmc.h	2005-03-26 23:18:39.000000000 +0100
@@ -13,4 +13,5 @@
 void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
 int mmc_register_card(struct mmc_card *card);
 void mmc_remove_card(struct mmc_card *card);
+int sd_set_bus_width(struct mmc_host *host, u16 rca, u32 bus_width);
 #endif
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/mmc_sysfs.c linux-2.6.11-bk1-h1940/drivers/mmc/mmc_sysfs.c
--- linux-2.6.11-bk1/drivers/mmc/mmc_sysfs.c	2005-03-06 12:23:13.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/mmc_sysfs.c	2005-03-26 23:18:39.000000000 +0100
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 2003 Russell King, All Rights Reserved.
  *
+ *  SD-Card support:
+ *    Copyright (C) 2004 Thomas Kleffel, All Rights Reserved
+ *
  * 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.
@@ -39,10 +42,13 @@ MMC_ATTR(manfid, "0x%06x\n", card->cid.m
 MMC_ATTR(name, "%s\n", card->cid.prod_name);
 MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid);
 MMC_ATTR(serial, "0x%08x\n", card->cid.serial);
+MMC_ATTR(bus_width, "%u\n", card->bus_width);
+MMC_ATTR(type, "%s\n", (card->sd?"SD":"MMC"));
 
 #define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
 
 static struct device_attribute mmc_dev_attrs[] = {
+	MMC_ATTR_RO(bus_width),
 	MMC_ATTR_RO(cid),
 	MMC_ATTR_RO(csd),
 	MMC_ATTR_RO(date),
@@ -52,6 +58,7 @@ static struct device_attribute mmc_dev_a
 	MMC_ATTR_RO(name),
 	MMC_ATTR_RO(oemid),
 	MMC_ATTR_RO(serial),
+	MMC_ATTR_RO(type),
 	__ATTR_NULL
 };
 
@@ -97,7 +104,7 @@ mmc_bus_hotplug(struct device *dev, char
 	})
 
 	for (i = 0; i < 12; i++)
-		ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';
+		ccc[i] = card->csd.ccc & (1 << i) ? '1' : '0';
 	ccc[12] = '\0';
 
 	i = 0;
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/s3c2410mci.c linux-2.6.11-bk1-h1940/drivers/mmc/s3c2410mci.c
--- linux-2.6.11-bk1/drivers/mmc/s3c2410mci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/s3c2410mci.c	2005-03-26 23:18:39.000000000 +0100
@@ -0,0 +1,760 @@
+/*
+ *  linux/drivers/mmc/s3c2410mci.h - Samsung S3C2410 SDI Interface driver
+ *
+ *  Copyright (C) 2004 Thomas Kleffel, All Rights Reserved.
+ *
+ * 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.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/protocol.h>
+
+#include <asm/dma.h>
+#include <asm/dma-mapping.h>
+#include <asm/arch/dma.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware/amba.h>
+#include <asm/hardware/clock.h>
+#include <asm/mach/mmc.h>
+
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-gpio.h>
+
+//#define S3C2410SDI_DMA_BACKBUF
+
+#ifdef CONFIG_MMC_DEBUG
+#define DBG(x...)       printk(KERN_DEBUG x)
+#else
+#define DBG(x...)       do { } while (0)
+#endif
+
+#include "s3c2410mci.h"
+
+#define DRIVER_NAME "mmci-s3c2410"
+#define PFX DRIVER_NAME ": "
+
+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
+
+// #define KERN_DEBUG KERN_INFO
+
+typedef enum {
+	DMAP_READ,
+	DMAP_WRITE,
+} eDMAPurpose_t;
+
+static struct s3c2410_dma_client s3c2410sdi_dma_client = {
+	.name		= "s3c2410-sdi",
+};
+
+
+
+/*
+ * ISR for SDI Interface IRQ
+ * Communication between driver and ISR works as follows:
+ *   host->mrq 			points to current request
+ *   host->complete_what	tells the ISR when the request is considered done
+ *     COMPLETION_CMDSENT	  when the command was sent
+ *     COMPLETION_RSPFIN          when a response was received
+ *     COMPLETION_XFERFINISH	  when the data transfer is finished
+ *     COMPLETION_XFERFINISH_RSPFIN both of the above.
+ *   host->complete_request	is the completion-object the driver waits for
+ *
+ * 1) Driver sets up host->mrq and host->complete_what
+ * 2) Driver prepares the transfer
+ * 3) Driver enables interrupts
+ * 4) Driver starts transfer
+ * 5) Driver waits for host->complete_rquest
+ * 6) ISR checks for request status (errors and success)
+ * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error
+ * 7) ISR completes host->complete_request
+ * 8) ISR disables interrupts
+ * 9) Driver wakes up and takes care of the request
+*/
+
+static irqreturn_t s3c2410sdi_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct s3c2410sdi_host *host;
+	u32 sdi_csta, sdi_dsta, sdi_dcnt;
+	u32 sdi_cclear, sdi_dclear;
+	unsigned long iflags;
+
+	host = (struct s3c2410sdi_host *)dev_id;
+
+	//Check for things not supposed to happen
+	if(!host) return IRQ_HANDLED;
+	
+	sdi_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	sdi_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	sdi_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+	
+	DBG(PFX "IRQ csta=0x%08x dsta=0x%08x dcnt:0x%08x\n", sdi_csta, sdi_dsta, sdi_dcnt);
+		
+	spin_lock_irqsave( &host->complete_lock, iflags);
+	
+	if( host->complete_what==COMPLETION_NONE ) {
+		goto clear_imask;
+	}
+	
+	if(!host->mrq) { 
+		goto clear_imask;
+	}
+
+	
+	sdi_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	sdi_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	sdi_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+	sdi_cclear	= 0;
+	sdi_dclear	= 0;
+	
+	
+	if(sdi_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
+		host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+		goto transfer_closed;
+	}
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_CMDSENT) {
+		if(host->complete_what == COMPLETION_CMDSENT) {
+			host->mrq->cmd->error = MMC_ERR_NONE;
+			goto transfer_closed;
+		}
+
+		sdi_cclear |= S3C2410_SDICMDSTAT_CMDSENT;
+	}
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
+		if(host->mrq->cmd->flags & MMC_RSP_CRC) {
+			host->mrq->cmd->error = MMC_ERR_BADCRC;
+			goto transfer_closed;
+		}
+
+		sdi_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;
+	}
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_RSPFIN) {
+		if(host->complete_what == COMPLETION_RSPFIN) {
+			host->mrq->cmd->error = MMC_ERR_NONE;
+			goto transfer_closed;
+		}
+
+		if(host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+			host->mrq->cmd->error = MMC_ERR_NONE;
+			host->complete_what = COMPLETION_XFERFINISH;
+		}
+
+		sdi_cclear |= S3C2410_SDICMDSTAT_RSPFIN;
+	}
+
+	if(sdi_dsta & S3C2410_SDIDSTA_FIFOFAIL) {
+		host->mrq->cmd->error = MMC_ERR_NONE;
+		host->mrq->data->error = MMC_ERR_FIFO;
+		goto transfer_closed;
+	}
+
+	if(sdi_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
+		host->mrq->cmd->error = MMC_ERR_NONE;
+		host->mrq->data->error = MMC_ERR_BADCRC;
+		goto transfer_closed;
+	}
+
+	if(sdi_dsta & S3C2410_SDIDSTA_CRCFAIL) {
+		host->mrq->cmd->error = MMC_ERR_NONE;
+		host->mrq->data->error = MMC_ERR_BADCRC;
+		goto transfer_closed;
+	}
+
+	if(sdi_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
+		host->mrq->cmd->error = MMC_ERR_NONE;
+		host->mrq->data->error = MMC_ERR_TIMEOUT;
+		goto transfer_closed;
+	}
+
+	if(sdi_dsta & S3C2410_SDIDSTA_XFERFINISH) {
+		if(host->complete_what == COMPLETION_XFERFINISH) {
+			host->mrq->cmd->error = MMC_ERR_NONE;
+			host->mrq->data->error = MMC_ERR_NONE;
+			goto transfer_closed;
+		}
+
+		if(host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+			host->mrq->data->error = MMC_ERR_NONE;
+			host->complete_what = COMPLETION_RSPFIN;
+		}
+
+		sdi_dclear |= S3C2410_SDIDSTA_XFERFINISH;
+	}
+
+	writel(sdi_cclear, host->base + S3C2410_SDICMDSTAT);
+	writel(sdi_dclear, host->base + S3C2410_SDIDSTA);
+
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	DBG(PFX "IRQ still waiting.\n");
+	return IRQ_HANDLED;
+
+
+transfer_closed:
+	host->complete_what = COMPLETION_NONE;
+	complete(&host->complete_request);
+	writel(0, host->base + S3C2410_SDIIMSK);
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	DBG(PFX "IRQ transfer closed.\n");
+	return IRQ_HANDLED;
+	
+clear_imask:
+	writel(0, host->base + S3C2410_SDIIMSK);
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	DBG(PFX "IRQ clear imask.\n");
+	return IRQ_HANDLED;
+
+}
+
+
+/*
+ * ISR for the CardDetect Pin
+*/
+
+static irqreturn_t s3c2410sdi_irq_cd(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct s3c2410sdi_host *host = (struct s3c2410sdi_host *)dev_id;
+	mmc_detect_change(host->mmc);
+
+	return IRQ_HANDLED;
+}
+
+
+
+void s3c2410sdi_dma_done_callback(s3c2410_dma_chan_t *dma_ch, void *buf_id,
+	int size, s3c2410_dma_buffresult_t result)
+{	unsigned long iflags;
+	u32 sdi_csta, sdi_dsta,sdi_dcnt;
+	struct s3c2410sdi_host *host = (struct s3c2410sdi_host *)buf_id;
+	
+	sdi_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	sdi_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	sdi_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+	
+	DBG(PFX "DMAD csta=0x%08x dsta=0x%08x dcnt:0x%08x result:0x%08x\n", sdi_csta, sdi_dsta, sdi_dcnt, result);
+	
+	spin_lock_irqsave( &host->complete_lock, iflags);
+	
+	if(!host->mrq) goto out;
+	if(!host->mrq->data) goto out;
+	
+	
+	sdi_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	sdi_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	sdi_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+		
+	if( result!=S3C2410_RES_OK ) {
+		goto fail_request;
+	}
+	
+	
+	if(host->mrq->data->flags & MMC_DATA_READ) {
+		if( sdi_dcnt>0 ) {
+			goto fail_request;
+		}
+	}
+	
+out:	
+	complete(&host->complete_dma);
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	return;
+
+
+fail_request:
+	host->mrq->data->error = MMC_ERR_DMA;
+	host->complete_what = COMPLETION_NONE;
+	complete(&host->complete_dma);
+	complete(&host->complete_request);
+	writel(0, host->base + S3C2410_SDIIMSK);
+	goto out;
+
+}
+
+
+void s3c2410sdi_dma_setup(struct s3c2410sdi_host *host, eDMAPurpose_t purpose) {
+	s3c2410_dmasrc_t source;
+
+	switch(purpose) {
+		default:
+		case DMAP_READ:
+			source  = S3C2410_DMASRC_HW;
+			break;
+
+		case DMAP_WRITE:
+			source  = S3C2410_DMASRC_MEM;
+			break;
+	}
+
+	s3c2410_dma_devconfig(host->dma, source, 3, host->mem->start + S3C2410_SDIDATA);
+	s3c2410_dma_config(host->dma, 4, (1<<23) | (2<<24));
+	s3c2410_dma_set_buffdone_fn(host->dma, s3c2410sdi_dma_done_callback);
+	s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
+}
+
+static void s3c2410sdi_request(struct mmc_host *mmc, struct mmc_request *mrq) {
+ 	struct s3c2410sdi_host *host = mmc_priv(mmc);
+	u32 sdi_carg, sdi_ccon, sdi_timer;
+	u32 sdi_bsize, sdi_dcon, sdi_imsk;
+
+	DBG(KERN_DEBUG PFX "request: [CMD] opcode:0x%02x arg:0x%08x flags:%x retries:%u\n",
+		mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags, mrq->cmd->retries);
+
+
+	sdi_ccon = mrq->cmd->opcode & S3C2410_SDICMDCON_INDEX;
+	sdi_ccon|= S3C2410_SDICMDCON_SENDERHOST;
+	sdi_ccon|= S3C2410_SDICMDCON_CMDSTART;
+
+	sdi_carg = mrq->cmd->arg;
+
+	//FIXME: Timer value ?!
+	sdi_timer= 0xF000;
+
+	sdi_bsize= 0;
+	sdi_dcon = 0;
+	sdi_imsk = 0;
+
+	//enable interrupts for transmission errors
+	sdi_imsk |= S3C2410_SDIIMSK_RESPONSEND;
+	sdi_imsk |= S3C2410_SDIIMSK_CRCSTATUS;
+
+
+	host->complete_what = COMPLETION_CMDSENT;
+
+	if (mrq->cmd->flags & MMC_RSP_MASK) {
+		host->complete_what = COMPLETION_RSPFIN;
+
+		sdi_ccon |= S3C2410_SDICMDCON_WAITRSP;
+		sdi_imsk |= S3C2410_SDIIMSK_CMDTIMEOUT;
+
+	} else {
+		//We need the CMDSENT-Interrupt only if we want are not waiting
+		//for a response
+		sdi_imsk |= S3C2410_SDIIMSK_CMDSENT;
+	}
+
+	if(mrq->cmd->flags & MMC_RSP_LONG) {
+		sdi_ccon|= S3C2410_SDICMDCON_LONGRSP;
+	}
+
+	if(mrq->cmd->flags & MMC_RSP_CRC) {
+		sdi_imsk |= S3C2410_SDIIMSK_RESPONSECRC;
+	}
+
+
+	if (mrq->data) {
+		host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
+
+
+
+		sdi_bsize = (1 << mrq->data->blksz_bits);
+
+		sdi_dcon  = (mrq->data->blocks & S3C2410_SDIDCON_BLKNUM_MASK);
+		sdi_dcon |= S3C2410_SDIDCON_DMAEN;
+
+		sdi_imsk |= S3C2410_SDIIMSK_FIFOFAIL;
+		sdi_imsk |= S3C2410_SDIIMSK_DATACRC;
+		sdi_imsk |= S3C2410_SDIIMSK_DATATIMEOUT;
+		sdi_imsk |= S3C2410_SDIIMSK_DATAFINISH;
+		sdi_imsk |= 0xFFFFFFE0;
+
+		DBG(PFX "request: [DAT] bsize:%u blocks:%u bytes:%u\n",
+			sdi_bsize, mrq->data->blocks, mrq->data->blocks * sdi_bsize);
+
+		if(mrq->data->flags & MMC_DATA_WIDE) {
+			sdi_dcon |= S3C2410_SDIDCON_WIDEBUS;
+		}
+
+		if(!(mrq->data->flags & MMC_DATA_STREAM)) {
+			sdi_dcon |= S3C2410_SDIDCON_BLOCKMODE;
+		}
+
+		if(mrq->data->flags & MMC_DATA_WRITE) {
+			sdi_dcon |= S3C2410_SDIDCON_TXAFTERRESP;
+			sdi_dcon |= S3C2410_SDIDCON_XFER_TXSTART;
+			s3c2410sdi_dma_setup(host, DMAP_WRITE);
+#ifdef S3C2410SDI_DMA_BACKBUF			
+			memcpy(host->dmabuf_log, mrq->data->req->buffer, mrq->data->blocks * sdi_bsize);
+#endif
+		}
+
+		if(mrq->data->flags & MMC_DATA_READ) {
+			sdi_dcon |= S3C2410_SDIDCON_RXAFTERCMD;
+			sdi_dcon |= S3C2410_SDIDCON_XFER_RXSTART;
+			s3c2410sdi_dma_setup(host, DMAP_READ);
+		}
+		
+		
+
+		//start DMA
+#ifdef S3C2410SDI_DMA_BACKBUF
+		s3c2410_dma_enqueue(host->dma, (void *) host,
+			host->dmabuf_phys,
+			(mrq->data->blocks << mrq->data->blksz_bits) );
+#else
+		s3c2410_dma_enqueue(host->dma, (void *) host,
+			virt_to_phys(mrq->data->req->buffer),
+			(mrq->data->blocks << mrq->data->blksz_bits) );
+#endif
+	}
+
+	host->mrq = mrq;
+
+	init_completion(&host->complete_request);
+	init_completion(&host->complete_dma);
+
+	//Clear command and data status registers
+	writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);
+	writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);
+
+	// Setup SDI controller
+	writel(sdi_bsize,host->base + S3C2410_SDIBSIZE);
+	writel(sdi_timer,host->base + S3C2410_SDITIMER);
+	writel(sdi_imsk,host->base + S3C2410_SDIIMSK);
+
+	// Setup SDI command argument and data control
+	writel(sdi_carg, host->base + S3C2410_SDICMDARG);
+	writel(sdi_dcon, host->base + S3C2410_SDIDCON);
+
+	// This initiates transfer
+	writel(sdi_ccon, host->base + S3C2410_SDICMDCON);
+
+	// Wait for transfer to complete
+	wait_for_completion(&host->complete_request);
+	DBG("[CMD] request complete.\n");
+	if(mrq->data) {
+		wait_for_completion(&host->complete_dma);
+		DBG("[DAT] DMA complete.\n");
+	}
+	
+	// Wait for DMA to complete
+//	if(mrq->data) wait_for_completion(&host->complete_dma);
+
+	//Cleanup controller
+	writel(0, host->base + S3C2410_SDICMDARG);
+	writel(0, host->base + S3C2410_SDIDCON);
+	writel(0, host->base + S3C2410_SDICMDCON);
+	writel(0, host->base + S3C2410_SDIIMSK);
+
+	// Read response
+	mrq->cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);
+	mrq->cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);
+	mrq->cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);
+	mrq->cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
+
+	host->mrq = NULL;
+
+	DBG(PFX "request done.\n");
+
+	// If we have no data transfer we are finished here
+	if (!mrq->data) goto request_done;
+
+	// Calulate the amout of bytes transfer, but only if there was
+	// no error
+	if(mrq->data->error == MMC_ERR_NONE) {
+		mrq->data->bytes_xfered = (mrq->data->blocks << mrq->data->blksz_bits);
+		if(mrq->data->flags & MMC_DATA_READ);
+#ifdef S3C2410SDI_DMA_BACKBUF
+		memcpy(mrq->data->req->buffer, host->dmabuf_log, mrq->data->bytes_xfered);
+#endif
+	} else {
+		mrq->data->bytes_xfered = 0;
+	}
+
+	// If we had an error while transfering data we flush the
+	// DMA channel to clear out any garbage
+	if(mrq->data->error != MMC_ERR_NONE) {
+		s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
+		DBG(PFX "flushing DMA.\n");		
+	}
+	// Issue stop command
+	if(mrq->data->stop) mmc_wait_for_cmd(mmc, mrq->data->stop, 3);
+
+
+request_done:
+
+	mrq->done(mrq);
+}
+
+static void s3c2410sdi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) {
+	struct s3c2410sdi_host *host = mmc_priv(mmc);
+	u32 sdi_psc, sdi_con;
+
+	//Set power
+	sdi_con = readl(host->base + S3C2410_SDICON);
+	switch(ios->power_mode) {
+		case MMC_POWER_ON:
+		case MMC_POWER_UP:
+			s3c2410_gpio_setpin(S3C2410_GPA17, 1); // card power on
+
+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
+			s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
+			s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
+			s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
+			s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
+			s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+
+			sdi_con|= S3C2410_SDICON_FIFORESET;
+			break;
+
+		case MMC_POWER_OFF:
+		default:
+			s3c2410_gpio_setpin(S3C2410_GPA17, 0); // card power off
+
+			s3c2410_gpio_setpin(S3C2410_GPE5, 0);
+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);
+			break;
+	}
+
+	//Set clock
+	for(sdi_psc=0;sdi_psc<255;sdi_psc++) {
+		if( (clk_get_rate(host->clk) / (2*(sdi_psc+1))) <= ios->clock) break;
+	}
+
+	if(sdi_psc > 255) sdi_psc = 255;
+	writel(sdi_psc, host->base + S3C2410_SDIPRE);
+
+	//Set CLOCK_ENABLE
+	if(ios->clock) 	sdi_con |= S3C2410_SDICON_CLOCKTYPE;
+	else		sdi_con &=~S3C2410_SDICON_CLOCKTYPE;
+
+	writel(sdi_con, host->base + S3C2410_SDICON);
+}
+
+static struct mmc_host_ops s3c2410sdi_ops = {
+	.request	= s3c2410sdi_request,
+	.set_ios	= s3c2410sdi_set_ios,
+};
+
+static int s3c2410sdi_probe(struct device *dev)
+{
+	struct platform_device	*pdev = to_platform_device(dev);
+	struct mmc_host 	*mmc;
+	struct s3c2410sdi_host 	*host;
+
+	int ret;
+
+	mmc = mmc_alloc_host(sizeof(struct s3c2410sdi_host), dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto probe_out;
+	}
+
+	host = mmc_priv(mmc);
+
+	spin_lock_init( &host->complete_lock );
+	host->complete_what 	= COMPLETION_NONE;
+	host->mmc 		= mmc;
+	host->dma		= S3C2410SDI_DMA;
+	host->irq_cd		= IRQ_EINT2;
+
+
+	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!host->mem) {
+		printk(KERN_INFO PFX "failed to get io memory region resouce.\n");
+		ret = -ENOENT;
+		goto probe_free_host;
+	}
+
+	host->mem = request_mem_region(host->mem->start,
+		RESSIZE(host->mem), pdev->name);
+
+	if (!host->mem) {
+		printk(KERN_INFO PFX "failed to request io memory region.\n");
+		ret = -ENOENT;
+		goto probe_free_host;
+	}
+
+	host->base = ioremap(host->mem->start, RESSIZE(host->mem));
+	if (host->base == 0) {
+		printk(KERN_INFO PFX "failed to ioremap() io memory region.\n");
+		ret = -EINVAL;
+		goto probe_free_mem_region;
+	}
+
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq == 0) {
+		printk(KERN_INFO PFX "failed to get interrupt resouce.\n");
+		ret = -EINVAL;
+		goto probe_iounmap;
+	}
+
+	if(request_irq(host->irq, s3c2410sdi_irq, 0, DRIVER_NAME, host)) {
+		printk(KERN_INFO PFX "failed to request sdi interrupt.\n");
+		ret = -ENOENT;
+		goto probe_iounmap;
+	}
+
+	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
+	set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
+
+	if(request_irq(host->irq_cd, s3c2410sdi_irq_cd, 0, DRIVER_NAME, host)) {
+		printk(KERN_WARNING PFX "failed to request card detect interrupt.\n" );
+		ret = -ENOENT;
+		goto probe_free_irq;
+	}
+
+	if(s3c2410_dma_request(S3C2410SDI_DMA, &s3c2410sdi_dma_client, NULL)) {
+		printk(KERN_WARNING PFX "unable to get DMA channel.\n" );
+		ret = -EBUSY;
+		goto probe_free_irq_cd;
+	}
+
+	host->clk = clk_get(dev, "sdi");
+	if (IS_ERR(host->clk)) {
+		printk(KERN_INFO PFX "failed to find clock source.\n");
+		ret = PTR_ERR(host->clk);
+		host->clk = NULL;
+		goto probe_free_host;
+	}
+
+	if((ret = clk_use(host->clk))) {
+		printk(KERN_INFO PFX "failed to use clock source.\n");
+		goto clk_free;
+	}
+
+	if((ret = clk_enable(host->clk))) {
+		printk(KERN_INFO PFX "failed to enable clock source.\n");
+		goto clk_unuse;
+	}
+
+
+	mmc->ops 	= &s3c2410sdi_ops;
+	mmc->ocr_avail	= MMC_VDD_32_33;
+	mmc->flags      = MMC_HOST_WIDEMODE;
+	mmc->f_min 	= clk_get_rate(host->clk) / 512;
+	mmc->f_max 	= clk_get_rate(host->clk) / 2;
+
+
+	//HACK: There seems to be a hardware bug in TomTom GO.
+	if(mmc->f_max>3000000) mmc->f_max=3000000;
+
+
+	/*
+	 * Since we only have a 16-bit data length register, we must
+	 * ensure that we don't exceed 2^16-1 bytes in a single request.
+	 * Choose 64 (512-byte) sectors as the limit.
+	 */
+	mmc->max_sectors = 64;
+
+	/*
+	 * Set the maximum segment size.  Since we aren't doing DMA
+	 * (yet) we are only limited by the data length register.
+	 */
+
+	mmc->max_seg_size = mmc->max_sectors << 9;
+#ifdef S3C2410SDI_DMA_BACKBUF	
+	host->dmabuf_log = dma_alloc_coherent(NULL, mmc->max_seg_size ,&host->dmabuf_phys, GFP_KERNEL|GFP_DMA);
+	
+	if(!host->dmabuf_log) {
+		printk(KERN_INFO PFX "failed to allocate DMA buffer.\n");
+		goto clk_disable;
+	}
+	
+	host->dmabuf_size = mmc->max_seg_size;
+	
+	printk(KERN_INFO PFX "probe: mapped sdi_base=%p irq=%u irq_cd=%u dma=%u dmabuf_l=%p dmabuf_p=%p.\n", 
+		host->base, host->irq, host->irq_cd, host->dma, host->dmabuf_log, host->dmabuf_phys);
+#else
+	printk(KERN_INFO PFX "probe: mapped sdi_base=%p irq=%u irq_cd=%u dma=%u.\n", 
+		host->base, host->irq, host->irq_cd, host->dma);
+#endif	
+	if((ret = mmc_add_host(mmc))) {
+		printk(KERN_INFO PFX "failed to add mmc host.\n");
+		goto free_dmabuf;
+	}
+
+	dev_set_drvdata(dev, mmc);
+
+	printk(KERN_INFO PFX "initialisation done.\n");
+	return 0;
+	
+ free_dmabuf:
+#ifdef S3C2410SDI_DMA_BACKBUF
+ 	dma_free_coherent(NULL, host->dmabuf_size, host->dmabuf_log, host->dmabuf_phys);
+#endif
+
+	clk_disable(host->clk);
+
+ clk_unuse:
+	clk_unuse(host->clk);
+
+ clk_free:
+	clk_put(host->clk);
+
+ probe_free_irq_cd:
+ 	free_irq(host->irq_cd, host);
+
+ probe_free_irq:
+ 	free_irq(host->irq, host);
+
+ probe_iounmap:
+	iounmap(host->base);
+
+ probe_free_mem_region:
+	release_mem_region(host->mem->start, RESSIZE(host->mem));
+
+ probe_free_host:
+	mmc_free_host(mmc);
+ probe_out:
+	return ret;
+}
+
+static int s3c2410sdi_remove(struct device *dev)
+{
+	struct mmc_host 	*mmc  = dev_get_drvdata(dev);
+	struct s3c2410sdi_host 	*host = mmc_priv(mmc);
+
+	mmc_remove_host(mmc);
+#ifdef S3C2410SDI_DMA_BACKBUF
+ 	dma_free_coherent(NULL, host->dmabuf_size, host->dmabuf_log, host->dmabuf_phys);
+#endif
+	clk_disable(host->clk);
+	clk_unuse(host->clk);
+	clk_put(host->clk);
+ 	free_irq(host->irq_cd, host);
+ 	free_irq(host->irq, host);
+	iounmap(host->base);
+	release_mem_region(host->mem->start, RESSIZE(host->mem));
+	mmc_free_host(mmc);
+
+	return 0;
+}
+
+static struct device_driver s3c2410sdi_driver =
+{
+        .name           = "s3c2410-sdi",
+        .bus            = &platform_bus_type,
+        .probe          = s3c2410sdi_probe,
+        .remove         = s3c2410sdi_remove,
+};
+
+static int __init s3c2410sdi_init(void)
+{
+	return driver_register(&s3c2410sdi_driver);
+}
+
+static void __exit s3c2410sdi_exit(void)
+{
+	driver_unregister(&s3c2410sdi_driver);
+}
+
+module_init(s3c2410sdi_init);
+module_exit(s3c2410sdi_exit);
+
+MODULE_DESCRIPTION("Samsung S3C2410 Multimedia Card Interface driver");
+MODULE_LICENSE("GPL");
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mmc/s3c2410mci.h linux-2.6.11-bk1-h1940/drivers/mmc/s3c2410mci.h
--- linux-2.6.11-bk1/drivers/mmc/s3c2410mci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mmc/s3c2410mci.h	2005-03-26 23:18:39.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ *  linux/drivers/mmc/s3c2410mci.h - Samsung S3C2410 SDI Interface driver
+ *
+ *  Copyright (C) 2004 Thomas Kleffel, All Rights Reserved.
+ *
+ * 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.
+ */
+
+struct clk;
+
+//FIXME: DMA Resource management ?!
+#define S3C2410SDI_DMA 0
+
+enum s3c2410sdi_waitfor {
+	COMPLETION_NONE,
+	COMPLETION_CMDSENT,
+	COMPLETION_RSPFIN,
+	COMPLETION_XFERFINISH,
+	COMPLETION_XFERFINISH_RSPFIN,
+};
+
+struct s3c2410sdi_host {
+	struct mmc_host		*mmc;
+
+	struct resource		*mem;
+	struct clk		*clk;
+	void __iomem		*base;
+	int			irq;
+	int			irq_cd;
+	int			dma;
+#ifdef S3C2410SDI_DMA_BACKBUF
+	dma_addr_t		 dmabuf_phys;
+	void			*dmabuf_log;
+	unsigned int		 dmabuf_size;
+#endif
+	
+	struct mmc_request	*mrq;
+
+	spinlock_t		complete_lock;
+	struct completion	complete_request;
+	struct completion	complete_dma;
+	enum s3c2410sdi_waitfor	complete_what;
+};
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/mtd/nand/s3c2410.c linux-2.6.11-bk1-h1940/drivers/mtd/nand/s3c2410.c
--- linux-2.6.11-bk1/drivers/mtd/nand/s3c2410.c	2005-03-02 08:38:13.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/mtd/nand/s3c2410.c	2005-03-26 23:18:44.000000000 +0100
@@ -31,10 +31,6 @@
 #include <config/mtd/nand/s3c2410/hwecc.h>
 #include <config/mtd/nand/s3c2410/debug.h>
 
-#ifdef CONFIG_MTD_NAND_S3C2410_DEBUG
-#define DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/init.h>
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/ether.c linux-2.6.11-bk1-h1940/drivers/usb/gadget/ether.c
--- linux-2.6.11-bk1/drivers/usb/gadget/ether.c	2005-03-02 08:38:32.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/ether.c	2005-03-26 23:18:17.000000000 +0100
@@ -259,6 +259,9 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
 #define	DEV_CONFIG_SUBSET
 #endif
 
+#ifdef CONFIG_USB_GADGET_S3C2410
+#define DEV_CONFIG_CDC
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -363,7 +366,7 @@ device_desc = {
 	.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,
@@ -2326,6 +2329,8 @@ eth_bind (struct usb_gadget *gadget)
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
 	} else if (gadget_is_pxa27x(gadget)) {
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
+	} else if (gadget_is_s3c2410(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
 	} else {
 		/* can't assume CDC works.  don't want to default to
 		 * anything less functional on CDC-capable hardware,
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/gadget_chips.h linux-2.6.11-bk1-h1940/drivers/usb/gadget/gadget_chips.h
--- linux-2.6.11-bk1/drivers/usb/gadget/gadget_chips.h	2005-03-02 08:37:30.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/gadget_chips.h	2005-03-26 23:18:18.000000000 +0100
@@ -74,6 +74,12 @@
 #define	gadget_is_pxa27x(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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/Kconfig linux-2.6.11-bk1-h1940/drivers/usb/gadget/Kconfig
--- linux-2.6.11-bk1/drivers/usb/gadget/Kconfig	2005-03-02 08:37:53.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/Kconfig	2005-03-26 23:18:18.000000000 +0100
@@ -162,7 +162,24 @@ config USB_LH7A40X
 	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_S3C2410_DEBUG
+	boolean "S3C2410 udc debug messages"
+	depends on USB_GADGET_S3C2410
+											    
 config USB_GADGET_DUMMY_HCD
 	boolean "Dummy HCD (DEVELOPMENT)"
 	depends on USB && EXPERIMENTAL
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/Makefile linux-2.6.11-bk1-h1940/drivers/usb/gadget/Makefile
--- linux-2.6.11-bk1/drivers/usb/gadget/Makefile	2005-03-02 08:37:48.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/Makefile	2005-03-26 23:18:18.000000000 +0100
@@ -7,7 +7,7 @@ obj-$(CONFIG_USB_PXA2XX)	+= pxa2xx_udc.o
 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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/s3c2410_udc.c linux-2.6.11-bk1-h1940/drivers/usb/gadget/s3c2410_udc.c
--- linux-2.6.11-bk1/drivers/usb/gadget/s3c2410_udc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/s3c2410_udc.c	2005-03-26 23:18:18.000000000 +0100
@@ -0,0 +1,1599 @@
+/*
+ * 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/arch/s3c2410_udc.h>
+#include <asm/hardware/clock.h>
+
+#include "s3c2410_udc.h"
+
+#define ENABLE_SYSFS
+
+#define DRIVER_DESC     "S3C2410 USB Device Controller Gadget"
+#define DRIVER_VERSION  "14 Mar 2005"
+#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 clk      		*udc_clock;
+
+static struct s3c2410_udc_mach_info *udc_info;
+
+/*************************** DEBUG FUNCTION ***************************/
+#define DEBUG_NORMAL	1
+#define DEBUG_VERBOSE	2
+
+#ifdef CONFIG_USB_S3C2410_DEBUG
+#define USB_S3C2410_DEBUG_LEVEL 1
+uint32_t s3c2410_ticks=0;
+static int dprintk(int level, const char *fmt, ...)
+{
+	static char printk_buf[1024];
+	static long prevticks;
+	static int invocation;
+	va_list args;
+	int len;
+	
+	if (level > USB_S3C2410_DEBUG_LEVEL)
+		return 0;
+	
+	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(int level, const char *fmt, ...)  { return 0; }
+#endif
+#ifdef ENABLE_SYSFS
+static ssize_t s3c2410udc_regs_show(struct device *dev, char *buf)
+{
+	u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg;
+	u32 ep_int_en_reg, usb_int_en_reg, ep0_csr;
+	u32 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2;
+	u32 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2;
+	
+	addr_reg       = __raw_readl(S3C2410_UDC_FUNC_ADDR_REG);
+	pwr_reg        = __raw_readl(S3C2410_UDC_PWR_REG);
+	ep_int_reg     = __raw_readl(S3C2410_UDC_EP_INT_REG);
+	usb_int_reg    = __raw_readl(S3C2410_UDC_USB_INT_REG);
+	ep_int_en_reg  = __raw_readl(S3C2410_UDC_EP_INT_EN_REG);
+	usb_int_en_reg = __raw_readl(S3C2410_UDC_USB_INT_EN_REG);
+	__raw_writel(0, S3C2410_UDC_INDEX_REG);
+	ep0_csr        = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+	__raw_writel(1, S3C2410_UDC_INDEX_REG);
+	ep1_i_csr1     = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+	ep1_i_csr2     = __raw_readl(S3C2410_UDC_IN_CSR2_REG);
+	ep1_o_csr1     = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+	ep1_o_csr2     = __raw_readl(S3C2410_UDC_IN_CSR2_REG);
+	__raw_writel(2, S3C2410_UDC_INDEX_REG);
+	ep2_i_csr1     = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+	ep2_i_csr2     = __raw_readl(S3C2410_UDC_IN_CSR2_REG);
+	ep2_o_csr1     = __raw_readl(S3C2410_UDC_IN_CSR1_REG);
+	ep2_o_csr2     = __raw_readl(S3C2410_UDC_IN_CSR2_REG);
+
+	
+	return snprintf(buf, PAGE_SIZE,        \
+		 "FUNC_ADDR_REG  : 0x%04X\n"   \
+		 "PWR_REG        : 0x%04X\n"   \
+		 "EP_INT_REG     : 0x%04X\n"   \
+		 "USB_INT_REG    : 0x%04X\n"   \
+		 "EP_INT_EN_REG  : 0x%04X\n"   \
+		 "USB_INT_EN_REG : 0x%04X\n"   \
+		 "EP0_CSR        : 0x%04X\n"   \
+		 "EP1_I_CSR1     : 0x%04X\n"   \
+		 "EP1_I_CSR2     : 0x%04X\n"   \
+		 "EP1_O_CSR1     : 0x%04X\n"   \
+		 "EP1_O_CSR2     : 0x%04X\n"   \
+		 "EP2_I_CSR1     : 0x%04X\n"   \
+		 "EP2_I_CSR2     : 0x%04X\n"   \
+		 "EP2_O_CSR1     : 0x%04X\n"   \
+		 "EP2_O_CSR2     : 0x%04X\n",  \
+		 addr_reg,pwr_reg,ep_int_reg,usb_int_reg,     \
+		 ep_int_en_reg, usb_int_en_reg, ep0_csr,      \
+		 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2, \
+		 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2  \
+		 );
+}
+
+static DEVICE_ATTR(regs, 0444,
+		   s3c2410udc_regs_show,
+		   NULL);
+
+
+#endif
+/*------------------------- I/O ----------------------------------*/
+static void nuke (struct s3c2410_udc *udc, struct s3c2410_ep *ep)
+{
+	/* Sanity check */
+	if (&ep->queue != NULL)
+		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(DEBUG_VERBOSE, "write_packet %d %d %d ",req->req.actual,req->req.length,len);
+	req->req.actual += len;
+	dprintk(DEBUG_VERBOSE, "%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(DEBUG_VERBOSE, "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(DEBUG_NORMAL, "read_fifo: Buffer full !!\n");
+		return -1;
+	}
+
+
+	__raw_writel(idx, S3C2410_UDC_INDEX_REG);
+		
+        fifo_count = fifo_count_out();
+	dprintk(DEBUG_VERBOSE, "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(DEBUG_VERBOSE, "fifo_read fifo count : %d [last %d]\n",fifo_count,is_last);
+
+	
+	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(DEBUG_VERBOSE, "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 ) {
+			dprintk(DEBUG_NORMAL, "read_fifo(): read failure\n");
+		}
+		
+		pOut++;
+		bytes_read++;
+	}
+	
+	dprintk(DEBUG_VERBOSE, "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(DEBUG_NORMAL, "... 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(DEBUG_NORMAL, "... 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(DEBUG_NORMAL, "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(DEBUG_NORMAL, "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(DEBUG_NORMAL, "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(DEBUG_NORMAL, "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(DEBUG_NORMAL, "config change %02x fail %d?\n",
+						crq.bRequest, ret);
+					return;
+				}
+				if (ret == -EOPNOTSUPP)
+					dprintk(DEBUG_NORMAL, "Operation not supported\n");
+				else
+					dprintk(DEBUG_NORMAL, "dev->driver->setup failed. (%d)\n",ret);
+				dev->ep0state = EP0_STALL;
+			/* deferred i/o == no response yet */
+			} else if (dev->req_pending) {
+			    	dprintk(DEBUG_NORMAL, "dev->req_pending... what now?\n");
+				dev->req_pending=0;
+			}
+			dprintk(DEBUG_VERBOSE, "ep0state %s\n",ep0states[dev->ep0state]);
+		}
+		break;
+	case EP0_IN_DATA_PHASE:			/* GET_DESCRIPTOR etc */
+	    	dprintk(DEBUG_NORMAL, "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(DEBUG_NORMAL, "EP0_OUT_DATA_PHASE ... what now?\n");
+		if ((ep0csr & 1) && req ) {
+			read_fifo(ep,req);
+		}
+		break;
+	case EP0_END_XFER:
+	    	dprintk(DEBUG_NORMAL, "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(DEBUG_VERBOSE, "ep%01d write csr:%02x ",idx,ep_csr1);
+		
+		if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL)
+		{
+			dprintk(DEBUG_VERBOSE, "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(DEBUG_VERBOSE, "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);
+		}
+	}
+}
+
+#include <asm/arch/regs-irq.h>
+/*
+ *      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;
+
+	
+	spin_lock(&dev->lock);
+	
+	/* Save index */
+	idx = __raw_readl(S3C2410_UDC_INDEX_REG);
+
+	/* Read status registers */
+	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(DEBUG_NORMAL, "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(DEBUG_NORMAL, "USB reset\n");
+		/* clear interrupt */
+		__raw_writel(S3C2410_UDC_USBINT_RESET,
+			S3C2410_UDC_USB_INT_REG);
+
+		__raw_writel(0x00, S3C2410_UDC_INDEX_REG);
+		__raw_writel(0x01,S3C2410_UDC_MAXP_REG);
+		
+		dev->address = 0x00;
+		__raw_writel( 0x80, S3C2410_UDC_FUNC_ADDR_REG);
+
+		dev->gadget.speed = USB_SPEED_FULL;
+		dev->ep0state = EP0_IDLE;
+	}
+
+	/* RESUME */
+	if (usb_status & S3C2410_UDC_USBINT_RESUME)
+	{
+		dprintk(DEBUG_NORMAL, "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(DEBUG_NORMAL, "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(DEBUG_NORMAL, "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(DEBUG_VERBOSE, "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(DEBUG_NORMAL,"irq: %d done.\n", irq);
+
+	/* Restore old index */
+	__raw_writel(idx,S3C2410_UDC_INDEX_REG);
+
+	spin_unlock(&dev->lock);
+
+	return IRQ_HANDLED;		
+}
+/*------------------------- 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 (DEBUG_NORMAL, "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;
+	u32			int_en_reg;
+
+
+	if (!_ep || !ep->desc) {
+		dprintk(DEBUG_NORMAL, "%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);
+
+	/* disable 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);
+
+	spin_unlock_irqrestore(&ep->dev->lock, flags);
+
+	dprintk(DEBUG_NORMAL, "%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;
+
+    	dprintk(DEBUG_NORMAL,"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;
+
+    	dprintk(DEBUG_NORMAL, "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;
+
+    	dprintk(DEBUG_NORMAL,"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)
+{
+    	dprintk(DEBUG_NORMAL, "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(DEBUG_NORMAL, "s3c2410_queue: 1 X X X\n");
+		else
+		{
+			dprintk(DEBUG_NORMAL, "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(DEBUG_NORMAL, "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(DEBUG_VERBOSE, "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;
+
+    	dprintk(DEBUG_NORMAL,"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(DEBUG_VERBOSE, "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;
+	
+	dprintk(DEBUG_VERBOSE,"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)
+{
+	
+	dprintk(DEBUG_NORMAL,"s3c2410_wakeup()\n");
+	
+	return 0;
+}
+
+/*
+ * 	s3c2410_set_selfpowered
+ */
+static int s3c2410_set_selfpowered (struct usb_gadget *_gadget, int value)
+{
+	struct s3c2410_udc  *udc;
+	
+	dprintk(DEBUG_NORMAL, "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---------------------------*/
+/*
+ * udc_disable
+ */
+static void udc_disable(struct s3c2410_udc *dev)
+{
+	dprintk(DEBUG_NORMAL, "udc_disable called");
+
+	/* Good bye, cruel world */
+	if (udc_info && udc_info->udc_command)
+		udc_info->udc_command(S3C2410_UDC_P_DISABLE);
+	
+	/* Set address to 0 */
+	__raw_writel( 0x80, S3C2410_UDC_FUNC_ADDR_REG);
+
+	/* Disable all interrupts */
+	__raw_writel(0x00, S3C2410_UDC_USB_INT_EN_REG);
+	__raw_writel(0x00, S3C2410_UDC_EP_INT_EN_REG);
+
+	/* Set speed to unknown */
+	dev->gadget.speed = USB_SPEED_UNKNOWN;
+}
+/*
+ * 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;
+	
+
+	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->dev = dev;
+		ep->desc = 0;
+		INIT_LIST_HEAD (&ep->queue);
+	}
+}
+
+/*
+ * udc_enable
+ */
+static void udc_enable(struct s3c2410_udc *dev)
+{
+	int i;
+	
+	dprintk(DEBUG_NORMAL, "udc_enable called");
+	
+	dev->gadget.speed = USB_SPEED_UNKNOWN;
+	
+	/* Set MAXP for all endpoints */
+	for (i = 0; i < S3C2410_ENDPOINTS; i++) {
+
+		__raw_writel(i, S3C2410_UDC_INDEX_REG);
+		__raw_writel(0x0001,S3C2410_UDC_MAXP_REG);
+	}
+
+	/* Set default power state */
+	__raw_writel(DEFAULT_POWER_STATE, S3C2410_UDC_PWR_REG);
+
+	/* Enable reset and suspend interrupt interrupts */
+	__raw_writel(1<<2 | 1<<0 ,S3C2410_UDC_USB_INT_EN_REG);
+	
+	/* Enable ep0 interrupt */
+	__raw_writel(0x01,S3C2410_UDC_EP_INT_EN_REG);
+
+	/* time to say "hello, world" */
+	if (udc_info && udc_info->udc_command)
+		udc_info->udc_command(S3C2410_UDC_P_ENABLE);
+}
+
+
+/*
+ * 	nop_release
+ */
+static void nop_release (struct device *dev)
+{
+	        dprintk(DEBUG_NORMAL, "%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;
+
+    	dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n",
+		driver->driver.name);
+
+	/* Sanity checks */
+	if (!udc)
+		return -ENODEV;
+	if (udc->driver)
+		return -EBUSY;
+	if (!driver->bind || !driver->unbind || !driver->setup
+			|| driver->speed == USB_SPEED_UNKNOWN)
+		return -EINVAL;
+
+	/* Hook the driver */
+	udc->driver = driver;
+	udc->gadget.dev.driver = &driver->driver;
+
+	/*Bind the driver */
+	device_add(&udc->gadget.dev);
+	dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", driver->driver.name);
+	if ((retval = driver->bind (&udc->gadget)) != 0) {
+		device_del(&udc->gadget.dev);
+		udc->driver = 0;
+		udc->gadget.dev.driver = 0;
+		return retval;
+	}
+
+        /* driver->driver.bus = 0; */
+
+	/* Enable udc */
+	udc_enable(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;
+
+    	dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n",
+		driver->driver.name);
+
+	driver->unbind (&udc->gadget);
+	device_del(&udc->gadget.dev);
+	udc->driver = 0;
+
+	device_release_driver (&udc->gadget.dev);
+	driver_unregister (&driver->driver);
+
+	/* Disable udc */
+	udc_disable(udc);
+	
+	return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+static struct s3c2410_udc memory = {
+	.gadget = {
+		.ops		= &s3c2410_ops,
+		.ep0		= &memory.ep[0].ep,
+		.name		= gadget_name,
+		.dev = {
+			.bus_id		= "gadget",
+			.release	= nop_release,
+		},
+	},
+
+	/* control endpoint */
+	.ep[0] = {
+		.num		= 0,
+		.ep = {
+			.name		= ep0name,
+			.ops		= &s3c2410_ep_ops,
+			.maxpacket	= EP0_FIFO_SIZE,
+		},
+		.dev		= &memory,
+	},
+
+	/* first group of endpoints */
+	.ep[1] = {
+		.num		= 1,
+		.ep = {
+			.name		= "ep1-bulk",
+			.ops		= &s3c2410_ep_ops,
+			.maxpacket	= EP_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= EP_FIFO_SIZE,
+		.bEndpointAddress = 1,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+	},
+	.ep[2] = {
+		.num		= 2,
+		.ep = {
+			.name		= "ep2-bulk",
+			.ops		= &s3c2410_ep_ops,
+			.maxpacket	= EP_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= EP_FIFO_SIZE,
+		.bEndpointAddress = 2,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+	},
+	.ep[3] = {
+		.num		= 3,
+		.ep = {
+			.name		= "ep3-bulk",
+			.ops		= &s3c2410_ep_ops,
+			.maxpacket	= EP_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= EP_FIFO_SIZE,
+		.bEndpointAddress = 3,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+	},
+	.ep[4] = {
+		.num		= 4,
+		.ep = {
+			.name		= "ep4-bulk",
+			.ops		= &s3c2410_ep_ops,
+			.maxpacket	= EP_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= EP_FIFO_SIZE,
+		.bEndpointAddress = 4,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+	}
+
+};
+
+/*
+ *	probe - binds to the platform device
+ */
+static int s3c2410_udc_probe(struct device *_dev)
+{
+	struct s3c2410_udc *udc = &memory;
+	int retval;
+
+
+	dprintk(DEBUG_NORMAL,"s3c2410_udc_probe\n");
+
+	spin_lock_init (&udc->lock);
+	udc_info = _dev->platform_data;
+
+	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);
+
+	udc_disable(udc);
+	udc_reinit(udc);
+	
+	/* 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(DEBUG_VERBOSE, "%s: got irq %i\n", gadget_name, IRQ_USBD);
+
+#ifdef ENABLE_SYSFS
+	/* create device files */
+	device_create_file(_dev, &dev_attr_regs);
+#endif
+	return 0;
+}
+
+/*
+ * 	s3c2410_udc_remove
+ */
+static int s3c2410_udc_remove(struct device *_dev)
+{
+	struct s3c2410_udc *udc = _dev->driver_data;
+	
+	dprintk(DEBUG_NORMAL, "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         = s3c2410_udc_remove,			
+};
+
+static int __init udc_init(void)
+{
+	u32 tmp;
+	dprintk(DEBUG_NORMAL, "%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_disable(udc_clock);
+	
+	tmp = (
+		 0x78 << S3C2410_PLLCON_MDIVSHIFT)
+	      | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
+	      | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
+	__raw_writel(tmp, S3C2410_UPLLCON);
+	
+
+	clk_enable(udc_clock);
+
+	mdelay(10);
+
+	dprintk(DEBUG_VERBOSE, "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_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/s3c2410_udc.h linux-2.6.11-bk1-h1940/drivers/usb/gadget/s3c2410_udc.h
--- linux-2.6.11-bk1/drivers/usb/gadget/s3c2410_udc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/s3c2410_udc.h	2005-03-26 23:18:18.000000000 +0100
@@ -0,0 +1,175 @@
+#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;
+};
+
+
+#define EP0_FIFO_SIZE		8
+#define EP_FIFO_SIZE		64
+#define DEFAULT_POWER_STATE	0x00
+
+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)
+
+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 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)
+
+#endif
+
+
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/serial.c linux-2.6.11-bk1-h1940/drivers/usb/gadget/serial.c
--- linux-2.6.11-bk1/drivers/usb/gadget/serial.c	2005-03-02 08:38:18.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/serial.c	2005-03-26 23:18:18.000000000 +0100
@@ -485,7 +485,11 @@ static struct usb_gadget_strings gs_stri
 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),
@@ -1531,6 +1535,9 @@ static int gs_bind(struct usb_gadget *ga
 	} else if (gadget_is_pxa27x(gadget)) {
 		gs_device_desc.bcdDevice =
 			__constant_cpu_to_le16(GS_VERSION_NUM|0x0011);
+ 	} else if (gadget_is_s3c2410(gadget)) {
+ 		gs_device_desc.bcdDevice =
+ 			__constant_cpu_to_le16(GS_VERSION_NUM|0x0012);
 	} else {
 		printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
 			gadget->name);
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/usb/gadget/zero.c linux-2.6.11-bk1-h1940/drivers/usb/gadget/zero.c
--- linux-2.6.11-bk1/drivers/usb/gadget/zero.c	2005-03-02 08:38:07.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/usb/gadget/zero.c	2005-03-26 23:18:18.000000000 +0100
@@ -226,7 +226,11 @@ device_desc = {
 	.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),
@@ -1191,6 +1195,8 @@ autoconf_fail:
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
 	} else if (gadget_is_pxa27x(gadget)) {
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
+	} else if (gadget_is_s3c2410(gadget)) {
+ 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
 	} else {
 		/* gadget zero is so simple (for now, no altsettings) that
 		 * it SHOULD NOT have problems with bulk-capable hardware.
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/backlight/Kconfig linux-2.6.11-bk1-h1940/drivers/video/backlight/Kconfig
--- linux-2.6.11-bk1/drivers/video/backlight/Kconfig	2005-03-02 08:38:10.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/backlight/Kconfig	2005-03-26 23:18:32.000000000 +0100
@@ -50,3 +50,11 @@ config BACKLIGHT_CORGI
 	  If you have a Sharp Zaurus SL-C7xx, say y to enable the
 	  backlight driver.
 
+config BACKLIGHT_S3C2410
+	tristate "Samsung S3C2410 Backlight Driver"
+	depends on BACKLIGHT_DEVICE && ARCH_S3C2410
+	default y
+	help
+	  If you have a backlight controler connected on a Samsung S3C2410,
+	  say y here to enable the driver.
+
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/backlight/Makefile linux-2.6.11-bk1-h1940/drivers/video/backlight/Makefile
--- linux-2.6.11-bk1/drivers/video/backlight/Makefile	2005-03-02 08:38:34.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/backlight/Makefile	2005-03-26 23:18:32.000000000 +0100
@@ -3,3 +3,4 @@
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_CORGI)	+= corgi_bl.o
+obj-$(CONFIG_BACKLIGHT_S3C2410)	+= s3c2410_bl.o
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/backlight/s3c2410_bl.c linux-2.6.11-bk1-h1940/drivers/video/backlight/s3c2410_bl.c
--- linux-2.6.11-bk1/drivers/video/backlight/s3c2410_bl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/backlight/s3c2410_bl.c	2005-03-26 23:18:32.000000000 +0100
@@ -0,0 +1,172 @@
+/*
+ * linux/drivers/video/backlight/s3c2410_bl.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * 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 Backlight Driver
+ *
+ * ChangeLog
+ *
+ * 2005-03-17: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *   - First version
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <asm/arch/s3c2410_bl.h>
+#include <asm/arch/regs-gpio.h>
+
+static int s3c2410bl_get_power(struct backlight_device *bl)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)class_get_devdata(&bl->class_dev);
+
+	if (info)
+		return info->power_value;
+	
+	return 0;
+}
+
+static int s3c2410bl_set_power(struct backlight_device *bl, int power)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)class_get_devdata(&bl->class_dev);
+	
+	power = !!power;
+
+	if (info) {
+		info->power_value=power;
+		info->backlight_power(power);
+	}
+
+	return 0;
+}
+
+static int s3c2410bl_get_brightness(struct backlight_device *bl)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)class_get_devdata(&bl->class_dev);
+
+	if(info)
+		return info->brightness_value;
+
+	return 0;
+}
+
+static int s3c2410bl_set_brightness(struct backlight_device *bl, int brightness)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)class_get_devdata(&bl->class_dev);
+	
+	if (info) {
+		if ( (brightness <= info->backlight_max) && brightness )
+		{
+			info->brightness_value=brightness;
+			info->set_brightness(brightness);
+		}
+		else
+			return -1;
+	}
+
+	return 0;
+}
+
+static int is_s3c2410fb(struct fb_info *info)
+{
+	return (!strcmp(info->fix.id,"s3c2410fb"));
+}
+
+static struct backlight_properties s3c2410bl_props = {
+	.owner    	= THIS_MODULE,
+	.get_power	= s3c2410bl_get_power,
+	.set_power	= s3c2410bl_set_power,
+	.get_brightness = s3c2410bl_get_brightness,
+	.set_brightness	= s3c2410bl_set_brightness,
+	.check_fb 	= is_s3c2410fb
+};
+
+
+
+
+static int __init s3c2410bl_probe(struct device *dev)
+{
+	struct backlight_device *bl;
+	struct s3c2410_bl_mach_info *info;
+
+	info = ( struct s3c2410_bl_mach_info *)dev->platform_data;
+	
+	/* Register the backlight device */
+	if (!info) {
+		printk(KERN_ERR "Hm... too bad : no platform data for bl\n");
+	}
+	else {	
+		s3c2410bl_props.max_brightness = info->backlight_max;
+	}
+	
+	bl=backlight_device_register ("s3c2410-bl",info, &s3c2410bl_props);
+	
+	if (IS_ERR (bl))
+		return PTR_ERR (bl);
+
+	dev_set_drvdata(dev, bl);
+	
+	/* Set power */
+	s3c2410bl_set_power(bl,1);
+
+	/* Set default brightness */
+	s3c2410bl_set_brightness(bl,info->backlight_default);
+
+	printk(KERN_ERR "s3c2410 Backlight Driver Initialized.\n");
+	return 0;
+}
+
+static int s3c2410bl_remove(struct device *dev)
+{
+	struct backlight_device *bl = dev->driver_data;
+	
+	if (bl) {
+		backlight_device_unregister(bl);
+		s3c2410bl_set_brightness(bl,0);
+	}
+	
+	printk("s3c2410 Backlight Driver Unloaded\n");
+	
+	return 0;
+					
+}
+
+static struct device_driver s3c2410bl_driver = {
+	.name		= "s3c2410-bl",
+	.bus		= &platform_bus_type,
+	.probe		= s3c2410bl_probe,
+	.remove		= s3c2410bl_remove,
+};
+
+
+
+static int __init s3c2410bl_init(void)
+{
+	return driver_register(&s3c2410bl_driver);
+}
+
+static void __exit s3c2410fb_cleanup(void)
+{
+	driver_unregister(&s3c2410bl_driver);
+}
+
+module_init(s3c2410bl_init);
+module_exit(s3c2410fb_cleanup);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("s3c2410 Backlight Driver");
+MODULE_LICENSE("GPLv2");
+
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/console/font_clean_4x6.c linux-2.6.11-bk1-h1940/drivers/video/console/font_clean_4x6.c
--- linux-2.6.11-bk1/drivers/video/console/font_clean_4x6.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/console/font_clean_4x6.c	2005-03-26 23:18:36.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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/console/font_clean_5x8.c linux-2.6.11-bk1-h1940/drivers/video/console/font_clean_5x8.c
--- linux-2.6.11-bk1/drivers/video/console/font_clean_5x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/console/font_clean_5x8.c	2005-03-26 23:18:36.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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/console/fonts.c linux-2.6.11-bk1-h1940/drivers/video/console/fonts.c
--- linux-2.6.11-bk1/drivers/video/console/fonts.c	2005-03-02 08:38:20.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/console/fonts.c	2005-03-26 23:18:36.000000000 +0100
@@ -56,6 +56,14 @@ static struct font_desc *fonts[] = {
 #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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/console/Kconfig linux-2.6.11-bk1-h1940/drivers/video/console/Kconfig
--- linux-2.6.11-bk1/drivers/video/console/Kconfig	2005-03-02 08:37:50.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/console/Kconfig	2005-03-26 23:18:36.000000000 +0100
@@ -171,6 +171,20 @@ config FONT_ACORN_8x8
 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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/console/Makefile linux-2.6.11-bk1-h1940/drivers/video/console/Makefile
--- linux-2.6.11-bk1/drivers/video/console/Makefile	2005-03-02 08:38:08.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/console/Makefile	2005-03-26 23:18:36.000000000 +0100
@@ -13,6 +13,8 @@ font-objs-$(CONFIG_FONT_6x11)      += fo
 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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/Kconfig linux-2.6.11-bk1-h1940/drivers/video/Kconfig
--- linux-2.6.11-bk1/drivers/video/Kconfig	2005-03-02 08:37:45.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/Kconfig	2005-03-26 23:18:28.000000000 +0100
@@ -1111,6 +1111,26 @@ config FB_PXA_PARAMETERS
 
 	  <file: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_S3C2410_DEBUG
+	bool "S3C2410 lcd debug messages"
+	depends on FB_S3C2410
+	help
+	  Turn on debugging messages. Note that you can set/unset at run time 
+	  through sysfs
+
 config FB_VIRTUAL
 	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
 	depends on FB
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/Makefile linux-2.6.11-bk1-h1940/drivers/video/Makefile
--- linux-2.6.11-bk1/drivers/video/Makefile	2005-03-02 08:37:48.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/Makefile	2005-03-26 23:18:28.000000000 +0100
@@ -92,6 +92,7 @@ obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.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_W100)		   += w100fb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
+obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
 obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
 obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
diff -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/s3c2410fb.c linux-2.6.11-bk1-h1940/drivers/video/s3c2410fb.c
--- linux-2.6.11-bk1/drivers/video/s3c2410fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/s3c2410fb.c	2005-03-26 23:18:28.000000000 +0100
@@ -0,0 +1,655 @@
+/*
+ * linux/drivers/video/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
+ *
+ * 2005-03-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - Removed the ioctl
+ *      - use readl/writel instead of __raw_writel/__raw_readl
+ * 
+ * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - Added the possibility to set on or off the 
+ *      debugging mesaages
+ *      - Replaced 0 and 1 by on or off when reading the
+ *      /sys files
+ * 
+ * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * 	- Removed the use of currcon as it no more exist
+ * 	- Added LCD power sysfs interface
+ *
+ * 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"
+
+
+static struct s3c2410fb_info info;
+static struct s3c2410fb_mach_info *mach_info;
+
+/* backlight and power control functions */
+
+static int lcd_power	   = 1;
+
+/* Debugging stuff */
+#ifdef CONFIG_FB_S3C2410_DEBUG
+static int debug	   = 1;
+#else
+static int debug	   = 0;
+#endif
+
+#define dprintk(msg...)	if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
+
+static inline void s3c2410fb_lcd_power(int to)
+{
+	if (mach_info == NULL)
+		return;
+
+	lcd_power = to;
+
+	if (mach_info->lcd_power)
+		(mach_info->lcd_power)(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;
+}
+
+#if 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;
+}
+#endif
+static int s3c2410fb_debug_show(struct device *dev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off");
+}
+static int s3c2410fb_debug_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) {
+		debug = 1;
+		printk(KERN_DEBUG "s3c2410fb: Debug On");
+	} else if (strnicmp(buf, "off", 3) == 0 ||
+		   strnicmp(buf, "0", 1) == 0) {
+		debug = 0;
+		printk(KERN_DEBUG "s3c2410fb: Debug Off");
+	} else {
+		return -EINVAL;
+	}
+
+	return len;
+}
+
+
+/* sysfs export of baclight control */
+static int s3c2410fb_lcd_power_show(struct device *dev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", lcd_power ? "on" : "off");
+}
+static int s3c2410fb_lcd_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_lcd_power(1);
+	} else if (strnicmp(buf, "off", 3) == 0 ||
+		   strnicmp(buf, "0", 1) == 0) {
+		s3c2410fb_lcd_power(0);
+	} else {
+		return -EINVAL;
+	}
+
+	return len;
+}
+
+static DEVICE_ATTR(debug, 0666,
+		   s3c2410fb_debug_show,
+		   s3c2410fb_debug_store);
+
+static DEVICE_ATTR(lcd_power, 0644,
+		   s3c2410fb_lcd_power_show,
+		   s3c2410fb_lcd_power_store);
+
+
+static struct fb_ops s3c2410fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= s3c2410fb_check_var,
+	.fb_set_par	= s3c2410fb_set_par,	
+#if 0
+	.fb_blank	= s3c2410fb_blank,
+#endif
+	.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,	
+};
+
+
+/* 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 = readl(reg) & ~mask;
+	writel(tmp | set, reg);
+
+	dprintk("%08lx set to %08x\n", reg, 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);
+
+	writel(mach_info->lcdcon1, S3C2410_LCDCON1);
+	writel(mach_info->lcdcon2, S3C2410_LCDCON2);
+	writel(mach_info->lcdcon3, S3C2410_LCDCON3);
+	writel(mach_info->lcdcon4, S3C2410_LCDCON4);
+	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);
+	writel(saddr1, S3C2410_LCDSADDR1);
+
+	dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
+	writel(saddr2, S3C2410_LCDSADDR2);
+	
+	dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
+	writel(saddr3, S3C2410_LCDSADDR3);
+
+	dprintk("LPCSEL    = 0x%08lx\n", mach_info->lpcsel);
+	writel(mach_info->lpcsel, S3C2410_LPCSEL);
+
+	dprintk("replacing TPAL %08x\n", readl(S3C2410_TPAL));
+
+	/* ensure temporary palette disabled */
+	writel(0x00, S3C2410_TPAL);
+
+	/* probably not required */
+	msleep(10);
+
+	/* Enable video by setting the ENVID bit to 1 */
+	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_lcd_power(1);
+
+
+	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_ERR "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( KERN_ERR "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(KERN_ERR "Failed to register framebuffer device: %d\n", ret);
+		goto failed;
+	}
+
+	/* create device files */
+	device_create_file(dev, &dev_attr_debug);
+	device_create_file(dev, &dev_attr_lcd_power);
+
+	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 = readl(S3C2410_LCDCON1);
+	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);
+
+		}
+
+		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);
+		
+	}
+
+	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 -Naurp -X dontdiff linux-2.6.11-bk1/drivers/video/s3c2410fb.h linux-2.6.11-bk1-h1940/drivers/video/s3c2410fb.h
--- linux-2.6.11-bk1/drivers/video/s3c2410fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/drivers/video/s3c2410fb.h	2005-03-26 23:18:28.000000000 +0100
@@ -0,0 +1,44 @@
+#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-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - Moved dprintk to s3c2410fb.c
+ *
+ * 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);
+
+#endif
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/regs-adc.h linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/regs-adc.h
--- linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/regs-adc.h	2005-03-06 12:23:13.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/regs-adc.h	2005-03-26 23:18:24.000000000 +0100
@@ -44,7 +44,7 @@
 #define S3C2410_ADCTSC_XP_SEN		(1<<4)
 #define S3C2410_ADCTSC_PULL_UP_DISABLE	(1<<3)
 #define S3C2410_ADCTSC_AUTO_PST		(1<<2)
-#define S3C2410_ADCTSC_XY_PST		(0x3<<0)
+#define S3C2410_ADCTSC_XY_PST(x)	(((x)&0x3)<<0)
 
 /* ADCDAT0 Bits */
 #define S3C2410_ADCDAT0_UPDOWN		(1<<15)
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/regs-sdi.h linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/regs-sdi.h
--- linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/regs-sdi.h	2005-03-02 08:37:31.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/regs-sdi.h	2005-03-26 23:18:39.000000000 +0100
@@ -47,7 +47,8 @@
 #define S3C2410_SDICMDCON_LONGRSP     (1<<10)
 #define S3C2410_SDICMDCON_WAITRSP     (1<<9)
 #define S3C2410_SDICMDCON_CMDSTART    (1<<8)
-#define S3C2410_SDICMDCON_INDEX       (0xff)
+#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
+#define S3C2410_SDICMDCON_INDEX       (0x3f)
 
 #define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
 #define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
@@ -73,6 +74,7 @@
 #define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
 #define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
 
+#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
 #define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
 
 #define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
@@ -115,4 +117,14 @@
 #define S3C2410_SDIIMSK_RXFIFOFULL     (1<<1)
 #define S3C2410_SDIIMSK_RXFIFOHALF     (1<<0)
 
+#define S3C2410_SDICMDCON_ABORT       (1<<12)
+#define S3C2410_SDICMDCON_WITHDATA    (1<<11)
+#define S3C2410_SDICMDCON_LONGRSP     (1<<10)
+#define S3C2410_SDICMDCON_WAITRSP     (1<<9)
+#define S3C2410_SDICMDCON_CMDSTART    (1<<8)
+#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
+
+#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
+#define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
+
 #endif /* __ASM_ARM_REGS_SDI */
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410_bl.h linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410_bl.h
--- linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410_bl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410_bl.h	2005-03-26 23:18:32.000000000 +0100
@@ -0,0 +1,29 @@
+/* linux/include/asm/arch-s3c2410/s3c2410_dl.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * 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:
+ *     14-Mar-2005     RTP     Created file
+ */
+
+#ifndef __ASM_ARM_S3C2410_BL_H
+#define __ASM_ARM_S3C2410_BL_H
+
+struct s3c2410_bl_mach_info {
+	int		power_value;
+	int		brightness_value;
+	int             backlight_max;
+	int             backlight_default;
+	void            (*backlight_power)(int);
+	void            (*set_brightness)(int);
+};
+
+void __init set_s3c2410bl_info(struct s3c2410_bl_mach_info *hard_s3c2410bl_info);
+
+#endif /* __ASM_ARM_S3C2410_BL_H */
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410fb.h linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410fb.h
--- linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410fb.h	2005-03-26 23:18:28.000000000 +0100
@@ -0,0 +1,59 @@
+/* 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;
+
+	/* Utility fonctions */
+	void		(*lcd_power)(int);
+};
+
+void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info);
+
+#endif /* __ASM_ARM_S3C2410FB_H */
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410_ts.h linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410_ts.h
--- linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410_ts.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410_ts.h	2005-03-26 23:18:24.000000000 +0100
@@ -0,0 +1,27 @@
+/* linux/include/asm/arch-s3c2410/s3c2410_ts.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * 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:
+ *     24-Mar-2005     RTP     Created file
+ */
+
+#ifndef __ASM_ARM_S3C2410_TS_H
+#define __ASM_ARM_S3C2410_TS_H
+
+struct s3c2410_ts_mach_info {
+       int             delay;
+       int             presc;
+       int             oversampling_shift;
+};
+
+void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info);
+
+#endif /* __ASM_ARM_S3C2410_TS_H */
+
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410_udc.h linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410_udc.h
--- linux-2.6.11-bk1/include/asm-arm/arch-s3c2410/s3c2410_udc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/asm-arm/arch-s3c2410/s3c2410_udc.h	2005-03-26 23:18:18.000000000 +0100
@@ -0,0 +1,31 @@
+/* linux/include/asm/arch-s3c2410/s3c2410_udc.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * 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:
+ *     14-Mar-2005     RTP     Created file
+ */
+
+#ifndef __ASM_ARM_S3C2410_UDC_H
+#define __ASM_ARM_S3C2410_UDC_H
+
+#include <asm/arch/regs-udc.h>
+
+#define S3C2410_UDC_P_ENABLE	1	/* Pull-up enable        */
+#define S3C2410_UDC_P_DISABLE	2	/* Pull-up disable       */
+#define S3C2410_UDC_P_RESET	3	/* UDC reset, in case of */
+
+struct s3c2410_udc_mach_info {
+	void            (*udc_command)(unsigned char);
+	
+};
+
+void __init set_s3c2410udc_info(struct s3c2410_udc_mach_info *hard_s3c2410udc_info);
+
+#endif /* __ASM_ARM_S3C2410_UDC_H */
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/linux/font.h linux-2.6.11-bk1-h1940/include/linux/font.h
--- linux-2.6.11-bk1/include/linux/font.h	2005-03-02 08:38:37.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/linux/font.h	2005-03-26 23:18:36.000000000 +0100
@@ -29,6 +29,8 @@ struct font_desc {
 #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 @@ extern struct font_desc	font_vga_8x8,
 				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 -Naurp -X dontdiff linux-2.6.11-bk1/include/linux/mmc/card.h linux-2.6.11-bk1-h1940/include/linux/mmc/card.h
--- linux-2.6.11-bk1/include/linux/mmc/card.h	2005-03-02 08:38:19.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/linux/mmc/card.h	2005-03-26 23:18:39.000000000 +0100
@@ -24,12 +24,55 @@ struct mmc_cid {
 };
 
 struct mmc_csd {
-	unsigned char		mmca_vsn;
-	unsigned short		cmdclass;
+	u8  sd;
+	u8  csd_vers;
+	u8  spec_vers;
+	u8  taac;
+	u8  nsac;
+	u16 ccc;
+	u8  tran_speed;
+	u8  read_bl_len;
+	u8  read_bl_partial;
+	u8  write_blk_misalign;
+	u8  read_blk_misalign;
+	u8  dsr_imp;
+	u16 c_size;
+	u8  vdd_r_curr_min;
+	u8  vdd_r_curr_max;
+	u8  vdd_w_curr_min;
+	u8  vdd_w_curr_max;
+	u8  c_size_mult;
+	union {
+		struct { /* MMC system specification version 3.1 */
+			u8  erase_grp_size;
+			u8  erase_grp_mult;
+		} mmc31;
+		struct { /* MMC system specification version 2.2 */
+			u8  sector_size;
+			u8  erase_grp_size;
+		} mmc22;
+		struct { /* SD Version 1.0 */
+			u8  erase_blk_en;
+			u8  erase_blk_size;
+		} sd10;
+	} erase;
+
+	u8  wp_grp_size;
+	u8  wp_grp_enable;
+	u8  default_ecc;
+	u8  r2w_factor;
+	u8  write_bl_len;
+	u8  write_bl_partial;
+	u8  file_format_grp;
+	u8  copy;
+	u8  perm_write_protect;
+	u8  tmp_write_protect;
+	u8  file_format;
+	u8  ecc;
+
 	unsigned short		tacc_clks;
 	unsigned int		tacc_ns;
 	unsigned int		max_dtr;
-	unsigned int		read_blkbits;
 	unsigned int		capacity;
 };
 
@@ -42,8 +85,10 @@ struct mmc_card {
 	struct list_head	node;		/* node in hosts devices list */
 	struct mmc_host		*host;		/* the host this device belongs to */
 	struct device		dev;		/* the device */
+	unsigned char		sd;
 	unsigned int		rca;		/* relative card address of device */
 	unsigned int		state;		/* (our) card state */
+	u8			bus_width;	/* bus_width the card is set to */
 #define MMC_STATE_PRESENT	(1<<0)		/* present in sysfs */
 #define MMC_STATE_DEAD		(1<<1)		/* device no longer in stack */
 #define MMC_STATE_BAD		(1<<2)		/* unrecognised device */
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/linux/mmc/host.h linux-2.6.11-bk1-h1940/include/linux/mmc/host.h
--- linux-2.6.11-bk1/include/linux/mmc/host.h	2005-03-02 08:38:10.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/linux/mmc/host.h	2005-03-26 23:18:39.000000000 +0100
@@ -61,12 +61,17 @@ struct mmc_host_ops {
 struct mmc_card;
 struct device;
 
+#define MMC_HOST_WIDEMODE	1
+
+#define MMC_HOST_WIDEMODE	1
+
 struct mmc_host {
 	struct device		*dev;
 	struct mmc_host_ops	*ops;
 	unsigned int		f_min;
 	unsigned int		f_max;
 	u32			ocr_avail;
+	u32			flags;
 	char			host_name[8];
 
 	/* host specific block data */
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/linux/mmc/mmc.h linux-2.6.11-bk1-h1940/include/linux/mmc/mmc.h
--- linux-2.6.11-bk1/include/linux/mmc/mmc.h	2005-03-02 08:38:09.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/linux/mmc/mmc.h	2005-03-26 23:18:39.000000000 +0100
@@ -47,6 +47,8 @@ struct mmc_command {
 #define MMC_ERR_FIFO	3
 #define MMC_ERR_FAILED	4
 #define MMC_ERR_INVALID	5
+#define MMC_ERR_BUSY	6
+#define MMC_ERR_DMA	7
 
 	struct mmc_data		*data;		/* data segment associated with cmd */
 	struct mmc_request	*mrq;		/* assoicated request */
@@ -63,6 +65,7 @@ struct mmc_data {
 #define MMC_DATA_WRITE	(1 << 8)
 #define MMC_DATA_READ	(1 << 9)
 #define MMC_DATA_STREAM	(1 << 10)
+#define MMC_DATA_WIDE	(1 << 11)
 
 	unsigned int		bytes_xfered;
 
@@ -71,6 +74,8 @@ struct mmc_data {
 
 	unsigned int		sg_len;		/* size of scatter list */
 	struct scatterlist	*sg;		/* I/O scatter list */
+
+	struct request		*req;
 };
 
 struct mmc_request {
diff -Naurp -X dontdiff linux-2.6.11-bk1/include/linux/mmc/protocol.h linux-2.6.11-bk1-h1940/include/linux/mmc/protocol.h
--- linux-2.6.11-bk1/include/linux/mmc/protocol.h	2005-03-02 08:38:34.000000000 +0100
+++ linux-2.6.11-bk1-h1940/include/linux/mmc/protocol.h	2005-03-26 23:18:39.000000000 +0100
@@ -76,6 +76,9 @@
 #define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */
 #define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1b */
 
+#define MMC_ACMD_SD_APP_OP_COND  41   /* ????  op conds		 ??? */
+#define MMC_ACMD_SD_SET_BUS_WIDTH 6   /* ????  00=1 10=4	 ??? */
+
 /*
   MMC status in R1
   Type
@@ -118,7 +121,8 @@
 /* These are unpacked versions of the actual responses */
 
 struct _mmc_csd {
-	u8  csd_structure;
+	u8  sd;
+	u8  csd_vers;
 	u8  spec_vers;
 	u8  taac;
 	u8  nsac;
@@ -139,11 +143,15 @@ struct _mmc_csd {
 		struct { /* MMC system specification version 3.1 */
 			u8  erase_grp_size;
 			u8  erase_grp_mult;
-		} v31;
+		} mmc31;
 		struct { /* MMC system specification version 2.2 */
 			u8  sector_size;
 			u8  erase_grp_size;
-		} v22;
+		} mmc22;
+		struct { /* SD Version 1.0 */
+			u8  erase_blk_en;
+			u8  erase_blk_size;
+		} sd10;
 	} erase;
 	u8  wp_grp_size;
 	u8  wp_grp_enable;
@@ -159,6 +167,13 @@ struct _mmc_csd {
 	u8  ecc;
 };
 
+#define SD_CSDV_1	0
+
+#define MMC_CSDV_1	0
+#define MMC_CSDV_14	1
+#define MMC_CSDV_2	2
+#define MMC_CSDV_3	3
+
 #define MMC_VDD_145_150	0x00000001	/* VDD voltage 1.45 - 1.50 */
 #define MMC_VDD_150_155	0x00000002	/* VDD voltage 1.50 - 1.55 */
 #define MMC_VDD_155_160	0x00000004	/* VDD voltage 1.55 - 1.60 */
diff -Naurp -X dontdiff linux-2.6.11-bk1/kernel/Makefile linux-2.6.11-bk1-h1940/kernel/Makefile
--- linux-2.6.11-bk1/kernel/Makefile	2005-03-02 08:37:50.000000000 +0100
+++ linux-2.6.11-bk1-h1940/kernel/Makefile	2005-03-26 23:18:21.000000000 +0100
@@ -7,7 +7,7 @@ obj-y     = sched.o fork.o exec_domain.o
 	    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 -Naurp -X dontdiff linux-2.6.11-bk1/kernel/mhelper.c linux-2.6.11-bk1-h1940/kernel/mhelper.c
--- linux-2.6.11-bk1/kernel/mhelper.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/kernel/mhelper.c	2005-03-26 23:18:21.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 -Naurp -X dontdiff linux-2.6.11-bk1/kernel/mhelper.h linux-2.6.11-bk1-h1940/kernel/mhelper.h
--- linux-2.6.11-bk1/kernel/mhelper.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-bk1-h1940/kernel/mhelper.h	2005-03-26 23:18:21.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 -Naurp -X dontdiff linux-2.6.11-bk1/Makefile linux-2.6.11-bk1-h1940/Makefile
--- linux-2.6.11-bk1/Makefile	2005-03-06 12:23:11.000000000 +0100
+++ linux-2.6.11-bk1-h1940/Makefile	2005-03-26 23:18:14.000000000 +0100
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 11
-EXTRAVERSION = -bk1
+EXTRAVERSION = -bk1-h1940
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
@@ -189,8 +189,8 @@ SUBARCH := $(shell uname -m | sed -e s/i
 # 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)
