diff -urN linux-2.4.26/arch/arm/boot/compressed/head.S linux-2.4.26-vrs1-lnode80/arch/arm/boot/compressed/head.S
--- linux-2.4.26/arch/arm/boot/compressed/head.S	2005-11-02 16:54:16.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/boot/compressed/head.S	2005-11-02 17:37:31.000000000 -0400
@@ -17,6 +17,7 @@
  * 100% relocatable.  Any attempt to do so will result in a crash.
  * Please select one of the following when turning on debugging.
  */
+#define DEBUG
 #ifdef DEBUG
 #if defined(CONFIG_DEBUG_DC21285_PORT)
 		.macro	loadsp, rb
@@ -81,6 +82,20 @@
  */
 		str	\rb, [r3, #0x14]	@ UTDR
 		.endm
+#elif 1 /* Sharp LH79520-type */
+		.macro	loadsp, rb
+		ldr	\rb, =0xfffc0000	@ UART1 base
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0]
+		.endm
+#elif 0 /* Sharp LH7A400-type */
+		.macro	loadsp, rb
+		ldr	\rb, =0x80000700	@ UART1 base
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0]
+		.endm
 #else
 #error no serial architecture defined
 #endif
@@ -97,6 +112,7 @@
 		bl	phex
 		.endm
 
+#undef DEBUG
 		.macro	debug_reloc_start
 #ifdef DEBUG
 		kputc	#'\n'
@@ -140,7 +156,9 @@
 		.word	0x016f2818		@ Magic numbers to help the loader
 		.word	start			@ absolute load/run zImage address
 		.word	_edata			@ zImage end address
-1:		mov	r7, r1			@ save architecture ID
+1:		@mov	r7, r1			@ save architecture ID
+		mov	r7, #0x300
+		orr	r7,r7,#0xe7
 		mov	r8, #0			@ save r0
 
 #ifndef __ARM_ARCH_2__
@@ -314,6 +332,11 @@
 LC1:		.word	reloc_end - reloc_start
 		.size	LC0, . - LC0
 
+		.type	proc_lh7a400_type,#object
+proc_lh7a400_type:
+		.word	0x41029220
+		.size	proc_lh7a400_type, . - proc_lh7a400_type
+
 /*
  * Turn on the cache.  We need to setup some page tables so that we
  * can have both the I and D caches on.
diff -urN linux-2.4.26/arch/arm/boot/Makefile linux-2.4.26-vrs1-lnode80/arch/arm/boot/Makefile
--- linux-2.4.26/arch/arm/boot/Makefile	2003-08-25 07:44:39.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/boot/Makefile	2005-11-02 17:37:31.000000000 -0400
@@ -101,6 +101,24 @@
 INITRD_VIRT	 = 0x0C800000
 endif
 
+ifeq ($(CONFIG_ARCH_LH79520),y)
+  ZTEXTADDR	 = 0x20008000
+  ZBSSADDR	 = 0x20200000
+  ZRELADDR	 = 0x20008000
+  INITRD_PHYS	 = 0x20400000
+  INITRD_VIRT	 = 0xC0400000
+  PARAMS_PHYS	 = 0x20110000
+endif
+
+ifeq ($(CONFIG_ARCH_LH7A400),y)
+  ZTEXTADDR	 = 0xC0008000
+  ZBSSADDR	 = 0xC0200000
+  ZRELADDR	 = 0xC0008000
+  INITRD_PHYS	 = 0xC4000000
+  INITRD_VIRT	 = 0xC4000000
+  PARAMS_PHYS	 = 0xC0000100
+endif
+
 ifeq ($(CONFIG_ARCH_SA1100),y)
 ZRELADDR	 = 0xc0008000
 # No defconfig file to move this into...
diff -urN linux-2.4.26/arch/arm/config.in linux-2.4.26-vrs1-lnode80/arch/arm/config.in
--- linux-2.4.26/arch/arm/config.in	2005-11-02 16:54:16.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/config.in	2005-11-02 17:37:31.000000000 -0400
@@ -48,6 +48,8 @@
 	 RiscPC			CONFIG_ARCH_RPC \
 	 RiscStation		CONFIG_ARCH_RISCSTATION \
 	 SA1100-based		CONFIG_ARCH_SA1100 \
+         LH79520-based          CONFIG_ARCH_LH79520 \
+         LH7A400-based          CONFIG_ARCH_LH7A400 \
 	 Shark			CONFIG_ARCH_SHARK \
 	 AT91RM9200-based	CONFIG_ARCH_AT91RM9200 " RiscPC
 
@@ -182,6 +184,17 @@
 
 endmenu
 
+mainmenu_option next_comment
+comment 'Sharp LH79520 Implementations'
+dep_bool '  LH79520 EVB' CONFIG_LH79520_EVB $CONFIG_ARCH_LH79520
+dep_bool '  520 BOGUS EVB' CONFIG_BOGON_EVB $CONFIG_ARCH_LH79520
+endmenu
+
+mainmenu_option next_comment
+comment 'Sharp LH7A400 Implementations'
+dep_bool '  LH7A400 EVB' CONFIG_LH7A400_EVB $CONFIG_ARCH_LH7A400
+endmenu
+
 # Definitions to make life easier
 if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \
      "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -295,6 +308,7 @@
 # ARM720T
 if [ "$CONFIG_ARCH_CLPS711X" = "y" -o \
      "$CONFIG_ARCH_L7200"    = "y" -o \
+     "$CONFIG_ARCH_LH79520"  = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" ]; then
    define_bool CONFIG_CPU_ARM720T y
 else
@@ -320,7 +334,8 @@
 
 
 # ARM922T
-if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
+if [ "$CONFIG_ARCH_CAMELOT" = "y" -o \
+     "$CONFIG_ARCH_LH7A400" = "y" ]; then
    define_bool CONFIG_CPU_ARM922T y
 else
    if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
@@ -399,6 +414,7 @@
      "$CONFIG_ARCH_TBOX"       = "y" -o "$CONFIG_ARCH_SHARK"    = "y" -o \
      "$CONFIG_ARCH_NEXUSPCI"   = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
+     "$CONFIG_ARCH_LH79520"    = "y" -o "$CONFIG_ARCH_LH7A400"  = "y" -o \
      "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
      "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" -o \
      "$CONFIG_ARCH_OMAHA"      = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
@@ -440,6 +456,8 @@
 
 # Select various configuration options depending on the machine type
 if [ "$CONFIG_ARCH_EDB7211" = "y" -o \
+     "$CONFIG_ARCH_LH79520" = "y" -o \
+     "$CONFIG_ARCH_LH7A400" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" -o \
      "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
    define_bool CONFIG_DISCONTIGMEM y
@@ -473,6 +491,8 @@
      "$CONFIG_ARCH_EBSA110" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o \
      "$CONFIG_ARCH_EDB7211" = "y" -o \
+     "$CONFIG_ARCH_LH79520" = "y" -o \
+     "$CONFIG_ARCH_LH7A400" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" ]; then
    define_bool CONFIG_ISA y
 else
@@ -690,6 +710,8 @@
         "$CONFIG_ARCH_TBOX" = "y" -o       \
         "$CONFIG_ARCH_CLPS7500" = "y" -o   \
         "$CONFIG_ARCH_P720T" = "y" -o      \
+	"$CONFIG_ARCH_LH79520" = "y" -o      \
+        "$CONFIG_ARCH_LH7A400" = "y" -o      \
         "$CONFIG_ARCH_ANAKIN" = "y" -o      \
 	"$CONFIG_ARCH_MX1ADS" = "y" ]; then
       define_bool CONFIG_PC_KEYMAP y
@@ -707,6 +729,8 @@
      "$CONFIG_ARCH_TBOX" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" -o \
+     "$CONFIG_ARCH_LH79520" = "y" -o \
+     "$CONFIG_ARCH_LH7A400" = "y" -o \
      "$CONFIG_PCI" = "y" ]; then
    mainmenu_option next_comment
    comment 'Sound'
diff -urN linux-2.4.26/arch/arm/def-configs/lnode80 linux-2.4.26-vrs1-lnode80/arch/arm/def-configs/lnode80
--- linux-2.4.26/arch/arm/def-configs/lnode80	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/def-configs/lnode80	2005-11-03 09:11:23.000000000 -0400
@@ -0,0 +1,804 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+CONFIG_ARCH_LH79520=y
+# CONFIG_ARCH_LH7A400 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_CSB337 is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+
+#
+# Sharp LH79520 Implementations
+#
+CONFIG_LH79520_EVB=y
+# CONFIG_BOGON_EVB is not set
+
+#
+# Sharp LH7A400 Implementations
+#
+# CONFIG_LH7A400_EVB is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_PLD is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+CONFIG_CPU_ARM720T=y
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1020E is not set
+# CONFIG_CPU_ARM1022 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE=""
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=40400000
+CONFIG_MTD_PHYSMAP_LEN=400000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=2
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_LH7A400 is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM1535_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+# CONFIG_LH79520_WATCHDOG is not set
+# CONFIG_EPXA_WATCHDOG is not set
+# CONFIG_OMAHA_WATCHDOG is not set
+# CONFIG_AT91_WATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SCx200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_AMD7XX_TCO is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_LH79520_PWM is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# Misc devices
+#
+# CONFIG_TOUCHSCREEN_LH79520 is not set
+# CONFIG_EEPROM_LH79520 is not set
+# CONFIG_7SEGMENT_LH79520 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.26/arch/arm/kernel/debug-armv.S linux-2.4.26-vrs1-lnode80/arch/arm/kernel/debug-armv.S
--- linux-2.4.26/arch/arm/kernel/debug-armv.S	2003-08-25 07:44:39.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/kernel/debug-armv.S	2005-11-02 17:37:31.000000000 -0400
@@ -470,6 +470,53 @@
 
 
 
+#elif defined(CONFIG_ARCH_LH79520)
+
+		.macro	addruart,rx
+		ldr	\rx, =0xfffc1000	@UART1 base
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]		@ UART1_DR
+		.endm
+
+		.macro	busyuart,rd,rx		@ spin while busy
+1001:		ldr	\rd, [\rx, #0x18]	@ UART1_FR
+		tst	\rd, #1 << 3		@ BUSY ?
+		bne	1001b			@ yes, spin
+		.endm
+
+		.macro	waituart,rd,rx		@ wait for Tx FIFO room
+1001:		ldrb	\rd, [\rx, #0x18]	@ UART1_FR
+		tst	\rd, #1 << 5		@ TXFF full?
+		bne	1001b			@ yes, spin
+		.endm
+
+#elif defined(CONFIG_ARCH_LH7A400)
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		ldr	\rx, =UART2_PHYS	@ physical base address
+		orrne	\rx, \rx, #0xf8000000	@ virtual base
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]		@ UART3_DR
+		.endm
+
+		.macro	busyuart,rd,rx		@ spin while busy
+1001:		ldr	\rd, [\rx, #0x10]	@ UART3_FR
+		tst	\rd, #1 << 3		@ BUSY ?
+		bne	1001b			@ yes, spin
+		.endm
+
+		.macro	waituart,rd,rx		@ wait for Tx FIFO room
+1001:		ldrb	\rd, [\rx, #0x10]	@ UART3_FR
+		tst	\rd, #1 << 5		@ TXFF full?
+		bne	1001b			@ yes, spin
+		.endm
+
 #else
 #error Unknown architecture
 #endif
diff -urN linux-2.4.26/arch/arm/kernel/entry-armv.S linux-2.4.26-vrs1-lnode80/arch/arm/kernel/entry-armv.S
--- linux-2.4.26/arch/arm/kernel/entry-armv.S	2005-11-02 16:54:17.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/kernel/entry-armv.S	2005-11-02 17:37:31.000000000 -0400
@@ -615,6 +615,49 @@
 		.text
 		.endm
 
+#elif defined(CONFIG_ARCH_LH79520)
+#include <asm/arch/hardware.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr     \irqstat, =VIC_BASE			@ Virt addr IRQ regs
+		ldr     \irqstat, [\irqstat, #0]		@ get masked interrupt status
+		mov     \irqnr, #0
+1001:		tst     \irqstat, #1
+		addeq   \irqnr, \irqnr, #1
+		moveq   \irqstat, \irqstat, lsr #1
+		tsteq   \irqnr, #32
+		beq     1001b
+		teq     \irqnr, #32
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_LH7A400)
+#include <asm/arch/hardware.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr     \irqstat, =IO_ADDRESS(INTC_PHYS)	@ Virt addr IRQ regs
+		ldr     \irqstat, [\irqstat, #0]		@ get masked interrupt status
+		mov     \irqnr, #0
+1001:		tst     \irqstat, #1
+		bne	1002f
+		add     \irqnr, \irqnr, #1
+		mov     \irqstat, \irqstat, lsr #1
+		cmp   \irqnr, #28
+		bcc     1001b
+1002:		/* EQ will be set if we reach 28 */
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
 #else
 #error Unknown architecture
 #endif
diff -urN linux-2.4.26/arch/arm/kernel/irq.c linux-2.4.26-vrs1-lnode80/arch/arm/kernel/irq.c
--- linux-2.4.26/arch/arm/kernel/irq.c	2005-11-02 16:54:17.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/kernel/irq.c	2005-11-02 17:37:31.000000000 -0400
@@ -216,6 +216,18 @@
 
 	desc->triggered = 1;
 
+#ifdef CONFIG_ARCH_LH79520
+	if( irq < 8) {											/* external interrupt */
+		vicRegs_t	*vic = (vicRegs_t *)VIC_BASE;
+		rcpcRegs_t	*rcpc = (rcpcRegs_t *)IO_ADDRESS( RCPC_PHYS);
+
+		rcpc->control   |=  RCPC_CTRL_WRTLOCK_ENABLED;		/* unlock RCPC registers */
+		barrier();
+		rcpc->intClear  = (1 << irq);				/* clear corresponding IRQ */
+		rcpc->control   &=  ~RCPC_CTRL_WRTLOCK_ENABLED;		/* lock RCPC registers   */
+	}
+#endif
+	
 	/*
 	 * Acknowledge and clear the IRQ, but (if its
 	 * a level-based IRQ, don't mask it)
diff -urN linux-2.4.26/arch/arm/kernel/ptrace.c linux-2.4.26-vrs1-lnode80/arch/arm/kernel/ptrace.c
--- linux-2.4.26/arch/arm/kernel/ptrace.c	2005-11-02 16:54:17.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/kernel/ptrace.c	2005-11-02 17:37:31.000000000 -0400
@@ -594,6 +594,9 @@
 		 */
 		case PTRACE_POKETEXT:
 		case PTRACE_POKEDATA:
+                    if(data == 0xe7ffdefe)
+                            data = 0xef9f0001;
+
 			ret = access_process_vm(child, addr, &data,
 						sizeof(unsigned long), 1);
 			if (ret == sizeof(unsigned long))
diff -urN linux-2.4.26/arch/arm/mach-lh79520/arch.c linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/arch.c
--- linux-2.4.26/arch/arm/mach-lh79520/arch.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/arch.c	2005-11-03 10:30:56.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ *  linux/arch/arm/mach-lh79520/arch.c
+ *
+ *  Architecture specific fixups.
+ *
+ *  Copyright (C) 2001 Lineo, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq( void);
+extern void lh79520_map_io( void);
+
+#ifdef CONFIG_ARCH_LH79520
+
+static void __init
+fixup_lh79520(struct machine_desc *desc, struct param_struct *unused,
+             char **cmdline, struct meminfo *mi)
+{
+        mi->nr_banks      = 1;
+        mi->bank[0].start = PHYS_OFFSET;
+        mi->bank[0].size  = (32*1024*1024);
+        mi->bank[0].node  = 0;
+
+        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+        setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+        setup_initrd( __phys_to_virt(0x20400000), 3 * 1024 * 1024);
+
+        /* Serial Console on UART 1 */
+		strcpy( *cmdline, "console=ttyAM1,115200");
+}
+
+
+MACHINE_START(LH79520EVB, "Sharp LH79520 Evaluation Board")
+	MAINTAINER("Duck")
+	BOOT_MEM( 0x20000000, 0xff800000, 0xff800000)		// pio, vio must be 8MB
+	FIXUP( fixup_lh79520)
+	MAPIO( lh79520_map_io)
+	INITIRQ( genarch_init_irq)
+MACHINE_END
+#endif
diff -urN linux-2.4.26/arch/arm/mach-lh79520/dma.c linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/dma.c
--- linux-2.4.26/arch/arm/mach-lh79520/dma.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/dma.c	2005-11-02 17:38:44.000000000 -0400
@@ -0,0 +1,841 @@
+/*
+ * arch/arm/mach-lh79520/dma-lh79520.c
+ * Copyright (C) 2002 Embedix, Inc.
+ *
+ * Support functions for the Sharp LH79520 internal DMA channels.
+ *
+ * Based on arch/arm/mach-sa1100/dma-sa1100.c, which is
+ * Copyright (C) 2000 Nicolas Pitre
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+#include <asm/arch/iocon.h>
+
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK( s, arg... )  printk( "dma<%s>: " s, dma->device_id , ##arg )
+#define DUMPREGS(r,d) \
+    printk( "regs=0x%x   src=0x%x:%x  dest=0x%x:%x  count=%d  control=0x%x  tcnt=%d    mask=0x%x  status=0x%x\n", \
+	    (u32)r, r->srcHi, r->srcLow, r->destHi, r->destLow, r->count, r->control, r->termCnt, d->mask, d->status)
+#define DUMPQ(d)	dumpq(d)
+#else
+#define DPRINTK( x... )
+#define DUMPREGS(r,d)
+#define DUMPQ(d)
+#endif
+
+/*
+ * DMA channel registers structure
+ */
+typedef struct {
+	volatile u32	srcLow;		/* Source base addr, low 16 bits */
+	volatile u32	srcHi;		/* Source base addr,  hi 16 bits */
+	volatile u32	destLow;	/* Dest base addr,   low 16 bits */ 
+	volatile u32	destHi;		/* Dest base addr,    hi 16 bits */ 
+	volatile u32	count;		/* Maximum Count */ 		
+	volatile u32	control;	/* Control */ 
+	volatile u32	currSrcHi;	/* Current src addr,  hi 16 bits*/ 
+	volatile u32	currSrcLow;	/* Current src addr, low 16 bits*/ 
+	volatile u32	currDstHi;	/* Curr dest addr,    hi 16 bits*/ 
+	volatile u32	currDstLow;	/* Curr src addr,    low 16 bits*/ 
+	volatile u32	termCnt;	/* Terminal Count */ 		
+} channelRegs_t;
+
+
+/*
+ * Control Register Bit Field
+ */ 
+#define DMAC_CTRL_ENABLE		_BIT(0)		/* Enable DMA */ 
+#define DMAC_CTRL_SOINC			_BIT(1)		/* Source Reg inc.bit */ 
+#define DMAC_CTRL_DEINC			_BIT(2)		/* Dest Reg inc.bit */ 
+/* Source Size */ 
+#define DMAC_CTRL_SOSIZE_1BYTE		_SBF(3,0)
+#define DMAC_CTRL_SOSIZE_2BYTE		_SBF(3,1)
+#define DMAC_CTRL_SOSIZE_4BYTE		_SBF(3,2)
+/* Destination Size */ 
+#define DMAC_CTRL_DESIZE_1BYTE		_SBF(7,0)
+#define DMAC_CTRL_DESIZE_2BYTE		_SBF(7,1)
+#define DMAC_CTRL_DESIZE_4BYTE		_SBF(7,2)
+/* Peripheral Burst Sizes */ 
+#define DMAC_CTRL_SOBURST_SINGLE	_SBF(5,0)	/* Single */ 
+#define DMAC_CTRL_SOBURST_4INC		_SBF(5,1)	/* 4 incrementing */ 
+#define DMAC_CTRL_SOBURST_8INC		_SBF(5,2)	/* 8 incrementing */ 
+#define DMAC_CTRL_SOBURST_16INC		_SBF(5,3)	/* 16 incrementing */ 
+/* Address Modes */ 
+#define DMAC_CTRL_ADDR_MODE_WRAP	_SBF(9,0)
+#define DMAC_CTRL_ADDR_MODE_INCR	_SBF(9,1)
+
+#define DMAC_CTRL_MEM2MEM		_BIT(11)	/* Memory to Memory */ 
+/* Direction */ 
+#define DMAC_CTRL_PERIPH_SOURCE		_SBF(13,0)
+#define DMAC_CTRL_PERIPH_DEST		_SBF(13,1)
+
+
+typedef struct {
+	channelRegs_t	stream0;	/* Data Stream 0 */ 
+	volatile u32	reserved0[5];
+	channelRegs_t	stream1;	/* Data Stream 1 */ 
+	volatile u32	reserved1[5];
+	channelRegs_t	stream2;	/* Data Stream 2 */ 
+	volatile u32	reserved2[5];
+	channelRegs_t	stream3;	/* Data Stream 3 */ 
+	volatile u32	reserved3;
+	volatile u32	mask;
+	volatile u32	clear;
+	volatile u32	status;
+	volatile u32	reserved4;
+} dmaRegs_t;
+
+channelRegs_t *streamRegs[] = {
+	&((dmaRegs_t *)IO_ADDRESS(DMAC_PHYS))->stream0,
+	&((dmaRegs_t *)IO_ADDRESS(DMAC_PHYS))->stream1,
+	&((dmaRegs_t *)IO_ADDRESS(DMAC_PHYS))->stream2,
+	&((dmaRegs_t *)IO_ADDRESS(DMAC_PHYS))->stream3
+};
+
+/*
+ * mask   - Mask Register Bit Fields
+ * clear  - Clear Register Bit Fields
+ * status - Clear Register Bit Fields
+ *
+ * Writing DMAC_xN to mask register enables corresponding interrupt
+ * Writing DMAC_xN to clear register disables corresponding interrupt
+ * AND'ing DMAC_xN with status register yields status
+ * Note: "ACTIVEx" constants are only applicable to Status Register
+ */ 
+#define	DMAC_INT0	_BIT(0)		/* Stream 0 Interrupt */ 
+#define	DMAC_INT1	_BIT(1)		/* Stream 1 Interrupt */ 
+#define	DMAC_INT2	_BIT(2)		/* Stream 2 Interrupt */ 
+#define	DMAC_INT3	_BIT(3)		/* Stream 3 Interrupt */ 
+#define	DMAC_ERRINT0	_BIT(4)		/* Stream 0 Error Interrupt */
+#define	DMAC_ERRINT1	_BIT(5)		/* Stream 1 Error Interrupt */ 
+#define	DMAC_ERRINT2	_BIT(6)		/* Stream 2 Error Interrupt */ 
+#define	DMAC_ERRINT3	_BIT(7)		/* Stream 3 Error Interrupt */ 
+#define	DMAC_ACTIVE0	_BIT(8)		/* Stream 0 Active */ 
+#define	DMAC_ACTIVE1	_BIT(9)		/* Stream 1 Active */ 
+#define	DMAC_ACTIVE2	_BIT(10)	/* Stream 2 Active */ 
+#define	DMAC_ACTIVE3	_BIT(11)	/* Stream 3 Active */ 
+
+/* all DMA error bits */
+#define DMAC_ERROR	(DMAC_ERRINT0 | DMAC_ERRINT1 | DMAC_ERRINT2 | DMAC_ERRINT3 )
+
+/* all DMA done bits */
+#define DMAC_DONE	(DMAC_INT0 | DMAC_INT1 | DMAC_INT2 | DMAC_INT3)
+
+/* all the bits in the clear register */
+#define DMAC_CLEAR_ALL	(DMAC_DONE | DMAC_ERROR)
+
+
+#include "dma.h"
+
+lh79520_dma_t dma_chan[LH79520_DMA_CHANNELS];
+
+/*
+ * Maximum physical DMA buffer size
+ */
+#define MAX_DMA_SIZE		0x3ffff
+#define MAX_DMA_ORDER		18
+
+
+static inline void dumpq (lh79520_dma_t *dma)
+{
+    dma_buf_t *p=dma->tail;
+
+    printk( "Q: curr=0x%p  tail=0x%p  head=0x%p  bid: ", dma->curr, dma->tail, dma->head);
+
+    while( p) {
+	printk( "(0x%p 0x%p)  ", p, p->id);
+	p = p->next;
+    }
+    printk("\n");
+}
+
+
+/*
+ * DMA processing...
+ */
+
+static inline int start_lh79520_dma(lh79520_dma_t * dma, dma_addr_t dma_ptr, int size)
+{
+    dmaRegs_t     *dmaRegs = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    cpldRegs_t    *cpld    = (cpldRegs_t *)CPLD_BASE;
+    channelRegs_t *regs    = dma->regs;
+    int status;
+
+    status = dmaRegs->status;
+
+    /* If the DMA channel is active, there's nothing else we can do. */
+    if( status & (DMAC_ACTIVE0 << dma->channel)) {
+	DPRINTK("start: st %#x busy\n", status);
+	return -EBUSY;
+    }
+
+    /* If there's an interrupt pending, split now
+     * and let it happen.
+     */
+    if( status & (DMAC_INT0 << dma->channel)) {
+	DPRINTK("start: st %#x IRQ pending\n", status);
+	return -EAGAIN;
+    }
+
+    /*
+     * if we're goint to the uda1341, we have to tell the CPLD
+     * to start to send/receive via DMA.
+     */
+    switch( dma->channel) {
+	case 2:
+	    cpld->audio_control |= CPLD_DAC_DMA_ENABLE;
+	    dmaRegs->mask  |= DMAC_INT2;
+	    break;
+
+	case 3:
+	    cpld->audio_control |= (CPLD_DAC_DMA_ENABLE | CPLD_DAC_USE_REQ1 );
+	    dmaRegs->mask  |= DMAC_INT3;
+	    break;
+    }
+
+    /*
+     * set the source or destination registers, based on which 
+     * direction the data's going.
+     */
+    if( dma->direction == DMA_IN) {	/* data coming from peripheral */
+	regs->destLow  = dma_ptr & 0xffff;
+	regs->destHi   = (dma_ptr >> 16 ) & 0xffff;
+    } else {				/* data going to peripheral */
+	regs->srcLow   = dma_ptr & 0xffff;
+	regs->srcHi    = (dma_ptr >> 16 ) & 0xffff;
+    }
+
+    regs->count    = size >> 2;		/* DDD assumes 4-byte transfer size */
+    regs->control |= DMAC_CTRL_ENABLE;
+
+    DPRINTK("audio_control=0x%x\n", cpld->audio_control);
+    DPRINTK("jif=%d start a=%#x sz=%d  st=0x%x  dma=0x%p  dir=%d\n",
+	    jiffies, dma_ptr, size, status, dma, dma->direction);
+    DUMPREGS(regs,dmaRegs);
+
+#if 0
+    {
+	u32 *p = phys_to_virt(dma_ptr);
+	int i;
+
+	for( i=0; i<8; i++)
+	    printk( " %08x %08x %08x %08x\n", *p++, *p++, *p++, *p++);
+    }
+#endif // 0
+
+    return 0;
+}
+
+
+static int start_dma(lh79520_dma_t *dma, dma_addr_t dma_ptr, int size)
+{
+	return start_lh79520_dma(dma, dma_ptr, size);
+}
+
+
+/* This must be called with IRQ disabled */
+static void process_dma(lh79520_dma_t * dma)
+{
+    dma_buf_t *buf;
+    int chunksize;
+
+    DUMPQ(dma);
+
+    for (;;) {
+	buf = dma->tail;
+
+	if (!buf || dma->stopped) {
+	    /* no more data available */
+	    DPRINTK("process: no more buf (dma %s)  buf=0x%p  stopped=%d\n",
+		    dma->curr ? "active" : "inactive", buf, dma->stopped);
+	    /*
+	     * Some devices may require DMA still sending data
+	     * at any time for clock reference, etc.
+	     * Note: if there is still a data buffer being
+	     * processed then the ref count is negative.  This
+	     * allows for the DMA termination to be accounted in
+	     * the proper order.
+	     */
+	    if (dma->spin_size && dma->spin_ref >= 0) {
+		chunksize = dma->spin_size;
+		if (chunksize > MAX_DMA_SIZE)
+		    chunksize = (1 << MAX_DMA_ORDER);
+		while (start_dma(dma, dma->spin_addr, chunksize) == 0)
+		    dma->spin_ref++;
+		if (dma->curr != NULL)
+		    dma->spin_ref = -dma->spin_ref;
+	    }
+	    break;
+	}
+
+	/*
+	 * Let's try to start DMA on the current buffer.
+	 * If DMA is busy then we break here.
+	 */
+	chunksize = buf->size;
+	if (chunksize > MAX_DMA_SIZE)
+	    chunksize = (1 << MAX_DMA_ORDER);
+
+	DPRINTK("process: bid=%#x s=%d\n", (int) buf->id, buf->size);
+	if (start_dma(dma, buf->dma_ptr, chunksize) != 0)
+	    break;
+
+	if (!dma->curr) {
+	    dma->curr = buf;
+	    DPRINTK("process: set curr %#p\n", dma->curr);
+	}
+
+	buf->ref++;
+	buf->dma_ptr += chunksize;
+	buf->size -= chunksize;
+	if (buf->size == 0) {
+	    /* current buffer is done: move tail to the next one */
+	    dma->tail = buf->next;
+	    DPRINTK("process: set tail b=%#x\n", (int) dma->tail);
+	}
+    }
+
+    DUMPQ(dma);
+}
+
+
+/* This must be called with IRQ disabled */
+void lh79520_dma_done (lh79520_dma_t *dma)
+{
+    dma_buf_t *buf = dma->curr;
+
+    if (dma->spin_ref > 0) {
+	dma->spin_ref--;
+    } else if (buf) {
+	buf->ref--;
+	if (buf->ref == 0 && buf->size == 0) {
+	    /*
+	     * Current buffer is done.
+	     * Move current reference to the next one and send
+	     * the processed buffer to the callback function,
+	     * then discard it.
+	     */
+	    DPRINTK("IRQ: buf done  set curr=%#p\n", buf->next);
+	    dma->curr = buf->next;
+	    if (dma->curr == NULL)
+		dma->spin_ref = -dma->spin_ref;
+	    if (dma->head == buf)
+		dma->head = NULL;
+	    if (dma->callback) {
+		int size = buf->dma_ptr - buf->dma_start;
+		dma->callback(buf->id, size);
+	    }
+	    kfree(buf);
+	}
+    }
+
+    process_dma(dma);
+}
+
+
+static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+    dmaRegs_t *dmaRegs  = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    lh79520_dma_t *dma = (lh79520_dma_t *) dev_id;
+    int status = dmaRegs->status;
+
+    DPRINTK("jif=%d  IRQ: irq=%d  regs=0x%x  bid=%#x st=%#x, dma=0x%p\n",
+	    jiffies, irq, (u32)dma->regs, (int) dma->curr->id, status, dma);
+
+    if (status & (DMAC_ERROR)) {
+	printk(KERN_ERR "DMA on \"%s\" caused an error\n", dma->device_id);
+	dmaRegs->clear = DMAC_ERROR;
+    }
+
+    dmaRegs->clear = status & DMAC_DONE;
+    
+    if (status & DMAC_DONE)
+	lh79520_dma_done (dma);
+}
+
+
+/*
+ * DMA interface functions
+ */
+
+static spinlock_t dma_list_lock;
+
+int lh79520_request_dma (dmach_t * channel, const char *device_id, dma_device_t device)
+{
+    lh79520_dma_t *dma = NULL;
+    cpldRegs_t    *cpld    = (cpldRegs_t *)CPLD_BASE;
+    channelRegs_t *regs;
+    int i, err;
+
+    /* DMA address (physical) of audio device */
+    void *cpldAudioAddr = (void *) &((cpldRegs_t *)CPLD_START)->adc_dac_left;
+
+
+#ifdef DEBUG
+    printk( __FUNCTION__ "(channel=0x%x,  device_id=0x%x  device=0x%x)\n",
+	    (u32)channel, (u32)device_id, device);
+#endif
+
+    *channel = -1;		/* to be sure we catch the freeing of a misregistered channel */
+
+    err = 0;
+    spin_lock(&dma_list_lock);
+
+    /*
+     * Allocate a channel.  On the lh79520, channels 0 and 1
+     * are dedicated to the SSP.  Channels 2 and 3 are general purpose,
+     * but channel 3 can only be used for audio if the rework described
+     * in the User's Guide has been performed.
+     */
+    switch( device) {
+	case DMA_Audio_Out:
+	    dma = &dma_chan[2];
+	    regs = dma->regs;
+
+	    dma->direction = DMA_OUT;
+
+	    regs->destLow = (u32)cpldAudioAddr & 0xffff;
+	    regs->destHi  = ((u32)cpldAudioAddr >> 16) & 0xffff;
+	    regs->control = DMAC_CTRL_SOINC | 
+			    DMAC_CTRL_SOSIZE_4BYTE |
+			    DMAC_CTRL_DESIZE_4BYTE |
+			    DMAC_CTRL_SOBURST_SINGLE |
+			    DMAC_CTRL_ADDR_MODE_WRAP |
+			    DMAC_CTRL_PERIPH_DEST;
+	    break;
+
+	case DMA_Audio_In:
+	    dma = &dma_chan[3];
+	    regs = dma->regs;
+
+	    dma->direction = DMA_IN;
+
+	    regs->srcLow = (u32)cpldAudioAddr & 0xffff;
+	    regs->srcHi  = ((u32)cpldAudioAddr >> 16) & 0xffff;
+	    regs->control = DMAC_CTRL_SOINC | 
+			    DMAC_CTRL_SOSIZE_4BYTE |
+			    DMAC_CTRL_DESIZE_4BYTE |
+			    DMAC_CTRL_SOBURST_SINGLE |
+			    DMAC_CTRL_ADDR_MODE_WRAP |
+			    DMAC_CTRL_PERIPH_SOURCE;
+	    break;
+
+	case DMA_SSP_Rx:	/* not supported */
+	case DMA_SSP_Tx:	/* not supported */
+	default:
+	    err = -ENOSR;
+	    break;
+    }
+
+    if (!err) {
+       if (dma)
+	   dma->in_use = 1;
+       else
+	   err = -ENOSR;
+    }
+    spin_unlock(&dma_list_lock);
+    if (err)
+	return err;
+
+    err = request_irq(dma->irq, dma_irq_handler, SA_INTERRUPT,
+		      device_id, (void *) dma);
+    if (err) {
+	printk(KERN_ERR
+	       "%s: unable to request IRQ %d for DMA channel.  error=0x%x\n",
+	       device_id, dma->irq, err);
+	return err;
+    }
+
+    *channel = dma - dma_chan;
+    dma->device_id = device_id;
+    dma->device = device;
+    dma->callback = NULL;
+    dma->spin_size = 0;
+
+    regs = dma->regs;
+
+    DPRINTK( "channel=%d  regs=0x%x\n", *channel, (u32)regs);
+    DPRINTK("requested\n");
+
+    return 0;
+}
+
+
+int lh79520_dma_set_callback(dmach_t channel, dma_callback_t cb)
+{
+    lh79520_dma_t *dma = &dma_chan[channel];
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    dma->callback = cb;
+    DPRINTK("cb = %p\n", cb);
+    return 0;
+}
+
+
+int lh79520_dma_set_spin(dmach_t channel, dma_addr_t addr, int size)
+{
+    lh79520_dma_t *dma = &dma_chan[channel];
+    int flags;
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    DPRINTK("set spin %d at %#x\n", size, addr);
+    local_irq_save(flags);
+    dma->spin_addr = addr;
+    dma->spin_size = size;
+    if (size)
+	process_dma(dma);
+
+    local_irq_restore(flags);
+    return 0;
+}
+
+
+int lh79520_dma_queue_buffer(dmach_t channel, void *buf_id,
+			    dma_addr_t data, int size)
+{
+    lh79520_dma_t *dma;
+    dma_buf_t *buf;
+    int flags;
+
+    dma = &dma_chan[channel];
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
+    if (!buf)
+	return -ENOMEM;
+
+    buf->next = NULL;
+    buf->ref = 0;
+    buf->dma_ptr = buf->dma_start = data;
+    buf->size = size;
+    buf->id = buf_id;
+
+    local_irq_save(flags);
+
+    DPRINTK("queueing bid=%#x a=%#x s=%d\n", (int) buf_id, data, size);
+
+    if (dma->head)
+	dma->head->next = buf;
+
+    dma->head = buf;
+    if (!dma->tail)
+	dma->tail = buf;
+
+    process_dma(dma);
+    local_irq_restore(flags);
+
+    return 0;
+}
+
+
+int lh79520_dma_get_current(dmach_t channel, void **buf_id, dma_addr_t *addr)
+{
+    int flags, ret;
+    lh79520_dma_t *dma = &dma_chan[channel];
+    channelRegs_t *regs;
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    regs = dma->regs;
+    local_irq_save(flags);
+    if (dma->curr && dma->spin_ref <= 0) {
+	dma_buf_t *buf = dma->curr;
+
+	/*
+	 * If we got here, that's because there is, or recently was, a
+	 * buffer being processed. Two possibilities: either we are
+	 * in the middle of a buffer, or the DMA controller just
+	 * switched to the next toggle but the interrupt hasn't been
+	 * serviced yet.  The former case is straight forward.  In
+	 * the later case, we'll do like if DMA is just at the end
+	 * of the previous toggle since all registers haven't been
+	 * reset yet.  This goes around the edge case and since we're
+	 * always a little behind anyways it shouldn't make a big
+	 * difference.  If DMA has been stopped prior calling this
+	 * then the position is always exact.
+	 */
+	if (buf_id)
+		*buf_id = buf->id;
+
+	if( dma->direction == DMA_IN)
+	    *addr = (regs->currDstHi << 16 ) | (regs->currDstLow);
+	else
+	    *addr = (regs->currSrcHi << 16 ) | (regs->currSrcLow);
+
+	/*
+	 * Clamp funky pointers sometimes returned by the hardware
+	 * on completed DMA transfers
+	 */
+	if (*addr < buf->dma_start ||
+	    *addr > buf->dma_ptr)
+		*addr = buf->dma_ptr;
+	DPRINTK("curr_pos: b=%#x a=%#x\n", (int)dma->curr->id, *addr);
+	ret = 0;
+    } else if (dma->tail && dma->stopped) {
+	dma_buf_t *buf = dma->tail;
+	if (buf_id)
+		*buf_id = buf->id;
+	*addr = buf->dma_ptr;
+	ret = 0;
+    } else {
+	if (buf_id)
+		*buf_id = NULL;
+	*addr = 0;
+	ret = -ENXIO;
+    }
+    local_irq_restore(flags);
+    return ret;
+}
+
+
+int lh79520_dma_stop(dmach_t channel)
+{
+    dmaRegs_t     *dmaRegs = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    lh79520_dma_t *dma = &dma_chan[channel];
+    int flags;
+
+    DPRINTK( "lh79520_dma_stop channel=%d\n", channel);
+
+    if (dma->stopped)
+	return 0;
+
+    local_irq_save(flags);
+    dma->stopped = 1;
+
+    /*
+     * Stop DMA and tweak state variables so everything could restart
+     * from there when resume/wakeup occurs.
+     */
+    dma->regs->control &= ~DMAC_CTRL_ENABLE;
+    dmaRegs->mask &= ~((DMAC_INT0 << channel) | (DMAC_ERRINT0 << channel));
+    
+    if (dma->curr) {
+	dma_buf_t *buf = dma->curr;
+	if (dma->spin_ref <= 0) {
+	    dma_addr_t curpos;
+	    lh79520_dma_get_current(channel, NULL, &curpos);
+	    buf->size += buf->dma_ptr - curpos;
+	    buf->dma_ptr = curpos;
+	}
+	buf->ref = 0;
+	dma->tail = buf;
+	dma->curr = NULL;
+    }
+    dma->spin_ref = 0;
+    process_dma(dma);
+    local_irq_restore(flags);
+    return 0;
+}
+
+
+int lh79520_dma_resume(dmach_t channel)
+{
+    lh79520_dma_t *dma = &dma_chan[channel];
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    if (dma->stopped) {
+	int flags;
+	save_flags_cli(flags);
+	dma->stopped = 0;
+	dma->spin_ref = 0;
+	process_dma(dma);
+	restore_flags(flags);
+    }
+    return 0;
+}
+
+
+int lh79520_dma_flush_all(dmach_t channel)
+{
+    dmaRegs_t     *dmaRegs = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    lh79520_dma_t *dma = &dma_chan[channel];
+    dma_buf_t *buf, *next_buf;
+    int flags;
+
+    DPRINTK("dma_flush_all channel=%d\n", channel);
+    DUMPQ(dma);
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    local_irq_save(flags);
+
+    /*
+     * Disable the channel, and mask off its interrupts
+     */
+    dma->regs->control &= ~(DMAC_CTRL_ENABLE);
+    dmaRegs->mask &= ~((DMAC_INT0 << channel) | (DMAC_ERRINT0 << channel));
+
+    buf = dma->curr;
+    if (!buf)
+	buf = dma->tail;
+
+    dma->head = dma->tail = dma->curr = NULL;
+    dma->stopped = 0;
+    dma->spin_ref = 0;
+    process_dma(dma);
+    local_irq_restore(flags);
+
+    while (buf) {
+	next_buf = buf->next;
+	kfree(buf);
+	buf = next_buf;
+    }
+    DPRINTK("flushed\n");
+    return 0;
+}
+
+
+void lh79520_free_dma(dmach_t channel)
+{
+    lh79520_dma_t *dma;
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS)
+	return;
+
+    dma = &dma_chan[channel];
+    if (!dma->in_use) {
+	printk(KERN_ERR "Trying to free free DMA%d\n", channel);
+	return;
+    }
+
+    lh79520_dma_set_spin(channel, 0, 0);
+    lh79520_dma_flush_all(channel);
+
+    free_irq(dma->irq, (void *) dma);
+    dma->in_use = 0;
+
+    DPRINTK("freed\n");
+}
+
+
+EXPORT_SYMBOL(lh79520_request_dma);
+EXPORT_SYMBOL(lh79520_dma_set_callback);
+EXPORT_SYMBOL(lh79520_dma_set_spin);
+EXPORT_SYMBOL(lh79520_dma_queue_buffer);
+EXPORT_SYMBOL(lh79520_dma_get_current);
+EXPORT_SYMBOL(lh79520_dma_stop);
+EXPORT_SYMBOL(lh79520_dma_resume);
+EXPORT_SYMBOL(lh79520_dma_flush_all);
+EXPORT_SYMBOL(lh79520_free_dma);
+
+
+#ifdef CONFIG_PM
+/* Drivers should call this from their PM callback function */
+
+int lh79520_dma_sleep(dmach_t channel)
+{
+    dmaRegs_t     *dmaRegs = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    lh79520_dma_t *dma = &dma_chan[channel];
+    int orig_state;
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    orig_state = dma->stopped;
+    lh79520_dma_stop(channel);
+    dma->regs->control &= ~DMAC_CTRL_ENABLE;
+    dmaRegs->mask &= ~((DMAC_INT0 << channel) | (DMAC_ERRINT0 << channel));
+
+    dma->stopped = orig_state;
+    dma->spin_ref = 0;
+    return 0;
+}
+
+int lh79520_dma_wakeup(dmach_t channel)
+{
+    dmaRegs_t     *dmaRegs = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    lh79520_dma_t *dma = &dma_chan[channel];
+    int flags;
+
+    if ((unsigned)channel >= LH79520_DMA_CHANNELS || !dma->in_use)
+	return -EINVAL;
+
+    dma->regs->control &= ~DMAC_CTRL_ENABLE;
+    dmaRegs->mask &= ~((DMAC_INT0 << channel) | (DMAC_ERRINT0 << channel));
+
+    local_irq_save(flags);
+    process_dma(dma);
+    local_irq_restore(flags);
+
+    return 0;
+}
+
+EXPORT_SYMBOL(lh79520_dma_sleep);
+EXPORT_SYMBOL(lh79520_dma_wakeup);
+
+#endif /* CONFIG_PM */
+
+
+static int __init lh79520_init_dma(void)
+{
+    int channel;
+    dmaRegs_t *dmaRegs  = (dmaRegs_t *)IO_ADDRESS(DMAC_PHYS);
+    ioconRegs_t *ioconRegs = (ioconRegs_t *)IO_ADDRESS( IOCON_PHYS);
+    channelRegs_t *regs;
+
+#ifdef DEBUG
+    printk( __FUNCTION__ "\n");
+#endif
+
+    dmaRegs->clear = DMAC_CLEAR_ALL;
+    dmaRegs->mask  = 0;
+
+    for (channel = 0; channel < LH79520_DMA_CHANNELS; channel++) {
+	dma_chan[channel].regs = regs = streamRegs[channel];
+
+	regs->control = 0;
+	regs->count   = 0;
+	regs->srcHi   = 0;
+	regs->srcLow  = 0;
+	regs->destHi  = 0;
+	regs->destLow = 0;
+
+	dma_chan[channel].irq = IRQ_DMA;
+	dma_chan[channel].channel = channel;
+
+#ifdef DEBUG
+	printk( "dma channel %d at 0x%x\n", channel, (u32)regs);
+#endif
+    }
+
+    /* assign pins to DMA stream 2 */
+    ioconRegs->DMAMux |= (DMAMUX_DCDEOT0 | DMAMUX_DCDREQ0) ;
+
+    /* assign pins to DMA Stream 3 */
+    // These two lines interfere with PWM Audio
+    // ioconRegs->MiscMux |= MISCMUX_DCDEOT1;
+    // ioconRegs->MiscMux &= ~MISCMUX_RCEII5;
+
+    return 0;
+}
+
+__initcall(lh79520_init_dma);
diff -urN linux-2.4.26/arch/arm/mach-lh79520/dma.h linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/dma.h
--- linux-2.4.26/arch/arm/mach-lh79520/dma.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/dma.h	2005-11-02 17:38:44.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-lh79520/dma.h
+ * Copyright (C) 2002 Embedix, Inc.
+ *
+ * Based on arch/arm/mach-sa1100/dma.h which is
+ * (C) 2000 Nicolas Pitre <nico@cam.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.
+ */
+
+#include <linux/config.h>
+
+/*
+ * DMA buffer structure
+ */
+
+typedef struct dma_buf_s {
+	int size;		/* buffer size */
+	dma_addr_t dma_start;	/* starting DMA address */
+	dma_addr_t dma_ptr;	/* next DMA pointer to use */
+	int ref;		/* number of DMA references */
+	void *id;		/* to identify buffer from outside */
+	struct dma_buf_s *next;	/* next buffer to process */
+} dma_buf_t;
+
+typedef enum {
+    DMA_OUT,
+    DMA_IN
+} dma_direction_t;
+
+/*
+ * DMA channel structure.
+ */
+typedef struct {
+	unsigned int	in_use;		/* Device is allocated */
+	const char 	*device_id;	/* Device name */
+	dma_device_t	device;		/* ... to which this channel is attached */
+	dma_buf_t	*head;		/* where to insert buffers */
+	dma_buf_t	*tail;		/* where to remove buffers */
+	dma_buf_t	*curr;		/* buffer currently DMA'ed */
+	int 		stopped;	/* 1 if DMA is stalled */
+	channelRegs_t	*regs;		/* points to appropriate DMA registers */
+	int		irq;		/* IRQ used by the channel */
+	dma_callback_t	callback;	/* ... to call when buffers are done */
+	int		spin_size;	/* > 0 when DMA should spin when no more buffer */
+	dma_addr_t	spin_addr;	/* DMA address to spin onto */
+	int		spin_ref;	/* number of spinning references */
+	int		channel;	/* channel number */
+	dma_direction_t	direction;	/* DMA direction: 0=Out / 1=In	*/
+} lh79520_dma_t;
+
+extern lh79520_dma_t dma_chan[LH79520_DMA_CHANNELS];
+
+
+void lh79520_dma_done( lh79520_dma_t *dma);
+
+
+
+
diff -urN linux-2.4.26/arch/arm/mach-lh79520/generic.c linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/generic.c
--- linux-2.4.26/arch/arm/mach-lh79520/generic.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/generic.c	2005-11-02 17:38:09.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ *  linux/arch/arm/mach-lh79520/generic.c
+ *
+ *  Common code for all LH79520 based machines.
+ *
+ *  Copyright (C) 2001 Lineo, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/arch/rcpc.h>
+
+
+/*
+ * return the CPU clock frequency (FCLK) in Hz.
+ */
+unsigned int
+cpufreq_get( int cpu)
+{
+	int	divider;
+	rcpcRegs_t *RCPC = (rcpcRegs_t *)IO_ADDRESS(RCPC_PHYS);
+
+	divider = RCPC->CpuClkPrescale * 2;
+	if( divider == 0)
+		divider = 1;
+	return PLL_CLOCK / divider;;
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+
+/*
+ * return the bus clock frequency (HCLK) in Hz.
+ */
+unsigned int
+hclkfreq_get( void)
+{
+	int	divider;
+	rcpcRegs_t *RCPC = (rcpcRegs_t *)IO_ADDRESS(RCPC_PHYS);
+
+	divider = RCPC->HCLKPrescale * 2;	/* HCLK prescale value			*/
+
+	if( divider == 0)					/* no prescalar == divide by 1	*/
+		divider = 1;
+
+	return PLL_CLOCK / divider;
+}
+
+
diff -urN linux-2.4.26/arch/arm/mach-lh79520/generic.h linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/generic.h
--- linux-2.4.26/arch/arm/mach-lh79520/generic.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/generic.h	2005-11-02 17:38:09.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ *  linux/arch/arm/mach-lh79520/generic.h
+ *
+ *  Common code for all LH79520 based machines.
+ *
+ *  Copyright (C) 2001 Lineo, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+unsigned int cpufreq_get( int cpu);
+unsigned int hclkfreq_get( void);
diff -urN linux-2.4.26/arch/arm/mach-lh79520/Makefile linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/Makefile
--- linux-2.4.26/arch/arm/mach-lh79520/Makefile	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/Makefile	2005-11-02 17:38:09.000000000 -0400
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= lh79520.o
+
+# Object file lists.
+
+obj-y			:= arch.o mm.o generic.o dma.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= generic.o dma.o
+
+# obj-$(CONFIG_LEDS)	+= leds.o
+# obj-$(CONFIG_PCI)	+= pci_v3.o pci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.26/arch/arm/mach-lh79520/mm.c linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/mm.c
--- linux-2.4.26/arch/arm/mach-lh79520/mm.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/mach-lh79520/mm.c	2005-11-02 17:38:09.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ *  linux/arch/arm/mach-lh79520/mm.c
+ *
+ *  Copyright (C) 2001 Lineo, Inc.
+ *
+ * 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/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include <asm/mach/map.h>
+
+static struct map_desc lh79520_io_desc[] __initdata = {
+	/* virt           phys              size                     r  w  c  b    */
+	{ FLASH_BASE,    FLASH_START,     FLASH_SIZE,     DOMAIN_IO, 0, 1, 0, 0 },
+	{ CPLD_BASE,     CPLD_START,      CPLD_SIZE,      DOMAIN_IO, 0, 1, 0, 0 },
+	{ CS8900_BASE,   CS8900_START,    CS8900_SIZE,    DOMAIN_IO, 0, 1, 0, 0 },
+	{ IDE_BASE,      IDE_START,       IDE_SIZE,       DOMAIN_IO, 0, 1, 0, 0 },
+	{ IDE2_BASE,     IDE2_START,      IDE2_SIZE,      DOMAIN_IO, 0, 1, 0, 0 },
+	{ INT_SRAM_BASE, INT_SRAM_START,  INT_SRAM_SIZE,  DOMAIN_IO, 0, 1, 0, 0 },
+	{ APB_BASE,      APB_START,       APB_SIZE,       DOMAIN_IO, 0, 1, 0, 0 },
+	{ AHB_BASE,      AHB_START,       AHB_SIZE,       DOMAIN_IO, 0, 1, 0, 0 },
+	{ VIC_BASE,      VIC_START,       VIC_SIZE,       DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+void __init lh79520_map_io(void)
+{
+	iotable_init( lh79520_io_desc);
+}
+
diff -urN linux-2.4.26/arch/arm/Makefile linux-2.4.26-vrs1-lnode80/arch/arm/Makefile
--- linux-2.4.26/arch/arm/Makefile	2005-11-02 16:54:16.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/Makefile	2005-11-02 17:37:31.000000000 -0400
@@ -160,6 +160,16 @@
 MACHINE		 = anakin
 endif
 
+ifeq ($(CONFIG_ARCH_LH79520),y)
+# C0008000 is the default, so not needed -- DDD
+# DDD TEXTADDR         = 0xC0008000
+MACHINE                = lh79520
+endif
+
+ifeq ($(CONFIG_ARCH_LH7A400),y)
+MACHINE                = lh7a400
+endif
+
 ifeq ($(CONFIG_ARCH_OMAHA),y)
 MACHINE                = omaha
 endif
diff -urN linux-2.4.26/arch/arm/tools/mach-types linux-2.4.26-vrs1-lnode80/arch/arm/tools/mach-types
--- linux-2.4.26/arch/arm/tools/mach-types	2005-11-02 16:54:18.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/arch/arm/tools/mach-types	2005-11-02 17:37:31.000000000 -0400
@@ -525,3 +525,5 @@
 omap_osk		MACH_OMAP_OSK		OMAP_OSK		515
 rg100v3			MACH_RG100V3		RG100V3			516
 mx2ads			MACH_MX2ADS		MX2ADS			517
+lh79520evb              LH79520_EVB             LH79520EVB              999
+lh7a400evb            	LH7A400_EVB             LH7A400EVB              998
diff -urN linux-2.4.26/Documentation/Configure.help linux-2.4.26-vrs1-lnode80/Documentation/Configure.help
--- linux-2.4.26/Documentation/Configure.help	2005-11-02 16:54:16.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/Documentation/Configure.help	2005-11-02 17:37:31.000000000 -0400
@@ -25531,6 +25531,136 @@
   a debugging option; you probably do not want to set it unless you
   are an S390 port maintainer.
 
+Sharp LH79520 based bords
+CONFIG_ARCH_LH79520
+  Say Y here to support the Sharp LH79520 System on Chip.
+
+Sharp LH79520 Evaluation Board (Isis)
+CONFIG_LH79520_EVB
+  Say Y here to support the Sharp LH79520 Evaluation Board.
+
+Sharp LH79520 Watchdog Timer
+CONFIG_LH79520_WATCHDOG
+  Say Y here to include support for the LH79520 watchdog timer.
+  The watchdog timer will reboot your system when the timeout is reached.
+  Note that once enabled, this timer cannot be disabled.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The module will be called lh79520_wdt.o.
+
+  If unsure, say N.
+
+Sharp LH79520 PWM controller
+CONFIG_LH79520_PWM
+  Say Y here to include support for the PWM device.
+  PWM0 is for the LCD backlight intensity, and
+  PWM1 is for audio.  The major number is dynamically assigned unless
+  module parameter is provided.  Device nodes must exist to control
+  the ioctls.
+  /dev/pwm0 c 254 0
+  /dev/pwm1 c 254 1
+  254 may or may not be the major number for your driver.
+  Check /proc/devices for major number of pwm520.
+
+  If unsure, say N.
+
+Sharp LH79520 7-segment display
+CONFIG_7SEGMENT_LH79520
+  Say Y here to include support for the LH79520 7-segment display.
+
+  If unsure, say N.
+
+Sharp LH79520 Touchscreen
+CONFIG_TOUCHSCREEN_LH79520
+  Say Y here to include support for the LH79520 touchscreen.
+
+  If unsure, say N.
+
+Sharp LH79520 LCD EEPROM
+CONFIG_EEPROM_LH79520
+  Say Y here to include support for the EEPROM on the LCD
+  board on the Sharp LH79520 EVB.
+
+  If unsure, say N.
+
+ARM PrimeCell PL011 UART
+CONFIG_SERIAL_AMBA_PL011
+  Say Y here to include support for the ARM PrimeCell PL011 UART.
+
+  If unsure, say N.
+
+Console on ARM PL011 UART
+CONFIG_SERIAL_AMBA_PL011_CONSOLE
+  Say Y here to support a serial console on an ARM PrimeCell PL011 UART.
+
+  If unsure, say N.
+
+ARM PrimeCell PL110 LCD Controller
+CONFIG_FB_PL110
+  Say Y here to include support the ARM PrimeCell PL110
+  LCD controller.
+
+  If unsure, say N.
+
+Sharp LQ039Q2DS53-HR-TFT LCD panel
+CONFIG_PL110_LQ39
+  Say Y here to if you've got a Sharp LQ039Q2DS53-HR-TFT
+  LCD panel connected to an ARM PL110 LCD controller.
+
+  If unsure, say N.
+
+Sharp LM057QCTT03-QVGA-STN LCD panel
+CONFIG_PL110_LM57
+  Say Y here to if you've got a Sharp LM057QCTT03-QVGA-STN
+  LCD panel connected to an ARM PL110 LCD controller.
+
+  If unsure, say N.
+
+Sharp LQ057Q3DC02-VGA/QVGA-TFT LCD panel
+CONFIG_PL110_LQ57
+  Say Y here to if you've got a Sharp LQ057Q3DC02-VGA/QVGA-TFT
+  LCD panel connected to an ARM PL110 LCD controller.
+
+  If unsure, say N
+
+Sharp LQ121S1DG31-800x600-TFT LCD panel
+CONFIG_PL110_LQ121
+  Say Y here to if you've got a Sharp LQ121S1DG31-800x600-TFT
+  LCD panel connected to an ARM PL110 LCD controller.
+
+  If unsure, say N
+
+Sharp LQ104V1DG11-640x480-TFT LCD panel
+CONFIG_PL110_LQ104
+  Say Y here to if you've got a Sharp LQ104V1DG11-640x480-TFT
+  LCD panel connected to an ARM PL110 LCD controller.
+
+  If unsure, say N
+
+Sharp LH7A400 based bords
+CONFIG_ARCH_LH7A400
+  Say Y here to support the Sharp LH7A400 System on Chip.
+
+Sharp LH7A400 Evaluation Board (Aruba)
+CONFIG_LH7A400_EVB
+  Say Y here to support the Sharp LH7A400 SoC Evaluation Board.
+
+Sharp LH7A400 UART
+CONFIG_SERIAL_LH7A400
+  Say Y here to include support for the UART on the Sharp
+  LH7A400 SoC.
+
+  If unsure, say N.
+
+Console on a Sharp LH7A400 Serial port
+CONFIG_SERIAL_LH7A400_CONSOLE
+  Say Y here to support a serial console on the
+  Sharp LH7A400 SoC Serial port.
+
+  If unsure, say N.
+
 #
 # ARM options
 #
diff -urN linux-2.4.26/drivers/char/Config.in linux-2.4.26-vrs1-lnode80/drivers/char/Config.in
--- linux-2.4.26/drivers/char/Config.in	2005-11-02 16:54:20.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/Config.in	2005-11-02 17:37:31.000000000 -0400
@@ -253,6 +253,7 @@
       dep_tristate '  DC21285 watchdog' CONFIG_21285_WATCHDOG $CONFIG_FOOTBRIDGE
       dep_tristate '  NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG $CONFIG_ARCH_NETWINDER
       dep_tristate '  SA1100 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_SA1100
+      dep_tristate '  Sharp LH79520 watchdog' CONFIG_LH79520_WATCHDOG $CONFIG_ARCH_LH79520
       dep_tristate '  EPXA watchdog' CONFIG_EPXA_WATCHDOG $CONFIG_ARCH_CAMELOT
       dep_tristate '  Omaha watchdog' CONFIG_OMAHA_WATCHDOG $CONFIG_ARCH_OMAHA
       dep_tristate '  AT91RM9200 watchdog' CONFIG_AT91_WATCHDOG $CONFIG_ARCH_AT91RM9200
@@ -304,6 +305,11 @@
 if [ "$CONFIG_X86" = "y" -o "$CONFIG_X86_64" = "y" ]; then
    dep_tristate 'AMD 768/8111 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI
 fi
+
+if [ "$CONFIG_ARCH_LH79520" = "y" ]; then
+      tristate 'LH79520 PWM support' CONFIG_LH79520_PWM
+fi
+
 if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then
    dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI
 fi
diff -urN linux-2.4.26/drivers/char/console.c linux-2.4.26-vrs1-lnode80/drivers/char/console.c
--- linux-2.4.26/drivers/char/console.c	2005-11-02 16:54:20.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/console.c	2005-11-02 17:37:31.000000000 -0400
@@ -169,7 +169,7 @@
 int console_blanked;
 
 static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
-static int blankinterval = 10*60*HZ;
+static int blankinterval = 0; // 10*60*HZ;
 static int vesa_off_interval;
 
 static struct tq_struct console_callback_tq = {
diff -urN linux-2.4.26/drivers/char/cradle.c linux-2.4.26-vrs1-lnode80/drivers/char/cradle.c
--- linux-2.4.26/drivers/char/cradle.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/cradle.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,486 @@
+/*
+**  cradle.c
+**
+**  Device driver for the cradle interface on the Touchblock device.
+**
+**  Copyright (C) 2002  The PTR Group, Inc. <www.theptrgroup.com>
+**
+**  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/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/arch/iocon.h>
+#include <asm/arch/gpio.h>
+#include <asm/hardware/cradle.h>
+
+static ssize_t cradle_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
+static int cradle_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+static int cradle_open(struct inode *inode, struct file *filp);
+static int cradle_release(struct inode *inode, struct file *filp);
+static int cradle_fasync(int fd, struct file *filp, int mode );
+static unsigned int cradle_poll(struct file *filp, poll_table *wait);
+
+
+static char read_docking_state(void);
+static inline void cradle_update_buffer(volatile char **index, int delta, char *buf, int size);
+
+#if 0
+void cradle_do_tasklet_docked(unsigned long data);
+DECLARE_TASKLET( cradle_tasklet_docked, cradle_do_tasklet_docked,0);
+void cradle_do_tasklet_undocked(unsigned long data);
+DECLARE_TASKLET( cradle_tasklet_undocked, cradle_do_tasklet_undocked,0);
+#endif
+
+//#define min(a,b) (((a)<(b))?(a):(b))
+
+#define CRADLE_IBUF_SIZE  2  
+
+typedef struct
+{
+	int users;
+	int ready;
+	volatile char *ibuf_wp;
+	volatile char *ibuf_rp;
+	char *ibuf;
+	wait_queue_head_t wait_inq;
+	struct fasync_struct *fasync; /* asynchronous readers */
+} cradle_dev_t;
+
+static cradle_dev_t cradle_dev;
+
+struct file_operations cradle_fops = {
+//	NULL, // seek
+read:		cradle_read, // read
+//	NULL, // write
+//	NULL, // readdir
+poll:		cradle_poll, // poll/select
+ioctl:		cradle_ioctl, // ioctl
+//	NULL, // mmap
+open:		cradle_open, // open
+//	NULL, // flush
+release:	cradle_release, // release
+//	NULL, // fsync
+fasync:		cradle_fasync, // fasync
+};
+
+/************************************************************************
+** Read the docking state from the hardware
+************************************************************************/
+static char read_docking_state(void)
+{
+    
+	return( (GPIOG->dr & 0x10)  ? CRADLE_UNDOCKED_STATE : CRADLE_DOCKED_STATE );
+}
+
+/************************************************************************
+** Manipulate the buffer pointers safely without using locks
+************************************************************************/
+static inline void cradle_update_buffer(volatile char **index, int delta, char *buf, int size)
+{
+	volatile char *new = *index + delta;
+	barrier();
+	*index=(new >= (buf+size)) ? buf : new;
+}
+
+
+#if 0
+/************************************************************************
+** Enable the interrupt(s) associated with the cradle
+************************************************************************/
+static void cradle_enable_interrupt(void)
+{
+	/* printk(KERN_INFO "cradle: interrupts enabled\n"); */
+}
+
+/************************************************************************
+** Disable the interrupt(s) associated with the cradle
+************************************************************************/
+static void cradle_disable_interrupt(void)
+{
+	/* printk(KERN_INFO "cradle: interrupts disabled\n"); */
+}
+
+/************************************************************************
+**
+************************************************************************/
+static void cradle_docked_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	cradle_dev_t *dev=dev_id;
+
+   	/* printk(KERN_INFO "cradle: docked irq\n"); */
+
+	/* Reset the interrupt request */
+
+	/* Get the state */
+	*dev->ibuf_wp=read_docking_state();
+	cradle_update_buffer(&dev->ibuf_wp, 1, dev->ibuf, CRADLE_IBUF_SIZE);
+
+	/* Notify any asynchronous readers */
+	if( dev->fasync )
+	{
+		/* printk(KERN_INFO "cradle: kill_fasync()\n"); */
+		kill_fasync(dev->fasync, SIGIO, POLL_IN);
+	}
+
+	wake_up_interruptible( &dev->wait_inq );
+
+	/* Schedule the bottom-half */
+	/* tasklet_schedule(&cradle_tasklet_docked); */
+}
+
+/************************************************************************
+**
+************************************************************************/
+static void cradle_undocked_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	cradle_dev_t *dev=dev_id;
+
+	/* printk(KERN_INFO "cradle: undocked irq\n"); */
+
+	/* Reset the interrupt request */
+
+	/* Get the state */
+	*dev->ibuf_wp=read_docking_state();
+	cradle_update_buffer(&dev->ibuf_wp, 1, dev->ibuf, CRADLE_IBUF_SIZE);
+
+	/* Notify any asynchronous readers */
+	if( dev->fasync )
+	{
+		/* printk(KERN_INFO "cradle: kill_fasync()\n"); */
+		kill_fasync(dev->fasync, SIGIO, POLL_IN);
+	}
+
+	wake_up_interruptible( &dev->wait_inq );
+
+	/* Schedule the bottom-half */
+	/* tasklet_schedule(&cradle_tasklet_undocked); */
+}
+
+/*************************************************************************
+** Bottom-half processing
+*************************************************************************/
+void cradle_do_tasklet_docked(unsigned long data)
+{
+   	printk(KERN_INFO "cradle: tasklet\n");
+}
+
+
+/*************************************************************************
+** Bottom-half processing
+*************************************************************************/
+void cradle_do_tasklet_undocked(unsigned long data)
+{
+   	printk(KERN_INFO "cradle: tasklet undocked\n");
+}
+#endif
+
+/************************************************************************
+** Open the cradle device
+************************************************************************/
+static int cradle_open(struct inode *inode, struct file *filp)
+{
+	cradle_dev_t  *dev;
+	int status;
+
+	/* printk(KERN_INFO "cradle: open()\n"); */
+
+	/* Initialize the device information */
+	dev=(cradle_dev_t *)filp->private_data;
+	if(!dev)
+	{
+		dev=&cradle_dev;
+		filp->private_data=dev;
+	}
+
+	if( dev->users++ ) return 0;
+
+	MOD_INC_USE_COUNT;
+
+	/* allocate the buffers */
+	dev->ibuf=(char *)kmalloc(CRADLE_IBUF_SIZE,GFP_KERNEL);
+	if( !dev->ibuf )
+	{
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+
+	/* clear the buffers */
+	dev->ibuf_wp=dev->ibuf_rp=dev->ibuf;
+
+	/* mark the device ready */
+	dev->ready=1;
+	
+	/* Install the interrupt handler(s) */
+
+	/* Enable the interrupts */
+	//cradle_enable_interrupt();
+
+
+	return 0;
+}
+
+/************************************************************************
+** Release the cradle device
+************************************************************************/
+static int cradle_release(struct inode *inode, struct file *filp)
+{
+
+	cradle_dev_t  *dev=(cradle_dev_t *)filp->private_data;
+
+	/* printk(KERN_INFO "cradle: release\n"); */
+
+	if( --dev->users ) return 0;
+
+	//cradle_disable_interrupt();
+
+	//free the irq
+	
+	/* release any asynchronous readers */
+	cradle_fasync(-1,filp,0);
+
+	/* free up resources */
+	kfree(dev->ibuf);
+
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+/************************************************************************
+** Read the cradle device
+**
+** This implementation supports both non-blocking and blocking i/o.
+************************************************************************/
+static ssize_t cradle_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+	cradle_dev_t  *dev=(cradle_dev_t *)filp->private_data;
+	wait_queue_t wait;
+
+	/* printk(KERN_INFO "cradle: read()\n"); */
+
+	/* unseekable device */
+	if( f_pos!=&filp->f_pos ) 
+		return -ESPIPE;
+
+	/* 
+	** safe implementation of sleeping that avoids race conditions
+	*/
+
+	/* init our local wait queue */
+	init_waitqueue_entry(&wait, current);
+	
+	/* add out queue to the drivers queue */
+	add_wait_queue(&dev->wait_inq, &wait);
+
+	while( 1 )
+	{
+		/* tell the schedule we are asleep (even though we aren't yet) */
+		set_current_state(TASK_INTERRUPTIBLE);
+		
+		/* check for available data */
+		if( dev->ibuf_wp != dev->ibuf_rp )
+		{
+			break;
+		}
+
+		if( filp->f_flags & O_NONBLOCK )
+		{
+			remove_wait_queue(&dev->wait_inq, &wait);
+			set_current_state(TASK_RUNNING);
+			return -EAGAIN;
+			/* return -EWOULDBLOCK; */
+		}
+
+		/* check to see if it is a signal */
+		if( signal_pending(current)) 
+		{
+			remove_wait_queue(&dev->wait_inq, &wait);
+			set_current_state(TASK_RUNNING);
+			return -ERESTARTSYS;
+		}
+
+		/* allow other processes to run (we'll go to sleep) */
+		schedule();
+	}
+
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&dev->wait_inq, &wait);
+
+	/* calculate how much data is available */
+	if( dev->ibuf_wp > dev->ibuf_rp )
+		count=min(count, dev->ibuf_wp - dev->ibuf_rp );
+	else
+		count=min(count, (dev->ibuf+CRADLE_IBUF_SIZE) - dev->ibuf_rp );
+
+	/* printk("cradle: read() %d available\n", count); */
+
+	/* copy the data to user space */
+	if( copy_to_user(buf, dev->ibuf_rp, count) )
+	{
+		return -EFAULT;
+	}
+
+	/* manager the buffer pointers */
+	cradle_update_buffer(&dev->ibuf_rp, count, dev->ibuf, CRADLE_IBUF_SIZE);
+
+
+	return count;
+}
+
+/************************************************************************
+** Poll/select the cradle device
+************************************************************************/
+static unsigned int cradle_poll(struct file *filp, poll_table *wait)
+{
+	cradle_dev_t *dev=filp->private_data;
+	unsigned int mask=0;
+
+	poll_wait(filp, &dev->wait_inq, wait);
+
+	/* check for readable */
+	if( dev->ibuf_wp != dev->ibuf_rp )
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+/************************************************************************
+** IOCTL interface for the cradle device
+************************************************************************/
+static int cradle_ioctl(struct inode *inode, struct file *filp,
+						unsigned int cmd, unsigned long arg)
+{
+	int docking_state;
+	int retval=0;
+
+	/* printk(KERN_INFO "cradle: ioct %d\n", cmd); */
+	
+	switch(cmd)
+	{
+	case CRADLE_GET_DOCKING_STATE_IOCTL:
+		docking_state=read_docking_state();
+		//this code is here temporarily until
+		// a timer is added to check the state and set
+		// the LED automatically
+		if(docking_state == CRADLE_DOCKED_STATE)
+		{
+		    // turn on dock led
+		    GPIOF->dr |= 0x40;
+		}
+		else
+		{
+		    // turn off dock led
+		    GPIOF->dr &= ~0x40;
+		}
+		
+		retval=put_user(docking_state, (int *)arg);
+
+		break;
+	default:
+		printk(KERN_INFO "cradle: unknown ioctl %d\n", cmd);
+		retval=-1;
+		break;
+	}
+
+	return retval;
+}
+
+/************************************************************************
+** Aynchronous i/o support for the cradle device
+************************************************************************/
+static int cradle_fasync(int fd, struct file *filp, int on )
+{
+	int retval;
+	cradle_dev_t *dev=filp->private_data;
+
+	/*
+	printk(KERN_INFO "cradle: fasync fd=%d filp=0x%08x mode=%d\n",
+		fd, (unsigned int) filp, on );
+	*/
+
+	retval=fasync_helper(fd, filp, on, &dev->fasync);
+	if( retval < 0 )
+		return retval;
+	else
+		return 0;
+}
+
+/************************************************************************
+** Initialize the cradle interface and the hardware associated with the 
+** cradle.
+**
+** This configuration is specific to the hardware design for the 
+** Touchblock device.  Moreover, this configuration *must* match the 
+** configuration of the MIPS interrupt  handler.
+************************************************************************/
+void cradle_init(void)
+{
+	int retval;
+	int cradle_major = 0;
+
+	/* register the device */
+	retval=register_chrdev( cradle_major, "cradle", &cradle_fops );
+	if( retval < 0 )
+	{
+		printk(KERN_WARNING "cradle: Failed to register device\n");
+	}
+	if (cradle_major == 0) 
+	{
+    	    cradle_major = retval; /* Dynamic Allocation of major number */
+    	    printk("<4>Cradle Dynamic Major Number %d\n",cradle_major);
+	}
+
+
+	/* initialize the device structure */
+	memset( &cradle_dev, 0, sizeof( cradle_dev_t ) );
+	init_waitqueue_head(&cradle_dev.wait_inq);
+	
+
+	/* printk(KERN_INFO "cradle: initalized\n"); */
+}
+
+/************************************************************************
+**
+** Since the cradle device is statically compiled into the kernel this 
+** is not really used. However, when the driver switches to loadable 
+** modules this should be the basis of the
+** module cleanup routine.
+************************************************************************/
+void cradle_cleanup(void)
+{
+	/* unregister the device */
+	unregister_chrdev( CRADLE_MAJOR, "cradle");
+
+
+	/* printk(KERN_INFO "cradle: cleanup\n"); */ 
+}
+
+
+module_init(cradle_init);
+module_exit(cradle_cleanup);
diff -urN linux-2.4.26/drivers/char/lh79520_wdt.c linux-2.4.26-vrs1-lnode80/drivers/char/lh79520_wdt.c
--- linux-2.4.26/drivers/char/lh79520_wdt.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/lh79520_wdt.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,259 @@
+/*
+ *	Watchdog driver for the LH79520
+ *
+ *      (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ *          Based on SoftDog driver by Alan Cox <alan@redhat.com>
+ *
+ *	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.
+ *
+ *	Neither Oleg Drokin nor iXcelerator.com admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
+ *
+ *	(c) Copyright 2000           Oleg Drokin <green@crimea.edu>
+ *
+ *      27/11/2000 Initial release
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/bitops.h>
+
+#include "lh79520_wdt.h"
+
+unsigned int hclkfreq_get( void);
+
+#define TIMER_MARGIN	60	/* default in seconds */
+#ifdef OLDWAY
+#define PCLK		51609600 /* ticks per second of AHB clock, 51MHz */
+#else
+#define PCLK		hclkfreq_get()
+#endif 
+#define SLEEP_TIME	10	/* number of seconds between each counter reload */
+
+static int lh79520_margin = TIMER_MARGIN;	/* in seconds */
+static int lh79520wdt_users;			/* mutex */
+#ifdef FIQ_ENABLED
+static int irq = 0x1c; /* FIQ. Normally 0x18 for standard irq */
+#else
+static int irq = 0x18; /* IRQ. Normally the FIQ is 0x1c */
+#endif
+
+#define WDTBase 0xFFFE3000L	/* Base Address for all LH79520 Watchdog Registers */
+WDTIMERREGS *wtdregs = (WDTIMERREGS *) WDTBase;
+
+#ifdef MODULE
+MODULE_PARM(lh79520_margin,"i");
+#endif
+
+/*
+ *	Allow only one person to hold it open
+ */
+
+static int lh79520dog_open(struct inode *inode, struct file *file)
+{
+	if(test_and_set_bit(1,&lh79520wdt_users))
+		return -EBUSY;
+	MOD_INC_USE_COUNT;
+
+	if ((lh79520_margin > (PCLK / 0xffffffff)) ||  /* 83 seconds max, 20 sec min margin */
+	    (lh79520_margin <= SLEEP_TIME * 2))
+		lh79520_margin = TIMER_MARGIN;
+
+/* setting bits 7-4 of WDCTLR to 0x0 through 0xF sets the *initial* counter value upon a reset */
+/* 0x0 is 2^16 tics of PCLK, or reset immediatly,  0x10 is 2^17 tics of PCLK, ... */
+/* 0xF is 2^31 tics of PCLK, if PCLK is 51 MHz, 2^31 / 51 MHz = 41.6 seconds */
+/* WDCTLR=0xF, the F sets initial counter to 41.6 seconds (assuming PCLK is 51 MHz) */
+/* The counter will be set to the user selected margin the first time a reload occurs */
+	wtdregs->wdctlr |= 0xF0;
+
+	/* Activate LH79520 Watchdog timer */
+	wtdregs->wdctlr |= WDT_CTRL_ENABLE;
+	///wtdregs->wdctlr |= WDT_CTRL_FRZ_ENABLE;
+	// The 1 sets the enable bit (bit 0) to 1 enabling the watchdog fuctionality
+	// The freeze or lock bit (bit 4) makes bit 0 read-only (to avoid accidental disabling)
+	// Bit 1 is left at 0 signifing that when the counter reaches 0, a machine reset occurs
+	// If bit 1 were 1, then the first time the counter reached 0 an interrupt occurs, and
+	// the second time the counter reaches 0 the machine is reset.
+
+	// Now reset Watchdog to let the above settings take effect
+	wtdregs->wdcntr = WDT_WDCNTR;  // 0x1984 is a special reset value
+	return 0;
+}
+
+static int lh79520dog_release(struct inode *inode, struct file *file)
+{
+	/*
+	 *	Shut off the timer.
+	 * 	Lock it in if it's a module and we defined ...NOWAYOUT
+	 */
+	///wtdregs->wdctr |= 0x0;   // turns off bit 4 the freeze lock so we can write to bit 0
+	wtdregs->wdctlr |= WDT_CTRL_DISABLE;   // turns off watchdog bit 0
+
+	lh79520wdt_users = 0;
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static ssize_t lh79520dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	/* Refresh/reload counter */
+	if(len) {
+		unsigned int count = (lh79520_margin * PCLK);
+		wtdregs->wdcnt3 = count && 0xFF000000;
+		wtdregs->wdcnt2 = count && 0x00FF0000;
+		wtdregs->wdcnt1 = count && 0x0000FF00;
+		wtdregs->wdcnt0 = count && 0x000000FF;
+		return 1;
+	}
+	return 0;
+}
+
+static int lh79520dog_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		identity: "LH79520 Watchdog",
+	};
+
+	switch(cmd){
+	default:
+		return -ENOIOCTLCMD;
+	case WDIOC_GETSUPPORT:
+		return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
+	case WDIOC_GETSTATUS:
+		return put_user(0,(int *)arg);
+	case WDIOC_GETBOOTSTATUS: /* 1 = last reboot was cause by watchdog, 0 means no */
+		return put_user( ! (wtdregs->wdtstr & WDT_WD_NWDRES), (int *)arg);
+	case WDIOC_KEEPALIVE:
+		{
+		unsigned int count = (lh79520_margin * PCLK);
+		wtdregs->wdcnt3 = count && 0xFF000000;
+		wtdregs->wdcnt2 = count && 0x00FF0000;
+		wtdregs->wdcnt1 = count && 0x0000FF00;
+		wtdregs->wdcnt0 = count && 0x000000FF;
+		}
+		return 0;
+	}
+}
+
+/**
+ *	lh79520dog_interrupt:
+ *	@irq:		Interrupt number
+ *	@dev_id:	Unused as we don't allow multiple devices.
+ *	@regs:		Unused.
+ *
+ *	Handle an interrupt from the board. These are raised when the status
+ *	map changes in what the board considers an interesting way. That means
+ *	a failure condition occuring.
+ */
+
+void lh79520dog_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/*
+	 *	Read the status register see what is up and
+	 *	then printk it.
+	 */
+	
+	unsigned char status=wtdregs->wdtstr;
+	
+/*	status|=FEATUREMAP1;
+	status&=~FEATUREMAP2;	*/
+	
+	printk(KERN_CRIT "WDT status %d\n", status);
+	
+    wtdregs->wdcntr = WDT_WDCNTR;  // 0x1984 is a special reset value
+/*
+	if(!(status&WDC_SR_TGOOD))
+		printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT));
+	if(!(status&WDC_SR_PSUOVER))
+		printk(KERN_CRIT "PSU over voltage.\n");
+	if(!(status&WDC_SR_PSUUNDR))
+		printk(KERN_CRIT "PSU under voltage.\n");
+	if(!(status&WDC_SR_FANGOOD))
+		printk(KERN_CRIT "Possible fan fault.\n");
+	if(!(status&WDC_SR_WCCR))
+#ifdef SOFTWARE_REBOOT
+#ifdef ONLY_TESTING
+		printk(KERN_CRIT "Would Reboot.\n");
+#else		
+		printk(KERN_CRIT "Initiating system reboot.\n");
+		machine_restart(NULL);
+#endif		
+#else
+		printk(KERN_CRIT "Reset in 5ms.\n");
+#endif	
+*/	
+}
+
+
+static struct file_operations lh79520dog_fops=
+{
+	owner:		THIS_MODULE,
+	write:		lh79520dog_write,
+	ioctl:		lh79520dog_ioctl,
+	open:		lh79520dog_open,
+	release:	lh79520dog_release,
+};
+
+static struct miscdevice lh79520dog_miscdev=
+{
+	WATCHDOG_MINOR,
+	"LH79520 watchdog",
+	&lh79520dog_fops
+};
+
+static int __init lh79520dog_init(void)
+{
+	int ret;
+
+	ret = misc_register(&lh79520dog_miscdev);
+
+	if (ret)
+    {
+		goto out;
+    }
+
+//	ret = request_irq(irq, lh79520dog_interrupt, SA_INTERRUPT, "lh79520wdt", NULL);
+//	if(ret) {
+//		printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq);
+//		goto outmisc;
+//	}
+
+    printk("LH79520 Watchdog Timer: timer margin %d sec\n", lh79520_margin);
+
+    ret=0;
+    out:
+	return ret;
+
+    outmisc:
+	misc_deregister(&lh79520dog_miscdev);
+	goto out;
+
+}
+
+static void __exit lh79520dog_exit(void)
+{
+	misc_deregister(&lh79520dog_miscdev);
+}
+
+module_init(lh79520dog_init);
+module_exit(lh79520dog_exit);
diff -urN linux-2.4.26/drivers/char/lh79520_wdt.h linux-2.4.26-vrs1-lnode80/drivers/char/lh79520_wdt.h
--- linux-2.4.26/drivers/char/lh79520_wdt.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/lh79520_wdt.h	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,63 @@
+/**********************************************************************
+ *	$Workfile:   LH79520_wdt.h  $
+ *	$Revision: 1.1.1.1 $
+ *	$Author: brad $
+ *	$Date: 2003/01/04 17:20:29 $
+ *
+ *	Project: LH79520 headers
+ *
+ *	Description:
+ *      This file contains the structure definitions and manifest
+ *      constants for LH79520 component:
+ *      	Watchdog Timer
+ *
+ *	References:
+ *		(1) ARM Isis Technical Reference Manual, System on Chip Group,
+ *		ARM SC063-TRM-0001-B
+ *
+ *	COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
+ *		CAMAS, WA
+ *********************************************************************/
+
+#ifndef LH79520_WDT_H
+#define LH79520_WDT_H
+
+/*
+ * Watchdog Timer Module Register Structure
+ */ 
+typedef struct {
+	volatile unsigned int	wdctlr;	/* Control */ 
+	volatile unsigned int	wdcntr;	/* Counter Reset */ 
+	volatile unsigned int	wdtstr;	/* Test */ 
+	volatile unsigned int	wdcnt0;	/* Counter Bits [7:0] */ 
+	volatile unsigned int	wdcnt1;	/* Counter Bits [15:8] */ 
+	volatile unsigned int	wdcnt2;	/* Counter Bits [23:16] */ 
+	volatile unsigned int	wdcnt3;	/* Counter Bits [31:24] */ 
+} WDTIMERREGS;
+
+/**********************************************************************
+ * Watchdog Timer Register Bit Fields
+ *********************************************************************/ 
+
+/**********************************************************************
+ * Watchdog Control Register Bit Fields
+ *********************************************************************/ 
+#define	WDT_CTRL_DISABLE	0
+#define	WDT_CTRL_ENABLE		_SBF(0,1)
+#define WDT_CTRL_RSP_FIQ	_SBF(1,0)		
+#define WDT_CTRL_RSP_RESET	_SBF(1,1)		
+#define	WDT_CTRL_FRZ_ENABLE	_BIT(3)
+#define WDT_CTRL_TOP		_SBF(4,((n)&0xF)
+
+/**********************************************************************
+ * Watchdog Counter Reset Register Bit Fields
+ *********************************************************************/ 
+#define	WDT_WDCNTR			(0x1984)
+
+/**********************************************************************
+ * Watchdog Register Bit Fields
+ *********************************************************************/ 
+#define WDT_WD_NWDFIQ			_BIT(7)
+#define WDT_WD_NWDRES			_BIT(6)
+
+#endif /* LH79520_WDT_H */
diff -urN linux-2.4.26/drivers/char/Makefile linux-2.4.26-vrs1-lnode80/drivers/char/Makefile
--- linux-2.4.26/drivers/char/Makefile	2005-11-02 16:54:20.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/Makefile	2005-11-02 17:37:31.000000000 -0400
@@ -16,7 +16,7 @@
 
 O_TARGET := char.o
 
-obj-y	 += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o
+obj-y	 += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o cradle.o
 
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
@@ -349,6 +349,7 @@
 obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
+obj-$(CONFIG_LH79520_WATCHDOG) += lh79520_wdt.o
 obj-$(CONFIG_EPXA_WATCHDOG) += epxa_wdt.o
 obj-$(CONFIG_OMAHA_WATCHDOG) += omaha_wdt.o
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
@@ -359,6 +360,12 @@
 # I2C char devices
 obj-$(CONFIG_I2C_DS1307) += ds1307.o
 
+# Specific to the LH79520 Sharp dev board.
+# Controls both PWM0 and PWM1
+# PWM0 is the backlighting
+# PWM1 is the audio
+obj-$(CONFIG_LH79520_PWM) += pwm520.o
+
 subdir-$(CONFIG_MWAVE) += mwave
 ifeq ($(CONFIG_MWAVE),y)
   obj-y += mwave/mwave.o
diff -urN linux-2.4.26/drivers/char/pwm520.c linux-2.4.26-vrs1-lnode80/drivers/char/pwm520.c
--- linux-2.4.26/drivers/char/pwm520.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/pwm520.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,870 @@
+/*
+ *  linux/drivers/char/pwm520.c
+ *
+ *  Copyright (C) 2002 Lineo.
+ *
+ *  Original code write was authored by Craig Matsuura <cmatsuura@lineo.com>
+ *  Parts of this code are from Sharp.
+ *  This code falls under the license of the GPL.
+ *
+ *  This modules is for controlling the PWM audio and backlighting.
+ *  Jumps for backlighting and audio must be set correctly on the LH79520
+ *  Board for this module to work properly.  See Sharp LH79520 Documentation
+ *  for jumper settings.
+ */
+//#define MODULES
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/irq.h>
+#include <asm/segment.h>
+#include <asm/uaccess.h>
+#include <linux/module.h>
+//#include <limits.h>
+#include <asm/arch/rcpc.h>
+#include <asm/arch/iocon.h>
+#include <asm/arch/hardware.h>
+
+#include "pwm520.h"
+
+pwmRegs_t   *pwmregs   = (pwmRegs_t *) IO_ADDRESS( PWM_PHYS);
+ioconRegs_t *ioconregs = (ioconRegs_t *)IO_ADDRESS( IOCON_PHYS);
+rcpcRegs_t  *rcpcregs  = (rcpcRegs_t *)IO_ADDRESS( RCPC_PHYS);
+
+#define TYPE(dev) (MINOR(dev) >> 4) /* high nibble */
+#define NUM(dev)  (MINOR(dev) & 0xf) /* low nibble */
+#if OLDWAY
+#define PCLK              51609600 /* ticks per second of AHB clock, 51MHz */
+static int pwm_xtal_freq = XTAL_IN; // From hardware.h
+static int pwm_clkin_freq = 0;      // PLL_CLOCK?  LH79520_CLKIN_FREQ;
+#else
+unsigned int hclkfreq_get( void);
+#endif
+
+static int pwm_major = 0;        // Major Number for Driver 0 indicates dynamic assignment
+static int pwm_prescale = 1;
+
+// Default Freq and Duty Cycles
+static int pwm_audio_freq = 440;    // Freq of tone
+static int pwm_audio_dcycle = 50;   // Duty Cycle for Audio
+static int pwm_audio_duration = 100000;// Delay (udelay) for beep
+
+static int pwm_backlight_dcycle = 100;// DC for Backlight
+static int pwm_backlight_mode = 0;  // Normal Mode
+static int pwm_backlight_freq = BACKLIGHT_INVERTER_PWM_FREQUENCY; // Freq of backlight
+
+#ifdef MODULES
+MODULE_PARM(pwm_major,"i");
+MODULE_PARM(pwm_prescale,"i");
+MODULE_PARM(pwm_xtal_freq,"i");
+MODULE_PARM(pwm_clkin_freq,"i");
+MODULE_PARM(pwm_audio_freq,"i");
+MODULE_PARM(pwm_audio_dcycle,"i");
+MODULE_PARM(pwm_audio_duration,"i");
+MODULE_PARM(pwm_backlight_dcycle,"i");
+MODULE_PARM(pwm_backlight_mode,"i");
+MODULE_PARM(pwm_backlight_freq,"i");
+#endif
+
+
+//void showPWM0Registers();
+
+#if OLDWAY
+/**********************************************************************
+*
+* Function: rcpc_get_bus_clock - From Sharp Source
+*
+* Purpose:
+*  return the frequency of the bus clock.
+*
+* Processing:
+*  this function returns the frequency of the bus clock in Hz
+*  based on the value of frequencies passed in and the value
+*  of the RCPC control register CLK_SEL bit.
+*
+* Parameters:
+*  xtalin: the frequency at the XTALIN pin; use 0 if there is no
+*          crystal or external clock driving the pin.
+*  clkin:  the frequency driving the CLKIN pin; use 0 if that pin
+*          is not driven.
+*
+* Outputs: None
+*
+* Returns:
+*  The bus clock frequency in Hz
+*
+* Notes:
+*  The nominal crystal input frequency in 14745600 Hz.
+*
+**********************************************************************/
+volatile unsigned long rcpc_get_bus_clock(unsigned long xtalin, unsigned long clkin)
+{
+   unsigned long timebase, divider;
+
+   if ( (rcpcregs->control & RCPC_CTRL_CLKSEL_EXT)
+                         == RCPC_CTRL_CLKSEL_EXT)
+   {
+      /* clock source is external clock */
+      timebase = clkin;
+   }
+   else
+   {
+      /* clock source is from PLL output */
+      timebase = xtalin * 21;
+   }
+
+   divider = rcpcregs->HCLKPrescale * 2;
+   if (divider == 0)
+      divider = 1;
+
+   return timebase / divider;
+}
+#endif // OLDWAY
+
+/**********************************************************************
+*
+* Function: pwm1_enable - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Enable PWM output on the PWM1 channel of the LH79520
+*
+* Processing:
+*   N/A
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+inline volatile void pwm1_enable(void)
+{
+    pwmregs->pwm1.enable = PWM_EN_ENABLE;
+}
+
+/**********************************************************************
+*
+* Function: pwm1_disable - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Disable PWM output on the PWM1 channel of the LH79520
+*
+* Processing:
+*   N/A
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+inline volatile void pwm1_disable(void)
+{
+    pwmregs->pwm1.enable = ~PWM_EN_ENABLE;
+}
+
+/**********************************************************************
+*
+* Function: pwm0_enable - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Enable PWM output on the PWM0 channel of the LH79520
+*
+* Processing:
+*   N/A
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+inline volatile void pwm0_enable(void)
+{
+    pwmregs->pwm0.enable = PWM_EN_ENABLE;
+}
+
+/**********************************************************************
+*
+* Function: pwm0_disable - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Disable PWM output on the PWM0 channel of the LH79520
+*
+* Processing:
+*   N/A
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+inline volatile void pwm0_disable(void)
+{
+    pwmregs->pwm0.enable = ~PWM_EN_ENABLE;
+}
+
+/**********************************************************************
+*
+* Function: pwm0_normal - Taken for Sharp Driver Example code146
+*
+* Purpose:
+*  Restores the normal sense of the PWM output signal on the PWM0
+*  channel of the LH79520
+*
+* Processing:
+*   N/A
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+inline volatile void pwm0_normal(void)
+{
+    pwmregs->pwm0.invert = ~PWM_INV_INVERT;
+}
+
+
+/**********************************************************************
+*
+* Function: pwm1_frequency - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Sets the PWM1 output frequency to the value specified
+*
+* Processing:
+*   Compute the prescale and period count to be programmed from the
+*   PCLK frequency. If the frequency value is too high or too low to
+*   be programmed within the permissible ranges of prescale and period,
+*   signal an error.
+*
+* Parameters:
+*   freq - Desired frequency, in Hz
+*
+* Outputs: None
+*
+* Returns:
+*   -1 - if frequency specified is zero
+*   -1 - if prescale is zero (an impossible condition)
+*   -1 - if the frequency is out of bounds
+*    0 - if the frequency is changed successfully
+*
+* Notes:
+*   This function depends on the values of LH79520_XTAL_FREQ and
+*   LH79520_CLKIN_FREQ to be set correctly in the LH79520_evb.h file.
+*   If external clock is used, LH79520_CLKIN_FREQ should be set
+*   to the external clock frequency. Otherwise, this function will
+*   fail.
+*
+*
+**********************************************************************/
+long pwm1_frequency(unsigned long freq)
+{
+    unsigned long pclk, pwm1clk, prescale;
+    unsigned long div;
+
+    if (0 == freq) {
+        return -1;
+    }
+
+#if OLDWAY
+    pclk = rcpc_get_bus_clock(pwm_xtal_freq,pwm_clkin_freq);
+#else
+	pclk = hclkfreq_get();
+#endif
+    prescale = rcpcregs->PWM1Prescale;
+    if (prescale > 0) {
+        pwm1clk = pclk / (prescale * 2);
+    } else {
+        printk("<4>THIS IS BAD.  SHOULD NOT GET HERE...\n");
+        //this should not happen
+        return -1;
+    }
+    div = pwm1clk / freq;
+    rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+    barrier();
+
+    while (div > USHRT_MAX && prescale <= SHRT_MAX) {
+        prescale += 1;
+        rcpcregs->PWM1Prescale = prescale;
+        pwm1clk = pclk / (prescale * 2);
+        div = pwm1clk / freq;
+    }
+    rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+    pwmregs->pwm1.tc = div;
+
+    return 0;
+}
+
+
+/**********************************************************************
+*
+* Function: pwm1_duty_cycle - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Sets the PWM1 duty cycle to the value specified
+*
+* Processing:
+*   Compute the duty cycle count to program into the dc register
+*   from the percentage specified and the tc count. Accounts for
+*   integer division truncation errors.
+*
+* Parameters:
+*   dcpercent - Desired duty cycle as a percentage of the total period
+*
+* Outputs: None
+*
+* Returns:
+*   the previous value of the duty cycle, as a percentage
+*
+* Notes:
+*
+**********************************************************************/
+long pwm1_duty_cycle(short dcpercent)
+{
+    unsigned short period;
+    unsigned long duty_cycle, prev_dc, prev_dc_percent;
+    period = (unsigned short) pwmregs->pwm1.tc;
+    prev_dc = pwmregs->pwm1.dc;
+    if (period > 0) {
+        prev_dc_percent = ((prev_dc * 100) + (period >> 1)) / period;
+    } else {
+        prev_dc_percent = 100;
+    }
+    duty_cycle = ((dcpercent * period) + 50) / 100;
+    pwmregs->pwm1.dc = duty_cycle;
+    return(long)prev_dc_percent;
+}
+
+/**********************************************************************
+*
+* Function: pwm0_frequency - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Sets the PWM0 output frequency to the value specified
+*
+* Processing:
+*   Compute the prescale and period count to be programmed from the
+*   PCLK frequency. If the frequency value is too high or too low to
+*   be programmed within the permissible ranges of prescale and period,
+*   signal an error.
+*
+* Parameters:
+*   freq - Desired frequency, in Hz
+*
+* Outputs: None
+*
+* Returns:
+*   -1 - if frequency specified is zero
+*   -1 - if prescale is zero (an impossible condition)
+*   -1 - if the frequency is out of bounds
+*    0 - if the frequency is changed successfully
+*
+* Notes:
+*   This function depends on the values of LH79520_XTAL_FREQ and
+*   LH79520_CLKIN_FREQ to be set correctly in the LH79520_evb.h file.
+*   If external clock is used, LH79520_CLKIN_FREQ should be set
+*   to the external clock frequency. Otherwise, this function will
+*   fail.
+*
+*
+**********************************************************************/
+long pwm0_frequency(unsigned long freq)
+{
+    unsigned long pclk, pwm0clk, prescale;
+    unsigned long div;
+
+    if (0 == freq) {
+        return -1;
+    }
+
+#if OLDWAY
+    pclk = rcpc_get_bus_clock(pwm_xtal_freq,pwm_clkin_freq);
+#else
+	pclk = hclkfreq_get();
+#endif
+    prescale = rcpcregs->PWM0Prescale;
+    if (prescale > 0) {
+        pwm0clk = pclk / (prescale * 2);
+    } else {
+        printk("<4>THIS IS BAD.  SHOULD NOT GET HERE...\n");
+        //this should not happen
+        return -1;
+    }
+    div = pwm0clk / freq;
+    rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+    barrier();
+
+    //FJB hack for orderite
+    rcpcregs->PWM0Prescale = 0x0a;
+#if 0    
+    while (div > USHRT_MAX && prescale <= SHRT_MAX) {
+        prescale += 1;
+        rcpcregs->PWM0Prescale = prescale;
+        pwm0clk = pclk / (prescale * 2);
+        div = pwm0clk / freq;
+    }
+#endif    
+    rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+    //pwmregs->pwm0.tc = div;
+    pwmregs->pwm0.tc = 0x285;
+    
+    return 0;
+}
+
+
+/**********************************************************************
+*
+* Function: pwm0_duty_cycle - Taken for Sharp Driver Example code
+*
+* Purpose:
+*  Sets the PWM0 duty cycle to the value specified
+*
+* Processing:
+*   Compute the duty cycle count to program into the dc register
+*   from the percentage specified and the tc count. Accounts for
+*   integer division truncation errors.
+*
+* Parameters:
+*   dcpercent - Desired duty cycle as a percentage of the total period
+*
+* Outputs: None
+*
+* Returns:
+*   the previous value of the duty cycle, as a percentage
+*
+* Notes:
+*
+**********************************************************************/
+long pwm0_duty_cycle(short dcpercent)
+{
+    unsigned short period;
+    unsigned long duty_cycle, prev_dc, prev_dc_percent;
+    period = (unsigned short) pwmregs->pwm0.tc;
+    prev_dc = pwmregs->pwm0.dc;
+    if (period > 0) {
+        prev_dc_percent = ((prev_dc * 100) + (period >> 1)) / period;
+    } else {
+        prev_dc_percent = 100;
+    }
+    duty_cycle = ((dcpercent * period) + 50) / 100;
+    pwmregs->pwm0.dc = duty_cycle;
+    return(long)prev_dc_percent;
+}
+
+/**********************************************************************
+*
+* Function: backlight_decrease_brightness
+*
+* Purpose:
+*  Decrease the LCD backlight brightness
+*
+* Processing:
+*  Decrement static variable holding current brightness level and
+*  set the PWM duty cycle.
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+void backlight_increase_brightness(void)
+{
+    pwm_backlight_dcycle--;
+    if (pwm_backlight_dcycle < 0)
+    {
+        pwm_backlight_dcycle = 0;
+    }
+    pwm0_duty_cycle(pwm_backlight_dcycle);
+}
+
+/**********************************************************************
+*
+* Function: backlight_increase_brightness
+*
+* Purpose:
+*  Increase the LCD backlight brightness
+*
+* Processing:
+*  Increment static variable holding current brightness level and
+*  set the PWM duty cycle.
+*
+* Parameters: None
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+void backlight_decrease_brightness(void)
+{
+    pwm_backlight_dcycle++;
+    if (pwm_backlight_dcycle > 100)
+    {
+        pwm_backlight_dcycle = 100;
+    }
+    pwm0_duty_cycle(pwm_backlight_dcycle);
+}
+
+/**********************************************************************
+*
+* Function: backlight_set_brightness
+*
+* Purpose:
+*  Set the LCD backlight brightness to the level specified
+*
+* Processing:
+*  N/A
+*
+* Parameters:
+*  bright - desired brightness level as a percentage of maximum
+*           brightness
+*
+* Outputs: None
+*
+* Returns: Nothing
+*
+* Notes:
+*
+**********************************************************************/
+void backlight_set_brightness(int bright)
+{
+    //bright = 0 means least brightness
+    //bright = 100 means max brightness
+    if (bright > 100)
+    {
+        bright = 100;
+    }
+    if (bright < 0)
+    {
+        bright = 0;
+    }
+
+    pwm_backlight_dcycle = 100 - bright;
+    pwm0_duty_cycle(pwm_backlight_dcycle);
+}
+
+
+/****************************************************************************
+ * Open Function - Open the device either the Backlight or the Audio
+ * /dev/pwm0 c 254 1 is the Backlighting
+ * /dev/pwm1 c 254 0 is the Audio
+ * Keep in mind the 254 is only an example.  If you do not specify a
+ * major code then a dynamic one will be assigned.  You will have to
+ * look at /proc/devices to see the major code for pwm
+ */
+int pwm_open(struct inode * inode, struct file * filp)
+{
+
+    MOD_INC_USE_COUNT;
+
+//    printk("<4>open pwm... dc=%d, bl_dc=%d\n",pwmregs->pwm0.dc,pwm_backlight_dcycle);
+    switch (NUM(inode->i_rdev)) {
+	case 0: // Audio
+            rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+            barrier();
+            rcpcregs->periphClkCtrl &= ~RCPC_CLKCTRL_PWM0_DISABLE;
+            rcpcregs->PWM0Prescale = ((~_BIT(15)) & pwm_prescale);
+            rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+            ioconregs->MiscMux |= MISCMUX_PWM0;
+            break;
+#if 0	    
+        case 1: // Backlight
+            rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+            barrier();
+            rcpcregs->periphClkCtrl &= ~RCPC_CLKCTRL_PWM1_DISABLE;
+            rcpcregs->PWM0Prescale = ((~_BIT(15)) & pwm_prescale);
+            rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+            ioconregs->MiscMux |= MISCMUX_PWM1;
+
+            if (pwm_backlight_mode) {
+                pwmregs->pwm0.sync = PWM_SYNC_SYNC;
+                ioconregs->MiscMux |= MISCMUX_PWM0SYNC;
+            }
+            else
+            {
+                pwmregs->pwm0.sync = PWM_SYNC_NORMAL;
+            }
+
+            pwm0_frequency(pwm_backlight_freq);
+            pwm0_duty_cycle(pwm_backlight_dcycle);
+            pwm0_normal();
+            pwm0_enable();
+            break;
+#endif        
+        default:
+            printk("<4>Minor device unknown %d\n",NUM(inode->i_rdev));
+            break;
+    }
+
+    return 0;
+}
+
+/****************************************************************************
+ *
+ */
+int pwm_release(struct inode *inode, struct file * filp)
+{
+//    printk("<4>release pwm...\n");
+    switch (NUM(inode->i_rdev)) {
+	case 0: // Audio
+            rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+            barrier();
+            rcpcregs->periphClkCtrl |= RCPC_CLKCTRL_PWM0_DISABLE;
+            rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+            ioconregs->MiscMux &= ~MISCMUX_PWM0;
+            pwm0_disable();
+            break;
+        case 1: // Should be backlight of touchscreen
+            //rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+            //barrier();
+            //rcpcregs->periphClkCtrl |= RCPC_CLKCTRL_PWM0_DISABLE;
+            //rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+            //ioconregs->MiscMux &= ~MISCMUX_PWM0;
+            //pwmregs->pwm0.enable = ~PWM_EN_ENABLE;
+            break;
+        
+        default:
+            printk("<4>Minor device unknown %d\n",NUM(inode->i_rdev));
+            break;
+    }
+
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+/****************************************************************************
+ *
+ */
+ssize_t pwm_read(struct file * file, char * buf,
+                    size_t count, loff_t *ppos)
+{
+    return 0;
+}
+
+/****************************************************************************
+ *
+ */
+ssize_t pwm_write(struct file * file, const char * buf,
+                     size_t count, loff_t *ppos)
+{
+    return 0;
+}
+
+/****************************************************************************
+ *
+ */
+int pwm_ioctl(struct inode *inode, struct file * file,
+                 unsigned int cmd, unsigned long arg)
+{
+    //int err = 0, size = _IOC_SIZE(cmd);
+
+    if (_IOC_TYPE(cmd) != PWM520_IOC_MAGIC) {
+        return -EINVAL;
+    }
+    if (_IOC_NR(cmd) > PWM520_IOC_MAXNR) {
+        return -EINVAL;
+    }
+
+    /*
+        Should check for direction bits see page 101 in "Linux Device Drivers Book"
+        size and err used here.
+    */
+
+    switch (NUM(inode->i_rdev)) {
+	case 0: // Audio
+            switch (cmd) {
+                case PWM520_IOCBEEP:
+                    pwm0_frequency(pwm_audio_freq);
+                    pwm0_duty_cycle(pwm_audio_dcycle);
+                    pwm0_enable();
+                    udelay(pwm_audio_duration);
+                    pwm0_disable();
+                    break;
+
+                case PWM520_IOCSTARTSND:
+                    pwm0_frequency(pwm_audio_freq);
+                    pwm0_duty_cycle(pwm_audio_dcycle);
+                    pwm0_enable();
+                    break;
+
+                case PWM520_IOCSTOPSND:
+                    pwm0_disable();
+                    break;
+
+                case PWM520_IOCSETFREQ: // Set Frequency
+                    pwm_audio_freq = arg;
+                    break;
+
+                case PWM520_IOCSETDCYCLE: // Set Duty Cycle
+                    pwm_audio_dcycle = arg;
+                    break;
+
+                case PWM520_IOCGETFREQ: // Get Frequency
+                    __put_user(pwm_audio_freq, (int *) arg);
+                    break;
+
+                case PWM520_IOCGETDCYCLE: // Get Duty Cycle
+                    __put_user(pwm_audio_dcycle, (int *) arg);
+                    break;
+            }
+            break;
+#if 0	    
+        case 1: // Should be backlight of touchscreen
+            switch (cmd) {
+                case PWM520_IOCRESET:
+//                    printk("Reset pwm0\n");
+                    pwm_backlight_dcycle = 100;// DC for Backlight
+                    pwm_backlight_mode = 0;  // Normal Mode
+                    pwm_backlight_freq = BACKLIGHT_INVERTER_PWM_FREQUENCY; // Freq of backlight
+                    break;
+                case PWM520_IOCSTOPPWM0: // Stop PWM0
+                    rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+                    barrier();
+                    rcpcregs->periphClkCtrl |= RCPC_CLKCTRL_PWM0_DISABLE;
+                    rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+                    ioconregs->MiscMux &= ~MISCMUX_PWM0;
+                    pwmregs->pwm0.enable = ~PWM_EN_ENABLE;
+                    break;
+                case PWM520_IOCINCREASEBL:
+//                    printk("Brighter\n");
+                    backlight_increase_brightness();
+                    break;
+
+                case PWM520_IOCDECREASEBL:
+//                    printk("Lighter\n");
+                    backlight_decrease_brightness();
+                    break;
+
+                case PWM520_IOCSETBL:
+//                    printk("Set to %ld\n",arg);
+                    backlight_set_brightness(arg);
+                    break;
+            }
+            break;
+#endif
+        
+    }
+
+    return 0;
+}
+
+
+/****************************************************************************
+ *
+ */
+struct file_operations  pwm_fops = {
+    owner:          THIS_MODULE,
+    llseek:     no_llseek,
+    read:       pwm_read,
+    write:      pwm_write,
+    ioctl:      pwm_ioctl,
+    open:       pwm_open,
+    release:    pwm_release,
+};
+
+#if 0
+void test_pwm1()
+{
+    printk("TEST CASE PLEASE REMOVE ONCE DONE\n");
+
+    rcpcregs->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+    barrier();
+    rcpcregs->periphClkCtrl &= ~RCPC_CLKCTRL_PWM1_DISABLE;
+    rcpcregs->PWM1Prescale = ((~_BIT(15)) & pwm_prescale);
+    rcpcregs->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+    ioconregs->MiscMux |= MISCMUX_PWM1;
+
+    pwm1_frequency(pwm_audio_freq);
+    pwm1_duty_cycle(pwm_audio_dcycle);
+    pwm1_enable();
+}
+
+void showPWM1Registers()
+{
+    printk("PWM1 Registers\n");
+    printk("=============\n\n");
+    printk("pwm1.tc     = %x\n",pwmregs->pwm1.tc);
+    printk("pwm1.dc     = %x\n",pwmregs->pwm1.dc);
+    printk("pwm1.enable = %x\n",pwmregs->pwm1.enable);
+    printk("pwm1.invert = %x\n",pwmregs->pwm1.invert);
+    printk("pwm1.sync   = %x\n",pwmregs->pwm1.sync);
+}
+
+void showPWM0Registers()
+{
+    printk("PWM0 Registers\n");
+    printk("=============\n\n");
+    printk("pwm0.tc     = %d\n",pwmregs->pwm0.tc);
+    printk("pwm0.dc     = %d\n",pwmregs->pwm0.dc);
+    printk("pwm0.enable = 0x%x\n",pwmregs->pwm0.enable);
+    printk("pwm0.invert = 0x%x\n",pwmregs->pwm0.invert);
+    printk("pwm0.sync   = 0x%x\n",pwmregs->pwm0.sync);
+}
+
+#endif
+
+/****************************************************************************
+ *
+ */
+static int __init pwm_init_module(void)
+{
+    int result;
+
+    //printk("<1>Start PWM Module\n");
+    printk("<1>Sharp LH79520 PWM Driver Copyright 2002 Lineo\n");
+
+    result = register_chrdev(pwm_major,"pwm",&pwm_fops);
+    if (result < 0) {
+        printk("<4>pwm: can't get major number %d\n",pwm_major);
+        return result;
+    }
+    if (pwm_major == 0) {
+        pwm_major = result; /* Dynamic Allocation of major number */
+        printk("<4>PWM Dynamic Major Number %d\n",pwm_major);
+    }
+
+    return 0;
+}
+
+/****************************************************************************
+ *
+ */
+static void __exit pwm_cleanup_module(void)
+{
+    int result;
+
+    printk("<1>End PWM Module...\n");
+    result = unregister_chrdev(pwm_major,"pwm");
+}
+
+module_init(pwm_init_module);
+module_exit(pwm_cleanup_module);
diff -urN linux-2.4.26/drivers/char/pwm520.h linux-2.4.26-vrs1-lnode80/drivers/char/pwm520.h
--- linux-2.4.26/drivers/char/pwm520.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/char/pwm520.h	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ *  linux/drivers/char/pwm520.h
+ *
+ *  Copyright (C) 2002 Lineo.
+ *
+ *  Original code write was authored by Craig Matsuura <cmatsuura@lineo.com>
+ *  Parts of this code are from Sharp.
+ *  This code falls under the license of the GPL.
+ *
+ *  This modules is for controlling the PWM audio and backlighting.
+ *  Jumps for backlighting and audio must be set correctly on the LH79520
+ *  Board for this module to work properly.  See Sharp LH79520 Documentation
+ *  for jumper settings.
+ */
+#ifndef __PWM520_H
+#define __PWM520_H
+
+typedef struct {
+	volatile unsigned int tc;
+	volatile unsigned int dc;
+	volatile unsigned int enable;
+	volatile unsigned int invert;
+	volatile unsigned int sync;
+	volatile unsigned int res[3];
+} pwmXRegs_t;
+
+typedef struct {
+    volatile pwmXRegs_t pwm0;
+    volatile pwmXRegs_t pwm1;
+} pwmRegs_t;
+
+extern pwmRegs_t *pwmregs;
+
+#define PWM_EN_ENABLE    _BIT(0)
+#define PWM_INV_INVERT   _BIT(0)
+#define PWM_SYNC_SYNC    _SBF(0,1)
+#define PWM_SYNC_NORMAL  _SBF(0,0)
+
+#define BACKLIGHT_INVERTER_PWM_FREQUENCY        (200) // 200Hz
+
+// IOCTL's
+#define PWM520_IOC_MAGIC    'p'
+#define PWM520_IOCBEEP       _IO(PWM520_IOC_MAGIC, 0)
+#define PWM520_IOCSTARTSND   _IO(PWM520_IOC_MAGIC, 1)
+#define PWM520_IOCSTOPSND    _IO(PWM520_IOC_MAGIC, 2)
+#define PWM520_IOCSETFREQ    _IOW(PWM520_IOC_MAGIC, 3, int)
+#define PWM520_IOCSETDCYCLE  _IOW(PWM520_IOC_MAGIC, 4, int)
+#define PWM520_IOCGETFREQ    _IOR(PWM520_IOC_MAGIC, 5, int)
+#define PWM520_IOCGETDCYCLE  _IOR(PWM520_IOC_MAGIC, 6, int)
+
+#define PWM520_IOCRESET      _IO(PWM520_IOC_MAGIC, 7)
+#define PWM520_IOCSTOPPWM0   _IO(PWM520_IOC_MAGIC, 8)
+#define PWM520_IOCINCREASEBL _IO(PWM520_IOC_MAGIC, 9)
+#define PWM520_IOCDECREASEBL _IO(PWM520_IOC_MAGIC, 10)
+#define PWM520_IOCSETBL      _IOW(PWM520_IOC_MAGIC, 11, int)
+
+#define PWM520_IOC_MAXNR 11
+#endif
diff -urN linux-2.4.26/drivers/misc/ads784x.c linux-2.4.26-vrs1-lnode80/drivers/misc/ads784x.c
--- linux-2.4.26/drivers/misc/ads784x.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/ads784x.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,1064 @@
+/* vi: set sw=4 ts=4 ai: */
+
+// #define MODULE
+
+#define TS_DATA_QTOPIA
+#undef  CONFIG_ADS7846
+
+/**********************************************************************
+*  linux/drivers/misc/ads784x.c
+*
+*  Provide ADS_784x (touchscreen) functionality for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License (GPL) version 2
+*  as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+/**********************************************************************
+* Algorithm:
+*
+*	The driver sleeps when there is no pen on the screen.  When a pen_down
+*	interrupt occurs, the pen_down interrupt handler wakes the polling thread.
+*	The polling thread polls the ADS chip SAMPLES_PER_SECOND.  When the polling
+*	thread polls the ADS chip and the pen is no longer down, the polling
+*	thread goes to sleep and the pen_down interrupt handler is enabled.
+*
+*	The ADS device sleeps between conversions to save power.
+*
+*	The driver stores pen coordinates in a queue. An application can access
+*	the coordinate queue by opening and reading the associated device file
+*	(char major=10 minor=20).  An application can poll the queue to see if
+*	it contains coordinates. If it does, the application can read a coordinate
+*	structure back. The coordinate queue is flushed when the application
+*	opens the device file.
+*
+**********************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+
+#undef DEBUG
+#undef VERBOSE
+#define DRVNAME "ads_784x"
+#include <linux/verbosedebug.h>
+
+#include <linux/version.h>
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+#endif /* MODULE */
+
+#include "ssp.h"
+
+#if defined(CONFIG_ADS7846) && defined(CONFIG_PROC_FS)
+#	define PROC_TEMPERATURE
+#	define PROC_BATTERY
+#endif
+
+#ifdef PROC_BATTERY
+static struct proc_dir_entry *ads_784x_proc_battery;
+#endif
+#ifdef PROC_TEMPERATURE
+static struct proc_dir_entry *ads_784x_proc_temperature;
+#endif
+
+/*********************************************************************
+* A couple of macros we use here...
+*********************************************************************/
+#ifndef _BIT
+#define _BIT(n) (1 << (n))
+#endif
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+#ifndef _BITMASK
+#define _BITMASK(field_width) ( _BIT(field_width) - 1)
+#endif
+
+/**********************************************************************
+* Define ADS 784x Control byte
+**********************************************************************/
+
+#define CTRL_S				_BIT(7)			/* Start bit (REQUIRED) */
+
+// #define CTRL_ADDR(n)		_SBF(4,(n&0x7))
+#define CTRL_X				_SBF(4,0x1)		/* Read X value */
+#define CTRL_Y				_SBF(4,0x5)		/* Read Y value */
+#ifdef	CONFIG_ADS7846
+#define CTRL_P1				_SBF(4,0x3)		/* Read P1 value */
+#define CTRL_P2				_SBF(4,0x4)		/* Read P2 value */
+#define CTRL_BATTERY		_SBF(4,0x2)		/* Read BATTERY value */
+#define CTRL_TEMP0			_SBF(4,0x0)		/* Read Temperature-0 value */
+#define CTRL_TEMP1			_SBF(4,0x7)		/* Read Temperature-1 value */
+#endif	// CONFIG_ADS7846
+
+// #define CTRL_MODE(n)		_SBF(3,(n&0x1))
+#define CTRL_12BIT			_SBF(3,0x0)		/* 12-Bit conversions  */
+#define CTRL_8BIT			_SBF(3,0x1)		/* 8-Bit conversions */
+
+// #define CTRL_SER_DFR(n)	_SBF(2,(n&0x1))
+#define CTRL_SER			_SBF(2,0x1)		/* Single-Ended reference */
+#define CTRL_DFR			_SBF(2,0x0)		/* Differential reference */
+
+// #define CTRL_PD(n)		(n&0x3)
+#define CTRL_PD_ZERO		(0x0)		/* PenIRQ enabled - PowerDown after */
+#define CTRL_PD_ONE			(0x1)		/* PenIRQ disabled - PowerDown after */
+#define CTRL_PD_TWO			(0x2)		/* PenIRQ disabled - RESERVED */
+#define CTRL_PD_THREE		(0x3)		/* PenIRQ disabled - Powered ON */
+
+/**********************************************************************
+* Define Simplified ADS 784x Control Codes
+**********************************************************************/
+
+//#define ADS_784x_PD      0   /* Power Down Settings */
+//#define ADS_784x_PD_INIT 0   /* Init setting reference and ADC Off */
+
+#define ADS_784x_INIT \
+	( CTRL_S | CTRL_X | CTRL_12BIT | CTRL_DFR | CTRL_PD_ZERO)
+#define ADS_784x_READ_X \
+	( CTRL_S | CTRL_X | CTRL_12BIT | CTRL_DFR | CTRL_PD_ZERO)
+#define ADS_784x_READ_Y \
+	( CTRL_S | CTRL_Y | CTRL_12BIT | CTRL_DFR | CTRL_PD_ZERO)
+#ifdef CONFIG_ADS7846
+#define ADS_784x_READ_P1 \
+	( CTRL_S | CTRL_P1 | CTRL_12BIT | CTRL_DFR | CTRL_PD_ZERO)
+#define ADS_784x_READ_P2 \
+	( CTRL_S | CTRL_P2 | CTRL_12BIT | CTRL_DFR | CTRL_PD_ZERO)
+#define ADS_784x_READ_BATTERY \
+	( CTRL_S | CTRL_BATTERY | CTRL_12BIT | CTRL_SER | CTRL_PD_ZERO)
+#define ADS_784x_READ_TEMP0 \
+	( CTRL_S | CTRL_TEMP0 | CTRL_12BIT | CTRL_SER | CTRL_PD_ZERO)
+#define ADS_784x_READ_TEMP1 \
+	( CTRL_S | CTRL_TEMP1 | CTRL_12BIT | CTRL_SER | CTRL_PD_ZERO)
+#endif // CONFIG_ADS7846
+
+/**********************************************************************
+* Define our touchscreen data type
+*
+* This structure is nonsense - millisecs is not very useful
+* since the field size is too small.  Also, we SHOULD NOT
+* be exposing jiffies to user space directly.
+**********************************************************************/
+typedef struct tsData_t tsData_t;
+
+#ifdef TS_DATA_COLLIE
+#define TS_DATA_STRUCT
+#define PROVIDE_TS_MILLISECS
+struct tsData_t {
+	long x;
+	long y;
+	long pressure;
+	long long millisecs;
+};
+#endif
+
+#ifdef TS_DATA_IPAQ
+#define TS_DATA_STRUCT
+struct tsData_t {
+	unsigned short pressure;
+	unsigned short x;
+	unsigned short y;
+	unsigned short pad;
+};
+#endif 
+
+#ifdef TS_DATA_LH79X
+#define TS_DATA_STRUCT
+struct tsData_t {
+	uint16_t pressure;
+	uint16_t y;		/* Will be read as X */
+	uint16_t x;		/* Will be read as Y */
+	uint16_t pad;
+};
+#endif
+
+/*
+QTopia data format:
+unsigned char data2[5];
+data.status=data2[0];	// bit 0x40 is "touch"/left mouse
+data.xpos=(data2[1] << 8) | data2[2];
+data.ypos=(data2[3] << 8) | data2[4];
+*/
+
+#ifdef TS_DATA_QTOPIA
+#define TS_DATA_STRUCT
+struct tsData_t {
+    unsigned char pressure;
+	unsigned char xhigh;
+    unsigned char xlow;
+    unsigned char yhigh;
+    unsigned char ylow;
+} __attribute__ ((packed));
+#endif
+
+#ifndef TS_DATA_STRUCT
+#define TS_DATA_DEFAULT
+#define PROVIDE_TS_TIMESTAMP
+struct tsData_t {
+	uint16_t pressure;
+	uint16_t x;
+	uint16_t y;
+	uint16_t pad;
+	struct timeval stamp;
+};
+#endif
+
+#define MAX_TS_DATA 16
+
+#define X_DELTA_MAX 10
+#define Y_DELTA_MAX 10
+
+/* Define the readings we are to take per second (default to 50) */
+#define SAMPLES_PER_SECOND	10
+
+/*
+* Define the pen down debounce we are to take.
+* (default of 20 == 1/20 of a second)
+*/
+#define DEBOUNCE_FRACTION_OF_A_SECOND	50
+
+/**********************************************************************
+* Define our ADS context structure
+**********************************************************************/
+typedef struct adsContext_t adsContext_t;
+struct adsContext_t {
+
+	void          *sspContext;
+	void          (*write) (void *sspContext, unsigned int data);
+	unsigned int  (*read) (void *sspContext);
+	int           (*enable_pen_down_irq)(void *sspContext);
+	int           (*disable_pen_down_irq)(void *sspContext);
+	int           (*is_pen_down)(void *sspContext);
+	int           (*lock)(void *sspContext, int device);
+	int           (*unlock)(void *sspContext, int device);
+	void 	      (*chipselect_enable)(void);
+	void 	      (*chipselect_disable)(void);
+	void 	      (*chipselect_manual)(void);
+	
+	struct fasync_struct *fasync;
+	struct completion complete;
+	struct task_struct *rtask;
+
+	wait_queue_head_t read_wait;
+	wait_queue_head_t irq_wait;
+
+	int tsDataHead;
+	int tsDataTail;
+	tsData_t tsData[MAX_TS_DATA];
+};
+static adsContext_t adsContext_l;
+
+/**********************************************************************
+* Macro: ads_784x_tsData_pending
+**********************************************************************/
+#define ads_784x_tsData_pending(adsContext) \
+	((adsContext)->tsDataHead != (adsContext)->tsDataTail)
+
+/**********************************************************************
+* Macro: ads_784x_tsData_get
+**********************************************************************/
+#define ads_784x_tsData_get(adsContext) \
+	((adsContext)->tsData + (adsContext)->tsDataTail)
+
+/**********************************************************************
+* Macro: ads_784x_tsData_pull
+**********************************************************************/
+#define ads_784x_tsData_pull(adsContext) \
+	((adsContext)->tsDataTail = \
+		((adsContext)->tsDataTail + 1) & (MAX_TS_DATA - 1))
+
+/**********************************************************************
+* Macro: ads_784x_tsData_flush
+**********************************************************************/
+#define ads_784x_tsData_flush(adsContext) \
+	((adsContext)->tsDataTail = (adsContext)->tsDataHead)
+
+/**********************************************************************
+* Function: ads_784x_tsData_add
+**********************************************************************/
+static inline void ads_784x_tsData_add(
+	adsContext_t *adsContext,
+	unsigned int pressure,
+	unsigned int x,
+	unsigned int y)
+{
+	int next_head;
+	long xcoff, ycoff;
+
+	vdprintk("ENTER: ads_784x_tsData_add()\n");
+	next_head = (adsContext->tsDataHead + 1) & (MAX_TS_DATA - 1);
+	if (next_head != adsContext->tsDataTail) {
+#ifndef TS_DATA_QTOPIA
+		adsContext->tsData[adsContext->tsDataHead].pressure = pressure;
+		adsContext->tsData[adsContext->tsDataHead].x = x;
+		adsContext->tsData[adsContext->tsDataHead].y = y;
+#ifdef PROVIDE_TS_TIMESTAMP
+		get_fast_time(&adsContext->tsData[adsContext->tsDataHead].stamp);
+#endif
+#else	// TS_DATA_QTOPIA
+		adsContext->tsData[adsContext->tsDataHead].pressure = pressure ? 0x40 : 0;
+		adsContext->tsData[adsContext->tsDataHead].xlow = x & 0xFF;
+		adsContext->tsData[adsContext->tsDataHead].xhigh = x >> 8;
+		adsContext->tsData[adsContext->tsDataHead].ylow = y & 0xFF;
+		adsContext->tsData[adsContext->tsDataHead].yhigh = y >> 8;
+#endif	// TS_DATA_QTOPIA
+		adsContext->tsDataHead = next_head;
+		if (adsContext->fasync)
+			kill_fasync(&adsContext->fasync, SIGIO, POLL_IN);
+		wake_up_interruptible(&adsContext->read_wait);
+	}
+	vdprintk("LEAVE: ads_784x_tsData_add()\n");
+	return;
+}
+
+/**********************************************************************
+* Function: ads_784x_Read_tsData
+**********************************************************************/
+static int x_last, y_last;
+static int ads_784x_Read_tsData(adsContext_t *adsContext)
+{
+	void *sspContext = adsContext->sspContext;
+	int x=0, x_1=0, x_2=0;
+	int y=0, y_1=0, y_2=0;
+	int pen_down = 0;
+	int p = 0;
+#ifdef CONFIG_ADS7846
+	int p1=0, p1_1=0, p1_2=0;
+	int p2=0, p2_1=0, p2_2=0;
+#endif
+
+	vdprintk("ENTER: ads_784x_Read_tsData()\n");
+
+#define	TS_AVG_ITERS	8
+
+	/*
+	* Filtering is policy.  Policy belongs in user space.  We
+	* therefore leave it to user space to do any filtering
+	* they please.
+	*
+	* We do however, read twice and check against maximum x & y deltas
+	* to reduce the amount of garbage returned.
+	*
+	* Note: There will be one reading with p=0 given when the pen is raised.
+	*/
+
+	/* Read the pen_down data first as it jitters after the other reads */
+	/* MUST lock the SSP  before accessing it */
+	adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+	pen_down = adsContext->is_pen_down(sspContext);
+	/* MUST unlock the SSP  after it has been locked */
+	adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+
+	do {
+		/* MUST lock the SSP  before accessing it */
+		adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+		/*
+		* Read the pressure, X position, and Y position.
+		* Interleave them for better performance
+		*/
+		//FJB
+		adsContext->chipselect_enable();
+#ifdef CONFIG_ADS7846
+		adsContext->write(sspContext, ADS_784x_READ_P1);
+		adsContext->write(sspContext, ADS_784x_READ_P2);
+		p1_1 = adsContext->read(sspContext);
+		p2_1 = adsContext->read(sspContext);
+#endif
+		adsContext->write(sspContext, ADS_784x_READ_X);
+		x_1 = adsContext->read(sspContext);
+		adsContext->write(sspContext, ADS_784x_READ_Y);
+		y_1 = adsContext->read(sspContext);
+
+		/*
+		* ... AGAIN ...
+		* Read the pressure, X position, and Y position.
+		* Interleave them for better performance
+		*/
+#ifdef CONFIG_ADS7846
+		adsContext->write(sspContext, ADS_784x_READ_P1);
+		adsContext->write(sspContext, ADS_784x_READ_P2);
+		p1_2 = adsContext->read(sspContext);
+		p2_2 = adsContext->read(sspContext);
+#endif
+		adsContext->write(sspContext, ADS_784x_READ_X);
+		x_2 = adsContext->read(sspContext);
+		adsContext->write(sspContext, ADS_784x_READ_Y);
+		y_2 = adsContext->read(sspContext);
+		
+		//FJB
+		adsContext->chipselect_disable();
+		
+		/* MUST unlock the SSP  after it has been locked */
+		adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+
+	} while ((x_1 > (x_2+X_DELTA_MAX)) || (x_2 > (x_1+X_DELTA_MAX))
+		||   (y_1 > (y_2+Y_DELTA_MAX)) || (y_2 > (y_1+Y_DELTA_MAX))
+		||   (x_1 == 0) || (y_1 == 0)  || (x_2 == 0) || (y_2 == 0));
+
+
+#ifdef CONFIG_ADS7846
+	p1 = (p1_1 + p1_2) / 2;
+	p2 = (p2_1 + p2_2) / 2;
+	p = p2 - p1;
+#else
+	p = pen_down;
+#endif
+	x = (x_1 + x_2) / 2;
+	y = (y_1 + y_2) / 2;
+
+	// normalize values
+	// very subject to experimentation
+
+#if 0
+	if((x == 0) || (y == 0))
+	{
+		x = x_last;
+		y = y_last;
+	}
+	else
+	{
+		x_last = x;
+		y_last = y;
+	}
+#endif
+
+	y = (1 << 12) - y;
+	vdprintk("LEAVE: ads_784x_Read_tsData(x=0x%03x, y=0x%03x)\n", x, y);
+	ads_784x_tsData_add(adsContext, 0x40, x, y); // generate pen up/pen down sequence
+	ads_784x_tsData_add(adsContext, 0x00, x, y);
+
+	return(pen_down);
+}
+
+/**********************************************************************
+* Function: ads_784x_thread
+*
+* This is a RT kernel thread that handles the ADC accesses
+* (mainly so we can use semaphores to serialise accesses to the ADC).
+**********************************************************************/
+static int ads_784x_thread(void *_adsContext)
+{
+	adsContext_t *adsContext = _adsContext;
+	void *sspContext = adsContext->sspContext;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	int pen_down = 0;
+
+	vdprintk("ENTER: ads_784x_thread()\n");
+	adsContext->rtask = tsk;
+
+	daemonize();
+	tsk->tty = NULL;
+	strcpy(tsk->comm, "ktsd");
+
+	/* only want to receive SIGKILL */
+	spin_lock_irq(&tsk->sigmask_lock);
+	siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
+	recalc_sigpending(tsk);
+	spin_unlock_irq(&tsk->sigmask_lock);
+
+	add_wait_queue(&adsContext->irq_wait, &wait);
+
+	complete(&adsContext->complete);
+
+	/* MUST lock the SSP  before accessing it */
+	adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+	pen_down = adsContext->is_pen_down(sspContext);
+	vdprintk("TSThrPD: %d\t", pen_down);
+	/* MUST unlock the SSP  after it has been locked */
+	adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+	for (;;) {
+		signed long interval;
+
+		/*
+		* Set to interrupt mode and wait a settling time.
+		*/
+		set_task_state(tsk, TASK_INTERRUPTIBLE);
+		if (sspContext == NULL) {
+			interval = HZ;	/* Check for change once per second */
+		} else if (pen_down) {
+			/* If pen is down then periodically read pen position */
+			/* MUST lock the SSP  before accessing it */
+			adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+			adsContext->disable_pen_down_irq(sspContext);
+			/* MUST unlock the SSP  after it has been locked */
+			adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+			interval = HZ/SAMPLES_PER_SECOND;
+		} else {
+			/* If pen is not down then sleep until pen down interrupt */
+			/* MUST lock the SSP  before accessing it */
+			adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+			adsContext->enable_pen_down_irq(sspContext);
+			/* MUST unlock the SSP  after it has been locked */
+			adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+			interval = MAX_SCHEDULE_TIMEOUT;
+		}
+		schedule_timeout(interval);
+		if (signal_pending(tsk)) {
+			break;
+		}
+#if 0
+		if (pen_down == 0) {
+			/*
+			* On pen down there is some bounce.
+			* Wait a debounce period and read it again.
+			*/
+			schedule_timeout(HZ/DEBOUNCE_FRACTION_OF_A_SECOND);
+			if (signal_pending(tsk)) {
+				break;
+			}
+			/*
+			* If the pen is not down after the debounce period,
+			* ignore the pen down signal.
+			*/
+			/* MUST lock the SSP  before accessing it */
+			adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+			pen_down = adsContext->is_pen_down(sspContext);
+			/* MUST unlock the SSP  after it has been locked */
+			adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+			if (pen_down == 0)
+				continue;
+		}
+#endif
+		adsContext->disable_pen_down_irq(sspContext);
+		/*
+		* We got an IRQ, which works us up.  Process the touchscreen.
+		*/
+		pen_down = ads_784x_Read_tsData(adsContext);
+	}
+
+	remove_wait_queue(&adsContext->irq_wait, &wait);
+	adsContext->rtask = NULL;
+	vdprintk("LEAVE: ads_784x_thread()\n");
+
+	return(0);
+}
+
+/**********************************************************************
+* Function: ads_784x_read
+*
+* ***********************************
+* *** User space driver interface ***
+* ***********************************
+**********************************************************************/
+static ssize_t ads_784x_read(struct file *filp, char *buffer, size_t _count, loff_t *ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	adsContext_t *adsContext = filp->private_data;
+	char *ptr = buffer;
+	int err = 0;
+	int count = (int)_count;	/* Force a sigened value to be used */
+
+	vdprintk("ENTER: ads_784x_read()\n");
+	add_wait_queue(&adsContext->read_wait, &wait);
+	while (count >= sizeof(tsData_t)) {
+		err = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+
+		if (ads_784x_tsData_pending(adsContext)) {
+			tsData_t *tsData = ads_784x_tsData_get(adsContext);
+
+			err = copy_to_user(ptr, tsData, sizeof(tsData_t));
+			ads_784x_tsData_pull(adsContext);
+
+			if (err)
+				break;
+#if 0
+			else
+			  printk("ads_784x_read: P: %02X X: %4d Y: %4d\n",
+				  tsData->pressure & 0x40, (tsData->xhigh << 8) + tsData->xlow, (tsData->yhigh << 8) + tsData->ylow);
+#endif
+
+			ptr += sizeof(tsData_t);
+			count -= sizeof(tsData_t);
+			continue;
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		err = -EAGAIN;
+		if (filp->f_flags & O_NONBLOCK)
+			break;
+		schedule();
+	}
+ 	current->state = TASK_RUNNING;
+	remove_wait_queue(&adsContext->read_wait, &wait);
+	vdprintk("LEAVE: ads_784x_read()\n");
+
+	return(ptr == buffer ? err : ptr - buffer);
+}
+
+/**********************************************************************
+* Function: ads_784x_poll
+*
+* ***********************************
+* *** User space driver interface ***
+* ***********************************
+**********************************************************************/
+static unsigned int ads_784x_poll(struct file *filp, poll_table *wait)
+{
+	adsContext_t *adsContext = filp->private_data;
+	int ret = 0;
+
+	vdprintk("ENTER: ads_784x_poll()\n");
+	poll_wait(filp, &adsContext->read_wait, wait);
+	if (ads_784x_tsData_pending(adsContext))
+		ret = POLLIN | POLLRDNORM;
+	vdprintk("LEAVE: ads_784x_poll()\n");
+
+	return(ret);
+}
+
+/**********************************************************************
+* Function: ads_784x_open
+*
+* ***********************************
+* *** User space driver interface ***
+* ***********************************
+**********************************************************************/
+static int ads_784x_open(struct inode *inode, struct file *filp)
+{
+	adsContext_t *adsContext = &adsContext_l;
+	int ret = 0;
+
+	vdprintk("ENTER: ads_784x_open()\n");
+
+	filp->private_data = adsContext;
+
+	/* Flush the ts data queue here */
+	ads_784x_tsData_flush(adsContext);
+
+	vdprintk("LEAVE: ads_784x_open()\n");
+	return(ret);
+}
+
+/**********************************************************************
+* Function: ads_784x_fasync
+*
+* ***********************************
+* *** User space driver interface ***
+* ***********************************
+**********************************************************************/
+static int ads_784x_fasync(int fd, struct file *filp, int on)
+{
+	int sts;
+	adsContext_t *adsContext = filp->private_data;
+
+	vdprintk("ENTER: ads_784x_fasync()\n");
+	sts = fasync_helper(fd, filp, on, &adsContext->fasync);
+	vdprintk("LEAVE: ads_784x_fasync()\n");
+
+	return(sts);
+}
+
+/**********************************************************************
+* Function: ads_784x_release
+*
+* ***********************************
+* *** User space driver interface ***
+* ***********************************
+*
+* Release touchscreen resources.  Disable IRQs.
+**********************************************************************/
+static int ads_784x_release(struct inode *inode, struct file *filp)
+{
+	// adsContext_t *adsContext = filp->private_data;
+
+	vdprintk("ENTER: ads_784x_release()\n");
+	lock_kernel();
+	ads_784x_fasync(-1, filp, 0);
+	unlock_kernel();
+	vdprintk("LEAVE: ads_784x_release()\n");
+
+	return(0);
+}
+
+/**********************************************************************
+* Define (fill in) the user space file operations for this driver
+* and initialize the ADS touchscreen driver as a "miscdevice":
+* 		Character device
+* 		Major(10) --- Non-serial mice, misc features
+* 		Minor(20) --- /dev/touchscreen/ads_784x
+**********************************************************************/
+static struct file_operations ads_784x_fops = {
+	owner:		THIS_MODULE,
+	read:		ads_784x_read,
+	poll:		ads_784x_poll,
+	open:		ads_784x_open,
+	fasync:		ads_784x_fasync,
+	release:	ads_784x_release,
+};
+
+static struct miscdevice ads_784x_dev = {
+	minor: 20,
+	name: "touchscreen/ads_784x",
+	fops: &ads_784x_fops,
+};
+
+#ifdef PROC_BATTERY
+/**********************************************************************
+* ads_784x_proc_battery_read
+**********************************************************************/
+static int ads_784x_proc_battery_read(char *buf, char **start, off_t offset,
+		int len, int *eof, void *unused)
+{
+	adsContext_t *adsContext = &adsContext_l;
+	void *ads784x_sspContext = adsContext->sspContext;
+	int milliVolts;
+	int volts;
+	int hundredthsVolts;
+	int sample;
+	int size;
+	int count;
+	int last_irq_state;
+
+	vdprintk("ENTER: ads_784x_proc_battery_read(len=%d)\n", len);
+	/*
+	* Reading the ADS784X takes the part out of pen down interrupt mode
+	* causing spurious pen down interrupts. So we must disable 
+	* pen down interrupts while reading battery voltage.
+	*/
+	last_irq_state = adsContext->disable_pen_down_irq(ads784x_sspContext);
+
+	/* Do a dummy read to turn on the internal reference voltage */
+	/* MUST lock the SSP  before accessing it */
+	adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	
+	//FJB
+	adsContext->chipselect_enable();
+	
+	adsContext->write(ads784x_sspContext, ADS_784x_READ_BATTERY);
+	sample = adsContext->read(ads784x_sspContext);
+	/* MUST unlock the SSP  after it has been locked */
+	adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	udelay(100);	/* wait until the reference voltage settle */
+
+	sample = 0;
+	for (count = 0; count < 3; count++) {
+		/* MUST lock the SSP  before accessing it */
+		adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+		adsContext->write(ads784x_sspContext, ADS_784x_READ_BATTERY);
+		sample += adsContext->read(ads784x_sspContext);
+		/* MUST unlock the SSP  after it has been locked */
+		adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	}       
+	sample /= count;
+	milliVolts = (sample * 1000 * 10) / 4096;
+	volts = milliVolts / 1000;
+	hundredthsVolts = (milliVolts - (volts * 1000)) / 10;
+	size = sprintf(buf, "battery: %i  %i.%02iV\n", sample, volts, hundredthsVolts);
+
+	/* Do a dummy read to turn off the internal reference voltage */
+	/* MUST lock the SSP  before accessing it */
+	adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	adsContext->write(ads784x_sspContext, ADS_784x_READ_X);
+	sample = adsContext->read(ads784x_sspContext);
+	
+	//FJB
+	adsContext->chipselect_disable();
+	
+	/* MUST unlock the SSP  after it has been locked */
+	adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+
+	/* Restore the interrupt enable state */
+	if (last_irq_state) {
+		udelay(100);	/* Wait until the pen down interrupt settles */
+		/* MUST lock the SSP  before accessing it */
+		adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+		adsContext->enable_pen_down_irq(ads784x_sspContext);
+		/* MUST unlock the SSP  after it has been locked */
+		adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	}
+	vdprintk("LEAVE: ads_784x_proc_battery_read(len=%d)\n", len);
+
+	return(size);
+}
+#endif
+
+#ifdef PROC_TEMPERATURE
+/**********************************************************************
+* ads_784x_proc_temperature_read
+**********************************************************************/
+static int ads_784x_proc_temperature_read(char *buf, char **start,
+		off_t offset, int len, int *eof, void *unused)
+{
+	adsContext_t *adsContext = &adsContext_l;
+	void *ads784x_sspContext = adsContext->sspContext;
+	int size;
+	int count;
+	int C10, F10;
+	int sample1;
+	int sample91;
+	int last_irq_state;
+
+	vdprintk("ENTER: ads_784x_proc_temperature_read(len=%d)\n", len);
+	/*
+	* Reading the ADS784X takes the part out of pen down interrupt mode
+	* causing spurious pen down interrupts. So we must disable 
+	* pen down interrupts while reading temperature.
+	*/
+	last_irq_state = adsContext->disable_pen_down_irq(ads784x_sspContext);
+
+	/* do a dummy read to turn on the internal reference voltage */
+	/* MUST lock the SSP  before accessing it */
+	adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	
+	//FJB
+	adsContext->chipselect_enable();
+	
+	adsContext->write(ads784x_sspContext, ADS_784x_READ_TEMP0);
+	sample1 = adsContext->read(ads784x_sspContext);
+	/* MUST unlock the SSP  after it has been locked */
+	adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	udelay(100);	/* wait until the reference voltage settle */
+
+	sample1  = 0;
+	sample91 = 0;
+	/* read the temperature values */
+	for (count = 0; count < 3; count++) {
+		/* MUST lock the SSP  before accessing it */
+		adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+		adsContext->write(ads784x_sspContext, ADS_784x_READ_TEMP0);
+		sample1  += adsContext->read(ads784x_sspContext);
+		adsContext->write(ads784x_sspContext, ADS_784x_READ_TEMP1);
+		sample91 += adsContext->read(ads784x_sspContext);
+		/* MUST unlock the SSP  after it has been locked */
+		adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	}
+	/* average values */
+	sample1 /= count;
+	sample91 /= count;
+
+	C10 = (((sample91 - sample1) * (25 * 2573)) / 4095) - 2730;
+	F10 = (C10*9)/5 + 320;
+
+	size = sprintf(buf, "Temperature: %iC, %iF\n", (C10+5)/10, (F10+5)/10);
+
+	/* do a dummy read to turn off the internal reference voltage */
+	/* MUST lock the SSP  before accessing it */
+	adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	adsContext->write(ads784x_sspContext, ADS_784x_READ_X);
+	sample1 = adsContext->read(ads784x_sspContext);
+	
+	//FJB
+	adsContext->chipselect_disable();
+	
+	/* MUST unlock the SSP  after it has been locked */
+	adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+
+	/* restore the interrupt enable state */
+	if (last_irq_state) {
+		udelay(100);	/* wait until the pen down interrupt settles */
+		/* MUST lock the SSP  before accessing it */
+		adsContext->lock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+		adsContext->enable_pen_down_irq(ads784x_sspContext);
+		/* MUST unlock the SSP  after it has been locked */
+		adsContext->unlock(ads784x_sspContext, SSP_DEV_TOUCHSCREEN);
+	}
+	vdprintk("LEAVE: ads_784x_proc_temperature_read(len=%d)\n", len);
+
+	return(size);
+}
+#endif
+
+/**********************************************************************
+* Function: ads_784x_make_ssp_association
+*
+* Purpose:
+*   Make the association between the eeprom driver and the ssp driver
+**********************************************************************/
+static int ads_784x__make_ssp_association(adsContext_t *adsContext)
+{
+    int sts = 0;
+    void *vp;
+
+/* NOTE: -EOPNOTSUPP == Operation not supported on transport endpoint */
+#define ASSOCIATION_ERROR	-EOPNOTSUPP
+
+	dprintk("ENTER: ads_784x_make_ssp_association()\n");
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "sspContext");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->sspContext = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "write");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->write = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "read");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->read = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "enable_pen_down_irq");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->enable_pen_down_irq = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "disable_pen_down_irq");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->disable_pen_down_irq = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "is_pen_down");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->is_pen_down = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "lock");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->lock = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "unlock");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->unlock = vp;
+	
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "chipselect_enable");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->chipselect_enable = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "chipselect_disable");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->chipselect_disable = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_TOUCHSCREEN, "chipselect_manual");
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+	adsContext->chipselect_manual = vp;
+
+	/* Note: The following need reset to NULL when we are finished */
+
+	vp = ssp_provide_pointer(SSP_DEV_TOUCHSCREEN, "irq_wait_ptr",
+			&(adsContext->irq_wait));
+	if ( ! vp )
+		sts = ASSOCIATION_ERROR;
+
+	dprintk("LEAVE: ads_784x_make_ssp_association(%d)\n", sts);
+
+	return(sts);
+}
+
+/**********************************************************************
+* Function: ads_784x_init
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+static int __init ads_784x_init(void)
+{
+	adsContext_t *adsContext = &adsContext_l;
+	int sts = -ENODEV;
+
+	vdprintk("ENTER: ads_784x_init()\n");
+	init_waitqueue_head(&adsContext->read_wait);
+	/* Retrieve the service information from the SSP driver */
+	sts = ads_784x__make_ssp_association(adsContext);
+	if (sts == 0) {
+		void *sspContext = adsContext->sspContext;
+
+		/* Start the ADS polling thread */
+		lock_kernel();
+		if (adsContext->rtask == NULL) {
+			init_completion(&adsContext->complete);
+			init_waitqueue_head(&adsContext->irq_wait);
+			sts = kernel_thread(ads_784x_thread, adsContext,
+						CLONE_FS | CLONE_FILES);
+			if (sts >= 0) {
+				sts = 0;
+				/* Only do this is the tread started correctly */
+				wait_for_completion(&adsContext->complete);
+			}
+		}
+		unlock_kernel();
+
+		/* MUST lock the SSP  before accessing it */
+		adsContext->lock(sspContext, SSP_DEV_TOUCHSCREEN);
+		adsContext->chipselect_manual();
+		adsContext->write(sspContext, ADS_784x_INIT);
+		adsContext->read(sspContext);	/* dummy read */
+		/* MUST unlock the SSP  after it has been locked */
+		adsContext->unlock(sspContext, SSP_DEV_TOUCHSCREEN);
+
+		sts = misc_register(&ads_784x_dev);
+
+#ifdef PROC_BATTERY
+		ads_784x_proc_battery = create_proc_entry("battery", 0, 0);
+		if (ads_784x_proc_battery) {
+			ads_784x_proc_battery->read_proc = ads_784x_proc_battery_read;
+		} else {
+			printk(KERN_ERR "%s: unable to register /proc/battery\n", DRVNAME);
+		}
+#endif
+#ifdef PROC_TEMPERATURE
+		ads_784x_proc_temperature = create_proc_entry("temperature", 0, 0);
+		if (ads_784x_proc_temperature) {
+			ads_784x_proc_temperature->read_proc = ads_784x_proc_temperature_read;
+		} else {
+			printk(KERN_ERR "%s: unable to register /proc/temperature\n", DRVNAME);
+		}
+#endif
+	}
+
+	vdprintk("LEAVE: ads_784x_init()\n");
+	return(sts);
+}
+
+/**********************************************************************
+* Function: ads_784x_exit
+*
+* Purpose:
+*	Un-Register & Cleanup the module
+**********************************************************************/
+static void ads_784x_exit(void)
+{
+	adsContext_t *adsContext = &adsContext_l;
+
+	vdprintk("ENTER: ads_784x_exit()\n");
+
+	if (adsContext->rtask) {
+		send_sig(SIGKILL, adsContext->rtask, 1);
+		schedule();
+	}
+
+	vdprintk("ads_784x_exit(): misc_deregister()\n");
+	misc_deregister(&ads_784x_dev);
+
+	/* Back out the pointer(s) we gave to the SSP driver */
+	(void) ssp_provide_pointer(SSP_DEV_TOUCHSCREEN, "irq_wait_ptr", NULL);
+
+#ifdef PROC_BATTERY
+	remove_proc_entry("battery", NULL);
+#endif
+#ifdef PROC_TEMPERATURE
+	remove_proc_entry("temperature", NULL);
+#endif
+
+	vdprintk("LEAVE: ads_784x_exit()\n");
+
+	return;
+}
+
+module_init(ads_784x_init);
+module_exit(ads_784x_exit);
+
+MODULE_AUTHOR("Jim Gleason");
+MODULE_DESCRIPTION("ADS 784x Driver for Sharp LH7x EVB");
+MODULE_LICENSE("Copyright (c) 2002 Lineo, Inc.");
+
diff -urN linux-2.4.26/drivers/misc/Config.in linux-2.4.26-vrs1-lnode80/drivers/misc/Config.in
--- linux-2.4.26/drivers/misc/Config.in	2005-11-02 16:54:22.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/Config.in	2005-11-02 17:37:31.000000000 -0400
@@ -15,3 +15,14 @@
 dep_tristate '  Touchscreen interface support' CONFIG_MCP_UCB1200_TS $CONFIG_MCP_UCB1200
 
 endmenu
+mainmenu_option next_comment
+
+comment 'Misc devices'
+
+if [ "$CONFIG_ARCH_LH79520" = "y" ]; then
+   tristate 'LH79590 touchscreen support' CONFIG_TOUCHSCREEN_LH79520
+   tristate 'LH79590 serial eeprom support' CONFIG_EEPROM_LH79520
+   tristate 'LH79590 7-segment support' CONFIG_7SEGMENT_LH79520
+fi
+
+endmenu
diff -urN linux-2.4.26/drivers/misc/eeprom-lh7x.c linux-2.4.26-vrs1-lnode80/drivers/misc/eeprom-lh7x.c
--- linux-2.4.26/drivers/misc/eeprom-lh7x.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/eeprom-lh7x.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,709 @@
+/* vi: set sw=4 ts=4 ai: */
+
+// #define MODULE
+
+#define READ_AFTER_WRITE
+
+/**********************************************************************
+*  linux/drivers/misc/eeprom-lh79x.c
+*
+*  Provide Microchip 93LC46B 64 x 16 EEPROM access for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License (GPL) version 2
+*  as published by the Free Software Foundation.
+*
+*  References:
+*     SHARP_EVB_DISPLAY_BOARD_REV2.pdf
+*     93LC46.pdf (Microchip 1K Microwire(R) EEPROM chip spec)
+*
+**********************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+
+#undef DEBUG
+#undef VERBOSE
+#define DRVNAME "eeprom-lh79x"
+#include <linux/verbosedebug.h>
+
+#include <linux/version.h>
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+#endif /* MODULE */
+
+#include <asm/arch/hardware.h>
+
+#include "ssp.h"
+
+#define SIXmsJIFFIES	(((HZ*6)/1000)+2)
+
+/**********************************************************************
+* Define EEPROM Control macros for "Microchip 93LC46B Microwire Serial EEPROM"
+**********************************************************************/
+
+/* Erase one 16 bit word at addr */
+#define EEPROM_ERASE(addr)	(0x01C0 | (addr & 0x3F))
+/* Erase entire eeprom */
+#define EEPROM_ERAL()		(0x0120)
+/* Erase/Write disable  */
+#define EEPROM_EWDS()		(0x0100)
+/* Erase/Write enable */
+#define EEPROM_EWEN()		(0x0130)
+/* Read one 16 bit word at addr */
+#define EEPROM_READ(addr)	(0x0180 | (addr & 0x3F))
+/* (Erase and) Write one 16 bit word at addr */
+#define EEPROM_WRITE(addr)	(0x0140 | (addr & 0x3F))
+/* Write one 16 bit value throught entire eeprom */
+#define EEPROM_WRAL()		(0x0110)
+
+/**********************************************************************
+* Define our eeprom context structure
+**********************************************************************/
+
+#define EEPROM_SIZE_16BIT	64
+#define EEPROM_SIZE_8BIT	128
+
+typedef struct eepromContext_t eepromContext_t;
+struct eepromContext_t {
+	union {
+		uint16_t w[EEPROM_SIZE_16BIT];	/* Actual device size */
+		u_char   c[EEPROM_SIZE_8BIT];
+	} cache;
+	union {
+		uint16_t w[EEPROM_SIZE_16BIT];	/* Actual device size */
+		u_char   c[EEPROM_SIZE_8BIT];
+	} state;
+	wait_queue_head_t read_and_write_wait;
+
+	void          *sspContext;
+	void          (*write) (void *sspContext, unsigned int data);
+	unsigned int  (*read) (void *sspContext);
+	int           (*lock)(void *sspContext, int device);
+	int           (*unlock)(void *sspContext, int device);
+	void          (*ssp_chipselect_automatic)(void);
+	void          (*ssp_chipselect_manual)(void);
+	void          (*ssp_chipselect_enable)(void);
+	void          (*ssp_chipselect_disable)(void);
+	void          (*ssp_flush_tx_fifo)(void *sspContext);
+	void          (*ssp_flush_rx_fifo)(void *sspContext);
+	void          (*ssp_busy_wait)(void);
+};
+static eepromContext_t eepromContext_l;
+
+#define CACHE_STATE_VALID_8			0x01
+#define CACHE_STATE_MODIFIED_8		0x02
+
+#define CACHE_STATE_VALID_16		0x0101
+#define CACHE_STATE_MODIFIED_16		0x0202
+
+/**********************************************************************
+* Function: eeprom_lh79x_erase_write_enable
+* Function: eeprom_lh79x_erase_write_disable
+**********************************************************************/
+static void
+eeprom_lh79x_erase_write_enable(eepromContext_t *eepromContext)
+{
+	void *sspContext = eepromContext->sspContext;
+
+	/* Lock the SSP before accessing it */
+	eepromContext->lock(sspContext, SSP_DEV_EEPROM);
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* EEPROM Writes must be done using manual control of the ChipSelect */
+	eepromContext->ssp_chipselect_manual();
+	eepromContext->ssp_chipselect_enable();
+
+	eepromContext->write(sspContext, EEPROM_EWEN());  /* Enable Erase/Write */
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* Reset back to automatic control of the EEPROM ChipSelect */
+	eepromContext->ssp_chipselect_disable();
+	eepromContext->ssp_chipselect_automatic();
+
+	/* Unlock the SSP after it has been locked */
+	eepromContext->unlock(sspContext, SSP_DEV_EEPROM);
+
+	return;
+}
+
+static void
+eeprom_lh79x_erase_write_disable(eepromContext_t *eepromContext)
+{
+	void *sspContext = eepromContext->sspContext;
+
+	/* Lock the SSP before accessing it */
+	eepromContext->lock(sspContext, SSP_DEV_EEPROM);
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* EEPROM Writes must be done using manual control of the ChipSelect */
+	eepromContext->ssp_chipselect_manual();
+	eepromContext->ssp_chipselect_enable();
+
+	eepromContext->write(sspContext, EEPROM_EWDS());  /* Disable Erase/Write */
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* Reset back to automatic control of the EEPROM ChipSelect */
+	eepromContext->ssp_chipselect_disable();
+	eepromContext->ssp_chipselect_automatic();
+
+	/* Unlock the SSP after it has been locked */
+	eepromContext->unlock(sspContext, SSP_DEV_EEPROM);
+
+	return;
+}
+
+/**********************************************************************
+* Function: eeprom_lh79x_read_device_word
+**********************************************************************/
+static void
+eeprom_lh79x_read_device_word(eepromContext_t *eepromContext, int offset_w)
+{
+	void *sspContext = eepromContext->sspContext;
+	uint16_t word = 0;
+
+	/* Lock the SSP before accessing it */
+	eepromContext->lock(sspContext, SSP_DEV_EEPROM);
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* EEPROM Reads must be done using manual control of the ChipSelect */
+	eepromContext->ssp_chipselect_manual();
+	eepromContext->ssp_chipselect_enable();
+
+	/* Read eeprom into cache */
+	/* Note: We shift to take care of the "dummy 0" the eeprom sends */
+	eepromContext->write(sspContext, (EEPROM_READ(offset_w))<<1);
+	/* Following is a Dummy/Invalid command to allow the eeprom to be read */
+	eepromContext->write(sspContext, 0);
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	word = eepromContext->read(sspContext);		/* Dummy Word */
+	word = eepromContext->read(sspContext);		/* Real Word */
+
+	/* Reset back to automatic control of the EEPROM ChipSelect */
+	eepromContext->ssp_chipselect_disable();
+	eepromContext->ssp_chipselect_automatic();
+
+	/* Unlock the SSP after it has been locked */
+	eepromContext->unlock(sspContext, SSP_DEV_EEPROM);
+
+	/* Modify the state of the cache data */
+	eepromContext->cache.w[offset_w] = word;
+	eepromContext->state.w[offset_w] |= CACHE_STATE_VALID_16;
+
+	schedule();		/* Give the rest of the system a chance to work */
+
+	return;
+}
+
+/**********************************************************************
+* Function: eeprom_lh79x_write_device_word
+**********************************************************************/
+static void
+eeprom_lh79x_write_device_word(eepromContext_t *eepromContext, int offset_w)
+{
+	void *sspContext = eepromContext->sspContext;
+	uint16_t word;
+	long timeoutJiffies;
+
+	/* Get the modified cache data to write to the eeprom */
+	word = eepromContext->cache.w[offset_w];
+
+	/* Lock the SSP before accessing it */
+	eepromContext->lock(sspContext, SSP_DEV_EEPROM);
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* EEPROM Writes must be done using manual control of the ChipSelect */
+	eepromContext->ssp_chipselect_manual();
+	eepromContext->ssp_chipselect_enable();
+
+	/* Write modified cache data to the eeprom */
+	eepromContext->write(sspContext, EEPROM_WRITE(offset_w));
+	eepromContext->write(sspContext, word);
+
+	/* Reset back to automatic control of the EEPROM ChipSelect */
+	eepromContext->ssp_chipselect_disable();
+	eepromContext->ssp_chipselect_automatic();
+
+	eepromContext->ssp_busy_wait(); /* Wait for the SSP to not be busy */
+	eepromContext->ssp_flush_rx_fifo(sspContext);
+
+	/* Unlock the SSP after it has been locked */
+	eepromContext->unlock(sspContext, SSP_DEV_EEPROM);
+
+	/* Modify the state of the cache data */
+	eepromContext->state.w[offset_w]  &= ~CACHE_STATE_MODIFIED_16;
+
+#ifdef READ_AFTER_WRITE
+	/* Force the modified cache data to be reread from the eeprom */
+	eepromContext->state.w[offset_w]  &= ~CACHE_STATE_VALID_16;
+#endif /* READ_AFTER_WRITE */
+
+	/* Cause ~ 6ms delay (actually does 10 on the Sharp LH79520) */
+	timeoutJiffies = SIXmsJIFFIES;
+	while (timeoutJiffies > 0) {
+		__set_current_state(TASK_UNINTERRUPTIBLE);
+		timeoutJiffies = schedule_timeout(timeoutJiffies);
+	}
+	// __set_current_state(TASK_RUNNING);
+
+	schedule();		/* Give the rest of the system a chance to work */
+
+	return;
+}
+
+/**********************************************************************
+* Function: eeprom_lh79x_read_device
+**********************************************************************/
+static void
+eeprom_lh79x_read_device(eepromContext_t *eepromContext)
+{
+	uint16_t *scwp;
+	int offset_w;
+
+	scwp = eepromContext->state.w;
+	for (offset_w = 0; offset_w < EEPROM_SIZE_16BIT; offset_w++) {
+		if ((*scwp & CACHE_STATE_VALID_16) != CACHE_STATE_VALID_16) {
+			eeprom_lh79x_read_device_word(eepromContext, offset_w);
+		}
+		scwp++;
+	}
+
+	return;
+}
+
+/**********************************************************************
+* Function: eeprom_lh79x_write_device
+**********************************************************************/
+static void
+eeprom_lh79x_write_device(eepromContext_t *eepromContext)
+{
+	uint16_t *scwp;
+	int offset_w;
+	int timeoutJiffies;
+
+	/* Enable erase/write of the eeprom */
+	eeprom_lh79x_erase_write_enable(eepromContext);
+
+	/* Just to get the timeouts in a desirable sequence */
+	/* and so we don't get a "partial" timeout we do the following... */
+	/* Cause ~ 6ms delay (actually does 10 on the Sharp LH79520) */
+	timeoutJiffies = SIXmsJIFFIES;
+	while (timeoutJiffies > 0) {
+		__set_current_state(TASK_UNINTERRUPTIBLE);
+		timeoutJiffies = schedule_timeout(timeoutJiffies);
+	}
+	// __set_current_state(TASK_RUNNING);
+
+	scwp = eepromContext->state.w;
+	for (offset_w = 0; offset_w < EEPROM_SIZE_16BIT; offset_w++) {
+		if (*scwp & CACHE_STATE_MODIFIED_16) {
+			eeprom_lh79x_write_device_word(eepromContext, offset_w);
+		}
+		scwp++;
+	}
+
+	/* Disable erase/write of the eeprom */
+	eeprom_lh79x_erase_write_disable(eepromContext);
+
+#ifdef READ_AFTER_WRITE
+	/*
+	* NOW ... Update the eeprom cache.
+	* ( Read the actual contents of the eeprom that were
+	* modified instead of relying on what we wrote. )
+	*/
+	eeprom_lh79x_read_device(eepromContext);
+#endif /* READ_AFTER_WRITE */
+
+	return;
+}
+
+/**********************************************************************
+* *****************************************************
+* *** User space "file operation" driver interfaces ***
+* *****************************************************
+* Function: lh79x_eeprom_llseek
+* Function: lh79x_eeprom_read
+* Function: lh79x_eeprom_write
+* Function: lh79x_eeprom_poll				( NOT USED --- YET )
+* Function: lh79x_eeprom_ioctl				( NOT USED --- YET )
+* Function: lh79x_eeprom_open
+* Function: lh79x_eeprom_flush				( NOT USED --- YET )
+* Function: lh79x_eeprom_release			( NOT USED --- YET )
+* Function: lh79x_eeprom_fsync				( NOT USED --- YET )
+* Function: lh79x_eeprom_fasync				( NOT USED --- YET )
+* Function: lh79x_eeprom_lock				( NOT USED --- YET )
+**********************************************************************/
+
+static loff_t
+lh79x_eeprom_llseek(struct file *filp, loff_t offset, int origin)
+{
+	// eepromContext_t *eepromContext = filp->private_data;
+	loff_t new_offset = -EINVAL;
+
+	switch (origin) {
+		case 0:		/* SEEK_SET == 0, Offset from the start */
+			new_offset = offset;
+			break;
+		case 1:		/* SEEK_CUR == 1, Offset from the current position */
+			new_offset = filp->f_pos + offset;
+			break;
+		case 2:		/* SEEK_END == 2, Offset from the end */
+			new_offset = EEPROM_SIZE_8BIT - offset;
+			break;
+	}
+	if ((new_offset < 0) || (new_offset > EEPROM_SIZE_8BIT)) {
+		new_offset = -EINVAL;
+	} else {
+		filp->f_pos = new_offset;
+	}
+
+	return(new_offset);
+}
+
+static ssize_t
+lh79x_eeprom_read(struct file *filp, char *buffer,
+		size_t count, loff_t *offsetp)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+	int err;
+
+	vdprintk("ENTER: lh79x_eeprom_read(%d:%d)\n", *offsetp, count);
+	/* Ensure we still have data to read (relative to the offset we are at) */
+	if (*offsetp < EEPROM_SIZE_8BIT) {
+		/* Adjust the size to be read if necessary */
+		if ((*offsetp + count) > EEPROM_SIZE_8BIT) {
+			count = EEPROM_SIZE_8BIT - *offsetp;
+		}
+		/* Ensure the eeprom cache is valid */
+		eeprom_lh79x_read_device(eepromContext);
+		/* Return the contents of the eeprom cache */
+		err = copy_to_user(buffer, &eepromContext->cache.c[*offsetp], count);
+		if ( ! err) {
+			*offsetp += count;
+			sts = count;
+		} else {
+			sts = -EFAULT;
+		}
+	}
+	vdprintk("LEAVE: lh79x_eeprom_read(%d)\n", sts);
+
+	return(sts);
+}
+
+static ssize_t
+lh79x_eeprom_write(struct file *filp, const char *buffer,
+		size_t count, loff_t *offsetp)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	u_char newcache_c[EEPROM_SIZE_8BIT];
+	int sts = 0;
+	int err;
+
+	vdprintk("ENTER: lh79x_eeprom_write(%d:%d)\n", *offsetp, count);
+	/* Ensure we still have room to write (relative to the offset we are at) */
+	if (*offsetp < EEPROM_SIZE_8BIT) {
+		/* Adjust the size to be written if necessary */
+		if ((*offsetp + count) > EEPROM_SIZE_8BIT) {
+			count = EEPROM_SIZE_8BIT - *offsetp;
+		}
+		/* Ensure the eeprom cache is valid to start with */
+		eeprom_lh79x_read_device(eepromContext);
+		/* Get the new contents of the eeprom cache */
+		err = copy_from_user(&newcache_c[*offsetp], buffer, count);
+		if ( ! err) {
+			u_char *ccp, *nccp, *sccp;
+			int i;
+			/*
+			* Transfer the new cache contents into the cache
+			* marking what has changed.
+			*/
+			ccp = &eepromContext->cache.c[*offsetp];
+			nccp = &newcache_c[*offsetp];
+			sccp = &eepromContext->state.c[*offsetp];
+			for (i = 0; i < count; i++) {
+				if (*ccp != *nccp) {
+					*ccp = *nccp;
+					*sccp |= CACHE_STATE_MODIFIED_8;
+				}
+				ccp++;
+				nccp++;
+				sccp++;
+			}
+			/* Write the modified cache into the eeprom */
+			eeprom_lh79x_write_device(eepromContext);
+			*offsetp += count;
+			sts = count;
+		} else {
+			sts = -EFAULT;
+		}
+	}
+	vdprintk("LEAVE: lh79x_eeprom_write(%d)\n", sts);
+
+	return(sts);
+}
+
+#if (0) /* NOT USED --- YET */
+static unsigned int
+lh79x_eeprom_poll(struct file *filp, struct poll_table_struct *wait)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+#if (0) /* NOT USED --- YET */
+static int
+lh79x_eeprom_ioctl(struct inode *, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+static int
+lh79x_eeprom_open(struct inode *inode, struct file *filp)
+{
+	eepromContext_t *eepromContext = &eepromContext_l;
+	int sts = 0;
+
+	filp->private_data = eepromContext;
+
+	return(sts);
+}
+
+#if (0) /* NOT USED --- YET */
+static int
+lh79x_eeprom_flush(struct file *filp)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+#if (0) /* NOT USED --- YET */
+static int
+lh79x_eeprom_release(struct inode *inode, struct file *filp)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+#if (0) /* NOT USED --- YET */
+static int
+lh79x_eeprom_fsync(struct file *filp, struct dentry *dentry, int datasync)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+#if (0) /* NOT USED --- YET */
+static int
+lh79x_eeprom_fasync(int fd, struct file *filp, int on)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+#if (0) /* NOT USED --- YET */
+static int
+lh79x_eeprom_lock(struct file *filp, int XXX, struct file_lock *file_lock)
+{
+	eepromContext_t *eepromContext = filp->private_data;
+	int sts = 0;
+
+	return(sts);
+}
+#endif /* NOT USED --- YET */
+
+/**********************************************************************
+* Define (fill in) the user space file operations for this driver
+* and initialize the eeprom driver as a "miscdevice":
+*       Character device
+*       Major(10) --- Non-serial mice, misc features
+*       Minor(22) --- /dev/eeprom		( Microchip 93LC46B 64 x 16 EEPROM )
+**********************************************************************/
+static struct file_operations lh79x_eeprom_fops = {
+	owner:      		THIS_MODULE,
+	llseek:				lh79x_eeprom_llseek,
+	read:				lh79x_eeprom_read,
+	write:				lh79x_eeprom_write,
+//	poll:				lh79x_eeprom_poll,
+//	ioctl:				lh79x_eeprom_ioctl,
+	open:				lh79x_eeprom_open,
+//	flush:				lh79x_eeprom_flush,
+//	release:			lh79x_eeprom_release,
+//	fsync:				lh79x_eeprom_fsync,
+//	fasync:				lh79x_eeprom_fasync,
+//	lock:				lh79x_eeprom_lock,
+};
+
+static struct miscdevice lh79x_eeprom_dev = {
+minor: 22,
+name: "eeprom",
+fops: &lh79x_eeprom_fops,
+};
+
+/**********************************************************************
+* Function: lh79x_eeprom_make_ssp_association
+*
+* Purpose:
+*	Make the association between the eeprom driver and the ssp driver
+**********************************************************************/
+static int lh79x_eeprom_make_ssp_association(eepromContext_t *eepromContext)
+{
+	int sts = 0;
+	void *vp;
+
+/* NOTE: -EOPNOTSUPP == Operation not supported on transport endpoint */
+#define ASSOCIATION_ERROR   -EOPNOTSUPP
+
+	dprintk("ENTER: lh79x_eeprom_make_ssp_association()\n");
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "sspContext");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->sspContext = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "write");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->write = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "read");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->read = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "lock");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->lock = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "unlock");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->unlock = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "chipselect_enable");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_chipselect_enable = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "chipselect_disable");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_chipselect_disable = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "chipselect_manual");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_chipselect_manual = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "chipselect_automatic");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_chipselect_automatic = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "flush_tx_fifo");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_flush_tx_fifo = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "flush_rx_fifo");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_flush_rx_fifo = vp;
+
+	vp = ssp_request_pointer(SSP_DEV_EEPROM, "ssp_busy_wait");
+	if ( ! vp ) 
+		sts = ASSOCIATION_ERROR;
+	eepromContext->ssp_busy_wait = vp;
+
+	dprintk("LEAVE: lh79x_eeprom_make_ssp_association(%d)\n", sts);
+
+	return(sts);
+}
+
+/**********************************************************************
+* Function: lh79x_eeprom_init
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+static int lh79x_eeprom_init(void)
+{
+	eepromContext_t *eepromContext = &eepromContext_l;
+	int sts = 0;
+	dprintk("ENTER: lh79x_eeprom_init()\n");
+	init_waitqueue_head(&eepromContext->read_and_write_wait);
+	/* Retrieve the service information from the SSP driver */
+	sts = lh79x_eeprom_make_ssp_association(eepromContext);
+	if (sts == 0) {
+		/* Ensure the eeprom cache is valid */
+		eeprom_lh79x_read_device(eepromContext);
+		sts = misc_register(&lh79x_eeprom_dev);
+	}
+	dprintk("LEAVE: lh79x_eeprom_init(%d)\n", sts);
+	return(sts);
+}
+
+/**********************************************************************
+* Function: lh79x_eeprom_exit
+*
+* Purpose:
+*	Un-Register & Cleanup the module
+**********************************************************************/
+static void lh79x_eeprom_exit(void)
+{
+	dprintk("ENTER: lh79x_eeprom_exit()\n");
+	misc_deregister(&lh79x_eeprom_dev);
+	dprintk("LEAVE: lh79x_eeprom_exit()\n");
+	return;
+}
+
+module_init(lh79x_eeprom_init);
+module_exit(lh79x_eeprom_exit);
+
+MODULE_AUTHOR("Jim Gleason / Lineo, Inc.");
+MODULE_DESCRIPTION("Microchip 93LC46B 64 x 16 EEPROM access for LH7x EVB");
+MODULE_LICENSE("Copyright (c) 2002 Lineo, Inc.");
+
diff -urN linux-2.4.26/drivers/misc/lh7x-7seg.c linux-2.4.26-vrs1-lnode80/drivers/misc/lh7x-7seg.c
--- linux-2.4.26/drivers/misc/lh7x-7seg.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/lh7x-7seg.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,649 @@
+/* vi: set sw=4 ts=4 ai: */
+
+//#define MODULE
+
+/**********************************************************************
+*  linux/drivers/misc/lh7x-7seg.c
+*
+*  Provide ADS_784x 7-Segment access for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License (GPL) version 2
+*  as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+/**********************************************************************
+* To light up the 7-segment display, write a 16-bit value to
+*
+*	cpld->seven_seg.
+*
+* The high-order byte is the most significant 7-segment digit,
+* and the low-order byte is the lsb.
+*
+* NOTE: The 7-segment display bars are bit-mapped.
+* NOTE: The 7-segment display bars are ACTIVE LOW.
+*
+*     _   ==   a
+*    | |  ==  f b
+*     -   ==   g
+*    | |  ==  e c
+*     -.  ==   d dot
+*
+*    a    0x01
+*    b    0x02
+*    c    0x04
+*    d    0x08
+*    e    0x10
+*    f    0x20
+*    g    0x40
+*    dot  0x80		(also known as dp)
+*
+* The data to write looks like this:
+*
+*	static u_char lednum[] =
+*	{ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,  // 0-7
+*	  0x80, 0x98, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E,  // 8-F
+*	  0xBF, // hyphen
+*	  0xFF, // (blank)
+*	};
+*
+* SO - to make "7F" show up, do this:
+*
+*	cpld->seven_seg = 0xf88e;
+*
+* NOTE: When read, the 7-segment display does not return valid data.
+*
+**********************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+
+#undef DEBUG
+#undef VERBOSE
+#define DRVNAME "lh7x-7seg"
+#include <linux/verbosedebug.h>
+
+#include <linux/version.h>
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+#endif /* MODULE */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/cpld.h>
+#include <asm/arch/lh7x-7seg.h>
+
+static cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+/**********************************************************************
+* Define our Seven Segment context structure
+**********************************************************************/
+typedef struct sevenSegmentContext_t sevenSegmentContext_t;
+struct sevenSegmentContext_t {
+	struct fasync_struct *fasync;
+	wait_queue_head_t read_and_write_wait;
+
+	int inEscape;		/* 1 == We are in an escape sequence, 0 == NOT */
+	int accessMode;		/* See ACCESSMODE_xxx definitions below */
+	int rawData;		/* Raw == 1, Cooked == 0 */
+	uint16_t			currentRawVal;
+};
+static sevenSegmentContext_t sevenSegmentContext_l;
+
+#define ESCAPE		27
+
+#define ACCESSMODE_SHIFT			0
+#define ACCESSMODE_LSB			1
+#define ACCESSMODE_MSB			2
+#define ACCESSMODE_DAFAULT		ACCESSMODE_SHIFT
+
+/**********************************************************************
+* Define our Seven Segment Data
+**********************************************************************/
+
+typedef struct sevenSegmentData_t sevenSegmentData_t;
+struct sevenSegmentData_t {
+	int val;
+	u_char raw_val;
+};
+
+#define SSD_BLANK	((u_char)~(0x00))
+
+static sevenSegmentData_t sevenSegmentData[] = {
+	{'0',  (u_char)~(SSD_A | SSD_B | SSD_C | SSD_D | SSD_E | SSD_F) },
+	{'1',  (u_char)~(SSD_B | SSD_C) },
+	{'2',  (u_char)~(SSD_A | SSD_B | SSD_G | SSD_E | SSD_D) },
+	{'3',  (u_char)~(SSD_A | SSD_B | SSD_G | SSD_C | SSD_D) },
+	{'4',  (u_char)~(SSD_F | SSD_G | SSD_B | SSD_C) },
+	{'5',  (u_char)~(SSD_A | SSD_F | SSD_G | SSD_C | SSD_D) },
+	{'6',  (u_char)~(SSD_A | SSD_F | SSD_E | SSD_D | SSD_C | SSD_G) },
+	{'7',  (u_char)~(SSD_A | SSD_B | SSD_C) },
+	{'8',  (u_char)~(SSD_A | SSD_B | SSD_C | SSD_D | SSD_E | SSD_F | SSD_G) },
+	{'9',  (u_char)~(SSD_G | SSD_F | SSD_A | SSD_B | SSD_C) },
+	{'A',  (u_char)~(SSD_E | SSD_F | SSD_A | SSD_B | SSD_C | SSD_G) },
+	{'a',  (u_char)~(SSD_E | SSD_F | SSD_A | SSD_B | SSD_C | SSD_G) },
+	{'B',  (u_char)~(SSD_F | SSD_E | SSD_D | SSD_C | SSD_G) },
+	{'b',  (u_char)~(SSD_F | SSD_E | SSD_D | SSD_C | SSD_G) },
+	{'C',  (u_char)~(SSD_A | SSD_F | SSD_E | SSD_D) },
+	{'c',  (u_char)~(SSD_A | SSD_F | SSD_E | SSD_D) },
+	{'D',  (u_char)~(SSD_B | SSD_C | SSD_D | SSD_E | SSD_G) },
+	{'d',  (u_char)~(SSD_B | SSD_C | SSD_D | SSD_E | SSD_G) },
+	{'E',  (u_char)~(SSD_A | SSD_F | SSD_G | SSD_E | SSD_D) },
+	{'e',  (u_char)~(SSD_A | SSD_F | SSD_G | SSD_E | SSD_D) },
+	{'F',  (u_char)~(SSD_A | SSD_F | SSD_G | SSD_E) },
+	{'f',  (u_char)~(SSD_A | SSD_F | SSD_G | SSD_E) },
+	{'H',  (u_char)~(SSD_F | SSD_E | SSD_G | SSD_B | SSD_C) },
+	{'h',  (u_char)~(SSD_F | SSD_E | SSD_G | SSD_B | SSD_C) },
+	{'I',  (u_char)~(SSD_F | SSD_E) },
+	{'i',  (u_char)~(SSD_F | SSD_E) },
+	{'Y',  (u_char)~(SSD_F | SSD_G | SSD_B | SSD_C | SSD_D) },
+	{'y',  (u_char)~(SSD_F | SSD_G | SSD_B | SSD_C | SSD_D) },
+	{'-',  (u_char)~(SSD_G) },
+	{'_',  (u_char)~(SSD_D) },
+	{'.',  (u_char)~(SSD_DOT) },
+	{' ',  SSD_BLANK },
+	{0x00, SSD_BLANK },
+	{  -1, (u_char)~(0x00) }		/* End Of Data --- Must Be Last */
+};
+
+/**********************************************************************
+* Function: val_to_raw_val
+**********************************************************************/
+static u_char val_to_raw_val(u_char val)
+{
+	sevenSegmentData_t *data;
+	u_char raw_val = 0xFF;	/* Assume a blank if not found */
+	for (data = sevenSegmentData; data->val != -1; data++) {
+		if (val == data->val) {
+			raw_val = data->raw_val;
+			break;
+		}
+	}
+	return(raw_val);
+}
+
+/**********************************************************************
+* Function: raw_val_to_val
+**********************************************************************/
+static u_char raw_val_to_val(u_char raw_val)
+{
+	sevenSegmentData_t *data;
+	u_char val = ' ';	/* Assume a blank if not found */
+	for (data = sevenSegmentData; data->val != -1; data++) {
+		if (raw_val == data->raw_val) {
+			val = data->val;
+			break;
+		}
+	}
+	return(val);
+}
+
+/**********************************************************************
+* Function: lh79x_7seg_read_raw_display
+* Function: lh79x_7seg_read_raw_display_lsb
+* Function: lh79x_7seg_read_raw_display_msb
+**********************************************************************/
+uint16_t lh79x_7seg_read_raw_display(void)
+{
+	sevenSegmentContext_t *sevenSegmentContext = &sevenSegmentContext_l;
+	uint16_t raw_val;
+
+	/*
+	* NOTE: The device does not read so we have to remember...
+	*/
+	raw_val = sevenSegmentContext->currentRawVal;
+	vdprintk("lh79x_7seg_read_raw_display(0x%04X)\n", raw_val);
+
+	return(raw_val);
+}
+
+u_char lh79x_7seg_read_raw_display_lsb(void)
+{
+	uint16_t raw_val;
+	u_char raw_lsb;
+
+	raw_val = lh79x_7seg_read_raw_display();
+	raw_lsb = (u_char)(raw_val & 0xFF);
+
+	return(raw_lsb);
+}
+
+u_char lh79x_7seg_read_raw_display_msb(void)
+{
+	uint16_t raw_val;
+	u_char raw_msb;
+
+	raw_val = lh79x_7seg_read_raw_display();
+	raw_msb = (u_char)((raw_val >> 8) & 0xFF);
+
+	return(raw_msb);
+}
+
+/**********************************************************************
+* Function: lh79x_7seg_read_display
+* Function: lh79x_7seg_read_display_lsb
+* Function: lh79x_7seg_read_display_msb
+**********************************************************************/
+uint16_t lh79x_7seg_read_display(void)
+{
+	uint16_t raw_val, val;
+	u_char raw_lsb, lsb;
+	u_char raw_msb, msb;
+
+	raw_val = lh79x_7seg_read_raw_display();
+	raw_lsb = (u_char)( raw_val       & 0xFF);
+	raw_msb = (u_char)((raw_val >> 8) & 0xFF);
+	lsb = raw_val_to_val(raw_lsb);
+	msb = raw_val_to_val(raw_msb);
+	val = (uint16_t)((msb << 8) | lsb);
+
+	return(val);
+}
+
+u_char lh79x_7seg_read_display_lsb(void)
+{
+	u_char raw_lsb, lsb;
+
+	raw_lsb = lh79x_7seg_read_raw_display_lsb();
+	lsb = raw_val_to_val(raw_lsb);
+
+	return(lsb);
+}
+
+u_char lh79x_7seg_read_display_msb(void)
+{
+	u_char raw_msb, msb;
+
+	raw_msb = lh79x_7seg_read_raw_display_msb();
+	msb = raw_val_to_val(raw_msb);
+
+	return(msb);
+}
+
+/**********************************************************************
+* Function: lh79x_7seg_write_raw_display
+* Function: lh79x_7seg_write_raw_display_lsb
+* Function: lh79x_7seg_write_raw_display_msb
+**********************************************************************/
+void lh79x_7seg_write_raw_display(uint16_t raw_val)
+{
+	sevenSegmentContext_t *sevenSegmentContext = &sevenSegmentContext_l;
+
+	vdprintk("lh79x_7seg_write_raw_display(0x%04X)\n", raw_val);
+	/*
+	* NOTE: The device does not read so we have to remember...
+	*/
+	sevenSegmentContext->currentRawVal = raw_val;
+	cpld->seven_seg = raw_val;
+
+	return;
+}
+
+void lh79x_7seg_write_raw_display_lsb(u_char raw_lsb)
+{
+	uint16_t raw_val;
+
+	raw_val = lh79x_7seg_read_raw_display();
+	raw_val &= 0xFF00;
+	raw_val &= ((uint16_t)raw_lsb) & 0x00FF;
+	lh79x_7seg_write_raw_display(raw_val);
+
+	return;
+}
+
+void lh79x_7seg_write_raw_display_msb(u_char raw_msb)
+{
+	uint16_t raw_val;
+
+	raw_val = lh79x_7seg_read_raw_display();
+	raw_val &= 0x00FF;
+	raw_val &= (((uint16_t)raw_msb) << 8) & 0xFF00;
+	lh79x_7seg_write_raw_display(raw_val);
+
+	return;
+}
+
+/**********************************************************************
+* Function: lh79x_7seg_write_display
+* Function: lh79x_7seg_write_display_lsb
+* Function: lh79x_7seg_write_display_msb
+* Function: lh79x_7seg_write_display_str
+**********************************************************************/
+void lh79x_7seg_write_display(uint16_t val)
+{
+	u_char raw_lsb, lsb;
+	u_char raw_msb, msb;
+	uint16_t raw_val;
+
+	lsb = (u_char)( val       & 0xFF);
+	msb = (u_char)((val >> 8) & 0xFF);
+	raw_lsb = val_to_raw_val(lsb);
+	raw_msb = val_to_raw_val(msb);
+	raw_val = (uint16_t)((raw_msb << 8) | raw_lsb);
+	lh79x_7seg_write_raw_display(raw_val);
+
+	return;
+}
+
+void lh79x_7seg_write_display_lsb(u_char lsb)
+{
+	u_char raw_lsb;
+
+	raw_lsb = val_to_raw_val(lsb);
+	lh79x_7seg_write_raw_display_lsb(raw_lsb);
+
+	return;
+}
+
+void lh79x_7seg_write_display_msb(u_char msb)
+{
+	u_char raw_msb;
+
+	raw_msb = val_to_raw_val(msb);
+	lh79x_7seg_write_raw_display_msb(raw_msb);
+
+	return;
+}
+
+void lh79x_7seg_write_display_str(u_char *str)
+{
+	uint16_t val;
+	uint16_t c16;
+	u_char c;
+
+	if (str) {
+		/* This is basically a read, shift, write lsb loop */
+		for ( ; *str; str++) {
+			c = *str;
+			if (c == '\n') continue;
+			if (c == '\r') continue;
+			val = lh79x_7seg_read_display();
+			val <<= 8;
+			val &= 0xFF00;
+			c16 = c & 0x00FF;
+			val |= c16;
+			lh79x_7seg_write_display(val);
+		}
+	}
+	return;
+}
+
+/**********************************************************************
+* Function: sevenSegment_read
+* Function: sevenSegment_poll
+* Function: sevenSegment_open
+* Function: sevenSegment_fasync
+* Function: sevenSegment_release
+* ************************************
+* *** User space driver interfaces ***
+* ************************************
+**********************************************************************/
+
+/*
+* NOTE: The read algorithm is wide open for interpretation.
+*       I am not sure what the behaviour ought to be here.
+*/
+static ssize_t sevenSegment_read(struct file *filp, char *buffer,
+		size_t _count, loff_t *ppos)
+{
+	sevenSegmentContext_t *sevenSegmentContext = filp->private_data;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t sizeRead = 0;
+	char *ptr = buffer;
+	int err = 0;
+	int count = (int)_count;
+	uint16_t c16;
+	u_char c;
+	int dataSize;
+	int dataByteCount;
+
+	switch (sevenSegmentContext->accessMode) {
+		case ACCESSMODE_LSB:
+		case ACCESSMODE_MSB:
+			dataSize = 8;
+			break;
+		case ACCESSMODE_SHIFT:
+		default:
+			dataSize = 16;
+			break;
+	}
+	dataByteCount = dataSize / 8;
+
+	add_wait_queue(&sevenSegmentContext->read_and_write_wait, &wait);
+	while (count >= dataByteCount) {
+		err = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		/* NOTE: We always have data */
+		switch (sevenSegmentContext->accessMode) {
+			case ACCESSMODE_LSB:
+				c = lh79x_7seg_read_display_lsb();
+				break;
+			case ACCESSMODE_MSB:
+				c = lh79x_7seg_read_display_msb();
+				break;
+			case ACCESSMODE_SHIFT:
+			default:
+				c16 = lh79x_7seg_read_display();
+				/* Flip the bytes so they get returned in the correct order */
+				c = (u_char)(c16 >> 8);
+				c16 = ((c16 << 8) & 0xFF00) | ((uint16_t)c);
+				break;
+		}
+		if (dataSize == 8) {
+			err = copy_to_user(ptr, &c, sizeof(c));
+			if (err)
+				break;
+			ptr += sizeof(c);
+			count -= sizeof(c);	
+		} else /* (dataSize == 16) */ {
+			err = copy_to_user(ptr, &c16, sizeof(c16));
+			if (err)
+				break;
+			ptr += sizeof(c16);
+			count -= sizeof(c16);	
+		}
+	}
+	remove_wait_queue(&sevenSegmentContext->read_and_write_wait, &wait);
+	sizeRead = (ptr == buffer ? err : ptr - buffer);
+	return(sizeRead);
+}
+
+static ssize_t sevenSegment_write(struct file *filp, const char *buffer,
+		size_t _count, loff_t *ppos)
+{
+	sevenSegmentContext_t *sevenSegmentContext = filp->private_data;
+	ssize_t sizeWritten = 0;
+	const char *ptr = buffer;
+	int count;
+	u_char c;
+	uint16_t c16;
+	uint16_t val;
+	int err = 0;
+
+	for (count = (int)_count; count > 0; count--) {
+		/* NOTE: We always have room for the data */
+		get_user(c, ptr++);
+		/* Ignore new_line or carriage_return characters */
+		if (c == '\n') continue;
+		if (c == '\r') continue;
+		vdprintk("JMG: (e:%d, r:%d, a:%d) Attempting to write (%c) == (0x%02X)\n",
+				sevenSegmentContext->inEscape,
+				sevenSegmentContext->rawData,
+				sevenSegmentContext->accessMode,
+				c, c);
+		if (sevenSegmentContext->inEscape) {
+			sevenSegmentContext->inEscape = 0;
+			if ( c != ESCAPE ) {
+				switch (c) {
+					case 'r':	/* Raw Data */
+					case 'R':	/* Raw Data */
+						sevenSegmentContext->rawData = 1;
+						break;
+					case 'c':	/* Coooked Data */
+					case 'C':	/* Coooked Data */
+						sevenSegmentContext->rawData = 0;
+						break;
+					case 'l':	/* LSB */
+					case 'L':	/* LSB */
+						sevenSegmentContext->accessMode = ACCESSMODE_LSB;
+						break;
+					case 'm':	/* MSB */
+					case 'M':	/* MSB */
+						sevenSegmentContext->accessMode = ACCESSMODE_MSB;
+						break;
+					case 's':	/* Shift */
+					case 'S':	/* Shift */
+					case 'n':	/* Normal */
+					case 'N':	/* Normal */
+					default:
+						sevenSegmentContext->accessMode = ACCESSMODE_SHIFT;
+				}
+				continue;
+			}
+		} else if ( c == ESCAPE ) {
+			sevenSegmentContext->inEscape = 1;
+			continue;
+		}
+		if (sevenSegmentContext->rawData) {
+			val = lh79x_7seg_read_raw_display();
+		} else {
+			val = lh79x_7seg_read_display();
+		}
+		switch (sevenSegmentContext->accessMode) {
+			case ACCESSMODE_LSB:
+				val &= 0xFF00;
+				c16 = c & 0x00FF;
+				val |= c16;
+				break;
+			case ACCESSMODE_MSB:
+				val &= 0x00FF;
+				c16 = ((uint16_t)c << 8) & 0xFF00;
+				val |= c16;
+				break;
+			case ACCESSMODE_SHIFT:
+			default:
+				val <<= 8;
+				val &= 0xFF00;
+				c16 = c & 0x00FF;
+				val |= c16;
+				break;
+		}
+		vdprintk("JMG: Writing (0x%04X)\n", val);
+		if (sevenSegmentContext->rawData) {
+			lh79x_7seg_write_raw_display(val);
+		} else {
+			lh79x_7seg_write_display(val);
+		}
+	}
+	filp->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+	sizeWritten = (ptr == buffer ? err : ptr - buffer);
+	return(sizeWritten);
+}
+
+static unsigned int sevenSegment_poll(struct file *filp, poll_table *wait)
+{
+	sevenSegmentContext_t *sevenSegmentContext = filp->private_data;
+	/* We ALWAYS have data waiting ;) */
+	int sts = POLLIN | POLLRDNORM;
+	poll_wait(filp, &sevenSegmentContext->read_and_write_wait, wait);
+	return(sts);
+}
+
+static int sevenSegment_open(struct inode *inode, struct file *filp)
+{
+	sevenSegmentContext_t *sevenSegmentContext = &sevenSegmentContext_l;
+	int sts = 0;
+	filp->private_data = sevenSegmentContext;
+	return(sts);
+}
+
+static int sevenSegment_fasync(int fd, struct file *filp, int on)
+{
+	sevenSegmentContext_t *sevenSegmentContext = filp->private_data;
+	int sts;
+	sts = fasync_helper(fd, filp, on, &sevenSegmentContext->fasync);
+	return(sts);
+}
+
+static int sevenSegment_release(struct inode *inode, struct file *filp)
+{
+	lock_kernel();
+	sevenSegment_fasync(-1, filp, 0);
+	unlock_kernel();
+	return(0);
+}
+
+/**********************************************************************
+* Define (fill in) the user space file operations for this driver
+* and initialize the Seven Segment driver as a "miscdevice":
+*       Character device
+*       Major(10) --- Non-serial mice, misc features
+*       Minor(21) --- /dev/7seg		(7-segment display)
+**********************************************************************/
+static struct file_operations sevenSegment_fops = {
+owner:      THIS_MODULE,
+read:       sevenSegment_read,
+write:      sevenSegment_write,
+poll:       sevenSegment_poll,
+open:       sevenSegment_open,
+fasync:     sevenSegment_fasync,
+release:    sevenSegment_release,
+};
+
+static struct miscdevice sevenSegment_dev = {
+minor: 21,
+name: "7seg",
+fops: &sevenSegment_fops,
+};
+
+/**********************************************************************
+* Function: lh79x_7seg_init
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+static int lh79x_7seg_init(void)
+{
+	sevenSegmentContext_t *sevenSegmentContext = &sevenSegmentContext_l;
+	int sts = 0;
+	dprintk("ENTER: lh79x_7seg_init()\n");
+	init_waitqueue_head(&sevenSegmentContext->read_and_write_wait);
+	sts = misc_register(&sevenSegment_dev);
+	lh79x_7seg_write_display_str((u_char *)"HI");
+	dprintk("LEAVE: lh79x_7seg_init(%d)\n", sts);
+	return(sts);
+}
+
+/**********************************************************************
+* Function: lh79x_7seg_exit
+*
+* Purpose:
+*	Un-Register & Cleanup the module
+**********************************************************************/
+static void lh79x_7seg_exit(void)
+{
+	dprintk("ENTER: lh79x_7seg_exit()\n");
+	misc_deregister(&sevenSegment_dev);
+	lh79x_7seg_write_display_str((u_char *)"BY");
+	dprintk("LEAVE: lh79x_7seg_exit()\n");
+	return;
+}
+
+module_init(lh79x_7seg_init);
+module_exit(lh79x_7seg_exit);
+
+MODULE_AUTHOR("Jim Gleason / Lineo, Inc.");
+MODULE_DESCRIPTION("Seven Segment Display Driver for Sharp LH7x EVB");
+MODULE_LICENSE("Copyright (c) 2002 Lineo, Inc.");
+
diff -urN linux-2.4.26/drivers/misc/Makefile linux-2.4.26-vrs1-lnode80/drivers/misc/Makefile
--- linux-2.4.26/drivers/misc/Makefile	2005-11-02 16:54:22.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/Makefile	2005-11-02 17:37:31.000000000 -0400
@@ -18,6 +18,9 @@
 obj-$(CONFIG_MCP_UCB1200)	+= ucb1x00-core.o
 obj-$(CONFIG_MCP_UCB1200_AUDIO)	+= ucb1x00-audio.o
 obj-$(CONFIG_MCP_UCB1200_TS)	+= ucb1x00-ts.o
+obj-$(CONFIG_TOUCHSCREEN_LH79520) += ads784x.o marm-lh7x.o
+obj-$(CONFIG_EEPROM_LH79520) += eeprom-lh7x.o
+obj-$(CONFIG_7SEGMENT_LH79520) += lh7x-7seg.o
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.26/drivers/misc/marm-lh7x.c linux-2.4.26-vrs1-lnode80/drivers/misc/marm-lh7x.c
--- linux-2.4.26/drivers/misc/marm-lh7x.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/marm-lh7x.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,521 @@
+/* vi: set sw=4 ts=4 ai: */
+
+// #define MODULE
+
+/**********************************************************************
+*  linux/drivers/misc/ssp-lh7x.c
+*
+*  Provide SSP (synchronous Serial Port) functionality for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*	This program is free software; you can redistribute it and/or modify
+*	it under the terms of the GNU General Public License (GPL) version 2
+*	as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+#undef DEBUG
+#undef VERBOSE
+#define DRVNAME	"marm_lh7x"
+#include <linux/verbosedebug.h>
+
+#include <linux/version.h>
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+#endif /* MODULE */
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/iocon.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/ssp_lh7x.h>
+#include <lh79520.h>
+#include "ssp.h"
+
+// global set by pl110fb driver
+unsigned short marm_backlight;
+
+#undef BACKLIGHT
+#define BACKLIGHT marm_backlight
+
+#define	MARM_TS_INT	3
+#define	MARM_TS_IOBIT 6
+
+static volatile u16 *gpioa = (volatile u16 *) GPOUT16_BASE;
+static gpioARegs_t *gpioadr = (gpioARegs_t *) GPIO0_BASE;
+static ioconRegs_t *iocon = (ioconRegs_t *)IOCON_PHYS;
+static vicRegs_t *vic = (vicRegs_t *)VIC_BASE;
+static rcpcRegs_t *rcpc = (rcpcRegs_t *) RCPC_PHYS;
+
+/**********************************************************************
+* Function: ssp_busy_wait
+*
+* Purpose:
+*	Wait until the state of the SSP busy bit from the status register
+*	indicates the SSP is no longer busy.
+*
+* Returns:
+*	N/A
+**********************************************************************/
+static void ssp_busy_wait(void)
+{
+	vdprintk("ENTER: ssp_busy_wait()\n");
+};
+
+/**********************************************************************
+* Function: ssp_flush_tx_fifo
+* Function: ssp_flush_rx_fifo
+*
+* Purpose:
+*	Flush the transmit (tx) and receive (rx) fifo buffer
+*
+* Returns:
+*	N/A
+**********************************************************************/
+static void ssp_flush_tx_fifo(sspContext_t *sspContext)
+{
+	vdprintk("ENTER: ssp_flush_tx_fifo()\n");
+};
+
+static void ssp_flush_rx_fifo(sspContext_t *sspContext)
+{
+	vdprintk("ENTER: ssp_flush_rx_fifo()\n");
+};
+
+/**********************************************************************
+* Function: ssp_chipselect_enable
+* Function: ssp_chipselect_disable
+* Function: ssp_chipselect_manual
+* Function: ssp_chipselect_automatic
+*
+* Purpose:
+*	Controls the chipselect pin associated with the SSP
+*
+* Returns:
+*	N/A
+*
+**********************************************************************/
+static void ssp_chipselect_enable(void)
+{
+	vdprintk("ENTER: ssp_chipselect_enable()\n");
+};
+
+static void ssp_chipselect_disable(void)
+{
+	vdprintk("ENTER: ssp_chipselect_disable()\n");
+};
+
+static void ssp_chipselect_manual(void)
+{
+	vdprintk("ENTER: ssp_chipselect_manual()\n");
+
+	gpioadr->ddr &= ~(1 << MARM_TS_IOBIT);	// make sure PA is input
+	iocon->MiscMux &= ~(MISCMUX_RCEII0); 	// make it PA6 instead of IRQ0
+
+	// ensure TS IRQ pin is interrupt
+	iocon->LCDMux &= ~(MISCMUX_PWM0SYNC);	// assumes irq 3
+};
+
+static void ssp_chipselect_automatic(void)
+{
+	vdprintk("ENTER: ssp_chipselect_automatic()\n");
+	ssp_chipselect_manual();
+};
+
+/**********************************************************************
+* Function: ssp_lh7x_write16
+*
+* Purpose:
+*	Write the LH7x SSP data register
+**********************************************************************/
+static void ssp_lh7x_write16(sspContext_t *sspContext,
+		unsigned int data)
+{
+	int i;
+	int ndata = data & 0xFF;
+	int pdata, qdata;
+
+	vdprintk("ENTER: ssp_lh7x_write16() 0x%04X\n", data);
+
+	udelay(10);
+	pdata = BACKLIGHT;					// keep on backlight
+	*gpioa = pdata;						// assert nCS
+	
+	for (i = 8; i > 0; i--)
+	{
+	  *gpioa = qdata = pdata | ((ndata & 0x80) ? TS_DIN : 0);	// strobe out bit
+	  udelay(1);
+	  *gpioa = qdata | TS_DCLK | nLED;							// raise clock
+	  udelay(1);
+	  *gpioa = qdata;											// lower clock
+	  udelay(1);
+
+	  ndata <<= 1;
+	}
+	udelay(50);						// leave enough time for conversion
+
+	*gpioa = pdata;
+};
+
+/**********************************************************************
+* Function: ssp_lh7x_read16
+*
+* Purpose:
+*	Read the LH7x SSP data register
+**********************************************************************/
+static unsigned int ssp_lh7x_read16(sspContext_t *sspContext)
+{
+	int i;
+	int pdata, ndata;
+
+	pdata = BACKLIGHT;
+	ndata = 0;
+
+	for (i = 16; i > 0; i--)
+	{
+	  *gpioa = pdata;
+	  udelay(1);
+	  *gpioa = pdata | TS_DCLK | nLED;
+	  udelay(1);
+
+	  if (gpioadr->dr & (1 << MARM_TS_IOBIT)) 
+	    ndata |= 1;
+
+	  ndata <<= 1;
+	}
+
+	vdprintk("LEAVE: ssp_lh7x_read16() 0x%04X (%04d norm) raw\n", ndata, ndata >> 4);
+	return(ndata >> 4);
+};
+
+/**********************************************************************
+* Macro: ssp_lh7x_ts_pen_down
+**********************************************************************/
+static int ssp_lh7x_ts_pen_down(sspContext_t *sspContext)
+{
+	int pen_down = vic->RawIntr & (1 << MARM_TS_INT); //look for IRQ
+	vdprintk("ssp_lh7x_ts_pen_down(%d)\n", pen_down);
+	return (pen_down);
+}
+
+/**********************************************************************
+* Macro: ssp_lh7x_ts_pen_down_irq_enable
+**********************************************************************/
+static int ssp_lh7x_ts_pen_down_irq_enable(sspContext_t *sspContext)
+{
+	int lastState = vic->IntEnable & (1 << MARM_TS_INT);
+	vdprintk("ssp_lh7x_ts_pen_down_irq_enable: lastState %d\n", lastState);
+#if 0
+	//enable_irq(MARM_TS_INT);
+    rcpc->control       |= RCPC_CTRL_WRTLOCK_ENABLED;
+	barrier();
+	rcpc->control       &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+#endif
+	sspContext->irq_state = 1;
+	return(lastState);
+}
+
+/**********************************************************************
+* Macro: ssp_lh7x_ts_pen_down_irq_disable
+**********************************************************************/
+static int ssp_lh7x_ts_pen_down_irq_disable(
+		sspContext_t *sspContext)
+{
+	int lastState = vic->IntEnable & (1 << MARM_TS_INT);
+	vdprintk("ssp_lh7x_ts_pen_down_irq_disable: lastState %d\n", lastState);
+	//disable_irq(MARM_TS_INT);
+    rcpc->control       |= RCPC_CTRL_WRTLOCK_ENABLED;
+	barrier();
+	rcpc->intClear		= (1 << MARM_TS_INT);
+	rcpc->control       &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+	sspContext->irq_state = 0;
+	return(lastState);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_ts_pen_down_irq
+*
+* We only detect touch screen _touches_ (pen down) with this interrupt
+* handler, and even then we just schedule our task.
+*
+* Note: It has already been determined that this is our interrupt
+* before we ever get it here so checking is minimal to non-existant.
+**********************************************************************/
+static void ssp_lh7x_ts_pen_down_irq(int irq, sspContext_t *sspContext,
+		struct pt_regs * regs)
+{
+	/*
+	* Disable the touchscreen interrupts
+	* by disabling the touchscreen IRQ
+	* --- AND ---
+	* Enable regular polling of the touchscreen device
+	* (The touchscreen IRQ will be re-enabled and polling
+	* will be disabled when it is detected that the
+	* pen is no longer down.)
+	*/
+	/* Disable touch screen IRQ */
+	vdprintk("ENTER: ssp_lh7x_ts_pen_down_irq()\n");
+	ssp_lh7x_ts_pen_down_irq_disable(sspContext);
+	vdprintk("ENTER: wake_up()\n");
+	wake_up(sspContext->irq_wait_ptr);
+	vdprintk("LEAVE: ssp_lh7x_ts_pen_down_irq()\n");
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_irq_handler
+*
+* This interrupt handler only directs traffic for the interrupts
+* by forwarding on the call to the appropriate interrupt handler.
+**********************************************************************/
+static void ssp_lh7x_irq_handler(int irq, void *_sspContext,
+		struct pt_regs * regs)
+{
+	sspContext_t *sspContext = _sspContext;
+
+	vdprintk("ENTER: ssp_lh7x_irq_handler()\n");
+	if ((sspContext) && (sspContext->irq_wait_ptr)) {
+		if (ssp_lh7x_ts_pen_down(sspContext))
+			ssp_lh7x_ts_pen_down_irq(irq, sspContext, regs);
+		else
+#if defined(VERBOSE) && defined(DEBUG)
+			printk("ssp_lh7x_irq_handler() --- Not our interrupt\n");
+#else
+		;
+#endif
+	} // if(sspContext) ...
+#if defined(VERBOSE) && defined(DEBUG)
+	else {
+		printk("ssp_lh7x_irq_handler( NO ACTION )\n");
+	}
+#endif
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_lock
+* Function: ssp_lh7x_unlock
+*
+* Purpose:
+*	Lock/UnLock the SSP for a particular device (ts/ee)
+**********************************************************************/
+static int ssp_lh7x_lock(sspContext_t *sspContext, int device)
+{
+	vdprintk("ENTER: ssp_lh7x_lock()\n");
+	return -1;
+};
+
+static int ssp_lh7x_unlock(sspContext_t *sspContext, int device)
+{
+	vdprintk("ENTER: ssp_lh7x_unlock()\n");
+	return -1;
+};
+
+/**********************************************************************
+* Function: ssp_lh7x_disable
+*
+* Purpose:
+*	Disconnect I/O pins from the SSP module
+*	and disable the SSP peripheral and its clocks.
+**********************************************************************/
+static void ssp_lh7x_disable(void)
+{
+	vdprintk("ENTER: ssp_lh7x_disable()\n");
+};
+
+/**********************************************************************
+* Function: ssp_lh7x_enable
+*
+* Purpose:
+*	Disconnect I/O pins from the SSP module
+*	and disable the SSP peripheral and its clocks.
+**********************************************************************/
+static void ssp_lh7x_enable(void)
+{
+	vdprintk("ENTER: ssp_lh7x_enable()\n");
+	return;
+}
+
+/**********************************************************************
+* Fill in our context structures
+**********************************************************************/
+
+static sspContext_t sspContext_l = {
+	ts_txTimeout: 10000,
+	ts_rxTimeout: 10000,
+	ee_txTimeout: 10000,
+	ee_rxTimeout: 10000,
+	haveIrq: 0,
+};
+
+/**********************************************************************
+* Function: ssp_request_pointer
+* Function: ssp_provide_pointer
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+void *ssp_request_pointer(int device, char *request)
+{
+	sspContext_t *sspContext = &sspContext_l;
+	void *vp = NULL;
+
+	vdprintk("ENTER: ssp_request_pointer(\"%d\":\"%s\")\n", device, request);
+	if (device == SSP_DEV_TOUCHSCREEN) {
+		if        (strcmp(request, "write") == 0) {
+			vp = ssp_lh7x_write16;
+		} else if (strcmp(request, "read") == 0) {
+			vp = ssp_lh7x_read16;
+		} else if (strcmp(request, "enable_pen_down_irq") == 0) {
+			vp = ssp_lh7x_ts_pen_down_irq_enable;
+		} else if (strcmp(request, "disable_pen_down_irq") == 0) {
+			vp = ssp_lh7x_ts_pen_down_irq_disable;
+		} else if (strcmp(request, "is_pen_down") == 0) {
+			vp = ssp_lh7x_ts_pen_down;
+		} else if (strcmp(request, "lock") == 0) {
+			vp = ssp_lh7x_lock;
+		} else if (strcmp(request, "unlock") == 0) {
+			vp = ssp_lh7x_unlock;
+		} else if (strcmp(request, "sspContext") == 0) {
+			vp = sspContext;
+		} else if (strcmp(request, "flush_tx_fifo") == 0) {
+			vp = ssp_flush_tx_fifo;
+		} else if (strcmp(request, "flush_rx_fifo") == 0) {
+			vp = ssp_flush_rx_fifo;
+		} else if (strcmp(request, "ssp_busy_wait") == 0) {
+			vp = ssp_busy_wait;
+		} else if (strcmp(request, "chipselect_enable") == 0) {
+			vp = ssp_chipselect_enable;
+		} else if (strcmp(request, "chipselect_disable") == 0) {
+			vp = ssp_chipselect_disable;
+		} else if (strcmp(request, "chipselect_manual") == 0) {
+			vp = ssp_chipselect_manual;
+		}
+	} else if (device == SSP_DEV_EEPROM) {
+			vp = NULL;
+    }
+	vdprintk("LEAVE: ssp_request_pointer(0x%08X)\n", (unsigned int)vp);
+
+	return(vp);
+}
+
+void *ssp_provide_pointer(int device, char *request, void *vp)
+{
+	sspContext_t *sspContext = &sspContext_l;
+
+	vdprintk("ENTER: ssp_provide_pointer(\"%d\":\"%s\":0x%08X)\n",
+			device, request, (unsigned int)vp);
+	if (device == SSP_DEV_TOUCHSCREEN) {
+		if (strcmp(request, "irq_wait_ptr") == 0) {
+			sspContext->irq_wait_ptr = vp;
+		} else {
+			vp = NULL;
+		}
+	} else if (device == SSP_DEV_EEPROM) {
+		vp = NULL;
+	} else {
+		vp = NULL;
+	}
+	vdprintk("LEAVE: ssp_provide_pointer(0x%08X)\n", (unsigned int)vp);
+
+	return(vp);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_init
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+static int __init ssp_lh7x_init(void)
+{
+	sspContext_t *sspContext = &sspContext_l;
+	int sts = 0;
+	int result;
+
+	vdprintk("ENTER: ssp_lh7x_init()\n");
+
+	/*
+	* Disconnect I/O pins from the SSP module
+	* and disable the SSP peripheral and its clocks.
+	*/
+	ssp_lh7x_disable();
+
+	/* Flush the transmit FIFO */
+	ssp_flush_tx_fifo(sspContext);
+
+	/* Flush the receive FIFO */
+	ssp_flush_rx_fifo(sspContext);
+
+	ssp_chipselect_automatic();
+	/*
+	* Connect I/O pins from the SSP module
+	* and enable the SSP peripheral and its clocks.
+	*/
+	ssp_lh7x_enable();
+
+	/*
+	* Request IRQ and attach it to the touchscreen pen_down line and enable it
+	*/
+	sspContext->haveIrq = 0;
+	result = request_irq(MARM_TS_INT, ssp_lh7x_irq_handler,
+			SA_SAMPLE_RANDOM, DRVNAME, sspContext);
+	if (result < 0) {
+		printk("%s: cannot get requested IRQ(MARM_TS_INT)\n", DRVNAME);
+	} else {
+		sspContext->haveIrq = 1;
+		vdprintk("%s: got requested IRQ(MARM_TS_INT)\n", DRVNAME);
+	}
+	ssp_lh7x_ts_pen_down_irq_enable(sspContext);
+
+	vdprintk("LEAVE: ssp_lh7x_init()\n");
+	return(sts);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_exit
+*
+* Purpose:
+*	Un-Register & Cleanup the module
+**********************************************************************/
+static void ssp_lh7x_exit(void)
+{
+	sspContext_t *sspContext = &sspContext_l;
+
+	vdprintk("ENTER: ssp_lh7x_exit()\n");
+
+	/*
+	* Disable & Return IRQ
+	*/
+	lock_kernel();
+	ssp_lh7x_ts_pen_down_irq_disable(sspContext);
+	if (sspContext->haveIrq) {
+		free_irq(MARM_TS_INT, sspContext);
+		sspContext->haveIrq = 0;
+	}
+	unlock_kernel();
+
+	vdprintk("LEAVE: ssp_lh7x_exit()\n");
+	return;
+}
+
+module_init(ssp_lh7x_init);
+module_exit(ssp_lh7x_exit);
+
+MODULE_AUTHOR("Jim Gleason / Lineo, Inc.");
+MODULE_DESCRIPTION("SSP Driver for Sharp LH7x EVB");
+MODULE_LICENSE("Copyright (c) 2002 Lineo, Inc.");
diff -urN linux-2.4.26/drivers/misc/ssp.h linux-2.4.26-vrs1-lnode80/drivers/misc/ssp.h
--- linux-2.4.26/drivers/misc/ssp.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/ssp.h	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,29 @@
+/* vi: set sw=4 ts=4 ai: */
+
+/**********************************************************************
+* linux/drivers/misc/ssp.h
+*
+* Copyright (C) 2002  Lineo, Inc.
+*
+* Provide SSP types & definitions
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License (GPL) version 2
+* as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+#ifndef _SSP_h
+#define _SSP_h
+
+/*********************************************************************
+* Global Function Declarations
+*********************************************************************/
+extern void *ssp_request_pointer(int device, char *request);
+extern void *ssp_provide_pointer(int device, char *request, void *vp);
+
+#define SSP_DEV_TOUCHSCREEN		1
+#define SSP_DEV_EEPROM			2
+
+#endif /* _SSP_h */
+
diff -urN linux-2.4.26/drivers/misc/ssp-lh7x.c linux-2.4.26-vrs1-lnode80/drivers/misc/ssp-lh7x.c
--- linux-2.4.26/drivers/misc/ssp-lh7x.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/misc/ssp-lh7x.c	2005-11-02 17:37:31.000000000 -0400
@@ -0,0 +1,1024 @@
+/* vi: set sw=4 ts=4 ai: */
+
+// #define MODULE
+
+/**********************************************************************
+*  linux/drivers/misc/ssp-lh7x.c
+*
+*  Provide SSP (synchronous Serial Port) functionality for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*	This program is free software; you can redistribute it and/or modify
+*	it under the terms of the GNU General Public License (GPL) version 2
+*	as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+//#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+//#include <linux/interrupt.h>
+//#include <linux/irq.h>
+
+#undef DEBUG
+#undef VERBOSE
+#undef DRVNAME	//"ssp_lh7x"
+#include <linux/verbosedebug.h>
+
+#include <linux/version.h>
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+#endif /* MODULE */
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/iocon.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+//#include <asm/arch/cpld.h>
+#include <asm/arch/rcpc.h>
+#include <asm/arch/ssp_lh7x.h>
+#include "ssp.h"
+
+unsigned int hclkfreq_get( void);
+
+static gpioARegs_t *gpioa = (gpioARegs_t *)GPIO0_PHYS;
+static ioconRegs_t *iocon = (ioconRegs_t *)IOCON_PHYS;
+static rcpcRegs_t *rcpc = (rcpcRegs_t *)RCPC_PHYS;
+//static cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+static sspRegs_t *ssp = (sspRegs_t *)SSP_BASE;
+static vicRegs_t *vic = (vicRegs_t *)VIC_BASE;
+/*
+* hclk_freq:
+* The frequency of the clock that feeds the SSP clock prescaler in the RCPC
+* The frequency is in Hz
+*/
+static unsigned int hclk_freq = 0;
+
+/**********************************************************************
+* Additional RCPC defines
+**********************************************************************/
+#define rcpc_sspClkControl		spareClkCtrl
+#define rcpc_sspClkPrescale		spare1Prescale
+
+#define RCPC_LOCK 1
+#define RCPC_LOCKED RCPC_LOCK
+#define RCPC_UNLOCK 0
+#define RCPC_UNLOCKED RCPC_UNLOCK
+
+/**********************************************************************
+* Function: ssp_busy_wait
+*
+* Purpose:
+*	Wait until the state of the SSP busy bit from the status register
+*	indicates the SSP is no longer busy.
+*
+* Returns:
+*	N/A
+**********************************************************************/
+static void ssp_busy_wait(void)
+{
+	while ( ssp->sr & SSP_SR_BSY ) {
+		barrier();
+	}
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_flush_tx_fifo
+* Function: ssp_flush_rx_fifo
+*
+* Purpose:
+*	Flush the transmit (tx) and receive (rx) fifo buffer
+*
+* Returns:
+*	N/A
+**********************************************************************/
+static void ssp_flush_tx_fifo(sspContext_t *sspContext)
+{
+	int i;
+
+	for (i = sspContext->ts_txTimeout; ((i > 0) && (ssp->sr & SSP_SR_TFE)); i--)
+	{
+		barrier();
+	}
+	return;
+}
+
+static void ssp_flush_rx_fifo(sspContext_t *sspContext)
+{
+	int i;
+	unsigned int junk;
+
+	for (i = sspContext->ts_rxTimeout; ((i > 0) && (ssp->sr & SSP_SR_RNE)); i--)
+	{
+		barrier();
+		junk = ssp->dr;
+		//printk("ssp_flush_rx_fifo(0x%04X)\n", junk);
+	}
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_chipselect_enable
+* Function: ssp_chipselect_disable
+* Function: ssp_chipselect_manual
+* Function: ssp_chipselect_automatic
+*
+* Purpose:
+*	Controls the chipselect pin associated with the SSP
+*
+* Returns:
+*	N/A
+*
+**********************************************************************/
+static void ssp_chipselect_enable(void)
+{
+	/* Make the SSPFRM signal (ChipSelect) high (enabled) */
+	/* Note: This must have had ssp_chipselect_manual() called first */
+	//printk("ssp_chipselect_enable()\n");
+#ifdef ORDERITE_REV4	
+	//FJBgpioa->dr &= ~(SSPFRM_GPIO_BIT);	/* LOW == Enabled */
+	gpioa->dr &= ~(SSPEN_GPIO_BIT);	/* LOW == Enabled */
+#else
+	gpioa->dr &= ~(SSPFRM_GPIO_BIT);	/* LOW == Enabled */
+#endif
+	return;
+}
+
+static void ssp_chipselect_disable(void)
+{
+	/* Make the SSPFRM signal (ChipSelect) low (disabled) */
+	/* Note: This must have had ssp_chipselect_manual() called first */
+	//printk("ssp_chipselect_disable()\n");
+#ifdef ORDERITE_REV4	
+	//FJBgpioa->dr |= SSPFRM_GPIO_BIT;	/* HIGH == Disabled */
+	gpioa->dr |= SSPEN_GPIO_BIT;	/* HIGH == Disabled */
+#else
+	gpioa->dr |= SSPFRM_GPIO_BIT;	/* HIGH == Disabled */
+#endif	
+	return;
+}
+
+static void ssp_chipselect_manual(void)
+{
+	/* First, disable the ChipSelect */
+	//JMG ssp_chipselect_disable();
+	/* Set up muxing so that we manually control the ChipSelect pin */
+	/* via GPIO port A bit 2 */
+#ifdef ORDERITE_REV4	
+	//FJBgpioa->ddr |= SSPFRM_GPIO_BIT;	/* Make GPIO an output */
+	gpioa->ddr |= SSPEN_GPIO_BIT;	/* Make GPIO an output */
+	//FJBiocon->SSIMux &= ~SSIMUX_SSPFRM;
+	iocon->SSIMux &= ~SSIMUX_SSPENB;
+#else
+	gpioa->ddr |= SSPFRM_GPIO_BIT;	/* Make GPIO an output */
+	iocon->SSIMux &= ~SSIMUX_SSPFRM;
+#endif	
+	ssp_chipselect_disable();
+	return;
+}
+
+static void ssp_chipselect_automatic(void)
+{
+	/* First, disable the ChipSelect */
+	ssp_chipselect_disable();
+#ifdef ORDERITE_REV4	
+	/* Set up muxing so the SSP automatically controls the ChipSelect pin */
+	//FJBiocon->SSIMux |= SSIMUX_SSPFRM;
+	iocon->SSIMux |= SSIMUX_SSPENB;
+#else
+	iocon->SSIMux |= SSIMUX_SSPFRM;
+#endif	
+	return;
+}
+
+/**********************************************************************
+* Function: rcpc_lh7x_locked
+*
+* Purpose:
+*	Determine write access to the RCPC
+*
+* Returns:
+*	The lock state of the RCPC
+*
+**********************************************************************/
+static int rcpc_lh7x_locked(void)
+{
+	int lockState;
+
+	vdprintk("ENTER: rcpc_lh7x_locked()\n");
+	if (rcpc->control & RCPC_CTRL_WRTLOCK_ENABLED) {
+		lockState = RCPC_LOCKED;
+	} else {
+		lockState = RCPC_UNLOCKED;
+	}
+	vdprintk("LEAVE: rcpc_lh7x_locked(%s)\n",
+			(lockState==RCPC_LOCKED)?"Locked":"UnLocked");
+
+	return(lockState);
+}
+
+/**********************************************************************
+* Function: rcpc_lh7x_lock
+*
+* Purpose:
+*	Control write access to the RCPC
+*
+* Parameters:
+*	action:	RCPC_UNLOCK == can    write to RCPC
+*			RCPC_LOCK   == cannot write to RCPC
+*
+* Returns:
+*	The previous lock state of the RCPC
+*
+**********************************************************************/
+static int rcpc_lh7x_lock(int action)
+{
+	int priorState;
+
+	vdprintk("ENTER: rcpc_lh7x_lock(%s)\n",
+			(action==RCPC_LOCK)?"Lock":"UnLock");
+	priorState = rcpc_lh7x_locked();
+	if (action == RCPC_UNLOCK) {
+		rcpc->control |= RCPC_CTRL_WRTLOCK_ENABLED;
+	} else /* (action == RCPC_LOCK) */ {
+		rcpc->control &= ~RCPC_CTRL_WRTLOCK_ENABLED;
+	}
+	vdprintk("LEAVE: rcpc_lh7x_lock(%s)\n",
+			(action==RCPC_LOCK)?"Lock":"UnLock");
+
+	return(priorState);
+}
+
+#if OLDWAY
+/**********************************************************************
+* Function: ssp_lh7x_get_hclk_freq
+*
+* Purpose:
+*	Get the HCLK (bus clock) frequency in Hz
+**********************************************************************/
+static unsigned int ssp_lh7x_get_hclk_freq(void)
+{
+#define XTAL_IN		14745600		/* 14.7456 MHz crystal */
+#define PLL_CLOCK	(XTAL_IN * 21)	/* 309 MHz PLL clock */
+	int divider;
+	unsigned int _hclk_freq;
+
+	vdprintk("ENTER: ssp_lh7x_get_hclk_freq()\n");
+	divider = rcpc->HCLKPrescale * 2;	/* HCLK prescale value */
+	if( divider == 0)					/* No prescalar == divide by 1 */
+		divider = 1;
+	_hclk_freq = PLL_CLOCK / divider;
+	vdprintk("LEAVE: ssp_lh7x_get_hclk_freq(%u)\n", _hclk_freq);
+
+	return(_hclk_freq);
+}
+#endif
+
+
+/**********************************************************************
+* Function: ssp_lh7x_get_speed
+*
+* Purpose:
+*	Get the SSP speed in bits per second
+**********************************************************************/
+static int ssp_lh7x_get_speed(void)
+{
+	int bps;
+	int rcpc_prescale;
+	int ssp_prescale;
+	int ssp_divider;
+
+	vdprintk("ENTER: ssp_lh7x_get_speed()\n");
+	rcpc_prescale = rcpc->rcpc_sspClkPrescale;
+	if (rcpc_prescale == 0) rcpc_prescale = 1;
+	else                    rcpc_prescale <<= 1;
+	ssp_prescale = ssp->cpsr;
+	ssp_divider = (ssp->cr0 & _SBF(8,_BITMASK(8) ) ) >> 8;
+	bps = hclk_freq / (rcpc_prescale * (ssp_prescale) * (ssp_divider + 1) );
+	vdprintk("LEAVE: ssp_lh7x_get_speed(%d bps)\n", bps);
+
+	return(bps);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_set_speed
+*
+* Purpose:
+*	Set the SSP speed in bits per second
+*
+* Processing:
+*	If the requested_bits_per_second is negaitve, return 0
+*	If the requested_bits_per_second is too fast, set the bit rate
+*	as fast as possible.
+*	If the requested_bits_per_second is too slow, set the bit rate as
+*	slow as possible.
+*	If the requested_bits_per_second is in range, set the RCPC
+*	SSP clock prescaler register, SSP prescaler, and SSP divider
+*	to obtain the clock as close as possible.
+*
+* Parameters:
+*	bps: The desired bits per second
+*
+* Returns:
+*	The actual bps obtained or 0 if the requested bps is not obtainable.
+*
+* Notes:
+*	The mode (SPI/uWire/TI) must be set first for this function to work!
+*
+**********************************************************************/
+static int ssp_lh7x_set_speed(int bps)
+{
+	int rcpcLockState;
+	int32_t ssp_prescale;
+	int32_t ssp_divider;
+	int32_t rcpc_prescale;
+	int32_t new_prescale;
+	int32_t new_divider;
+	int32_t quotient;
+	int32_t delta1;
+	int32_t delta2;
+	int32_t min_error;
+	int32_t new_error;
+#	define MAX_SSP_FREQ (hclk_freq / SSP_PRESCALE_MIN)
+
+	vdprintk("ENTER: ssp_lh7x_set_speed(%d bps)\n", bps);
+
+	/* Ensure we are dealing with a legal BPS */
+	if (bps <= 0) {
+		printk("%s: requested ssp speed (%d bps) is to slow\n", DRVNAME, bps);
+		printk("%s: making ssp speed as slow as possible\n", DRVNAME);
+		/* The request bps is slower than the minimum possible */
+		/* ... make it as slow as possible */
+		/* Don't bother calculating the divider values as we know them */
+		rcpc_prescale = RCPC_SSP_PRESCALE_MAX;
+		ssp_prescale = SSP_PRESCALE_MAX;
+		ssp_divider = SSP_DIVIDER_MAX;
+	} else if (bps >= MAX_SSP_FREQ) {
+		printk("%s: requested ssp speed (%d bps) is to fast\n", DRVNAME, bps);
+		printk("%s: making ssp speed as fast as possible\n", DRVNAME);
+		/* Don't bother calculating the divider values as we know them */
+		bps = MAX_SSP_FREQ;
+		ssp_prescale = SSP_PRESCALE_MIN;
+		ssp_divider = 1;
+		rcpc_prescale = 1;
+	} else {
+		/* Calculate the divider values as close as we can */
+		quotient = hclk_freq / bps;
+		if (quotient <= 0)
+			quotient = 1;
+		/* round the quotient */
+		delta1 = bps - (hclk_freq / quotient );
+		if (delta1 < 0)
+			delta1 = -delta1;
+		delta2 = bps - (hclk_freq / (quotient + 1));
+		if (delta2 < 0)
+			delta2 = -delta2;
+		if (delta1 > delta2)
+			quotient++;
+		if (quotient >=
+				(SSP_PRESCALE_MAX * RCPC_SSP_PRESCALE_MAX * SSP_DIVIDER_MAX))
+		{
+			printk("%s: requested ssp speed (%d bps) is to slow\n",
+					DRVNAME, bps);
+			printk("%s: making ssp speed as slow as possible\n", DRVNAME);
+			/* The request bps is slower than the minimum possible */
+			/* ... make it as slow as possible */
+			/* Don't bother calculating the divider values as we know them */
+			rcpc_prescale = RCPC_SSP_PRESCALE_MAX;
+			ssp_prescale = SSP_PRESCALE_MAX;
+			ssp_divider = SSP_DIVIDER_MAX;
+		} else {
+			/*
+			* The computed quotient is in range.
+			* Quotient is the target clock divide frequency.
+			* Get as close as possible.
+			*/
+			rcpc_prescale = 1;
+			/*
+			* Try to reduce power by using RCPC prescaler.
+			* Note that the ssp prescaler minimum is two
+			* so can only prescale and maintain accuracy
+			* if quotient is divisible by 4.
+			*/
+			while ( ((quotient & 0x3) == 0)
+					&& (rcpc_prescale < RCPC_SSP_PRESCALE_MAX) )
+			{
+				quotient >>= 1;
+				rcpc_prescale <<= 1;
+			}
+			/*
+			* Make sure the requested frequency is within range
+			* of the SPP's prescaler and divider.
+			* Hopefully, this loop never executes.
+			* If it does, accuracy suffers.
+			*/
+			while (quotient > (SSP_PRESCALE_MAX * SSP_DIVIDER_MAX) ) {
+				rcpc_prescale <<= 1;
+				quotient >>= 1;
+			}
+			/*
+			* Factor the quotient into the divider and prescaler combo
+			* that minimizes the error in the quotient by exhaustively
+			* searching all legal ssp prescaler values.
+			*/
+			ssp_prescale = SSP_PRESCALE_MIN;
+			ssp_divider = (quotient / ssp_prescale);
+			ssp_divider = (ssp_divider > SSP_DIVIDER_MAX)
+				? SSP_DIVIDER_MAX : ssp_divider;
+			min_error = quotient - (ssp_divider * ssp_prescale);
+			min_error = (min_error < 0) ? -min_error : min_error;
+			for (new_prescale = SSP_PRESCALE_MIN + 2;
+					new_prescale < SSP_PRESCALE_MAX;
+					new_prescale += 2)
+			{
+				new_divider = (quotient / new_prescale);
+				new_divider = (new_divider > SSP_DIVIDER_MAX)
+					? SSP_DIVIDER_MAX : new_divider;
+				new_error = quotient - (new_divider * new_prescale);
+				new_error = (new_error < 0) ? -new_error : new_error;
+				if (new_error < min_error) {
+					min_error = new_error;
+					ssp_prescale = new_prescale;
+					ssp_divider = new_divider;
+				}
+			}
+		}
+	}
+	/* Set up the necessary registers to get the desired BSP */
+	rcpcLockState = rcpc_lh7x_lock(RCPC_UNLOCK);
+	rcpc->rcpc_sspClkPrescale = rcpc_prescale >> 1;
+	(void) rcpc_lh7x_lock(rcpcLockState);
+	ssp->cpsr = ssp_prescale;
+	ssp->cr0 &= 0xff; /* clear old divider value */
+	ssp->cr0 |= SSP_CR0_SCR(ssp_divider - 1);
+
+	vdprintk("LEAVE: ssp_lh7x_set_speed(%d bps)\n", bps);
+
+	return(ssp_lh7x_get_speed());
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_write16
+*
+* Purpose:
+*	Write the LH7x SSP data register
+**********************************************************************/
+static void ssp_lh7x_write16(sspContext_t *sspContext,
+		unsigned int data)
+{
+	int i;
+
+	//if (sspContext->ssp_dev_sel == SSP_EEPROM) {	//JMG
+		//printk("ENTER: ssp_lh7x_write16(0x%04X)\n", (uint16_t)data);
+	//}
+	for (i=sspContext->ts_txTimeout; ((i>0) && ((ssp->sr&SSP_SR_TNF) == 0)); i--) {
+		barrier();
+	}
+	if (ssp->sr & SSP_SR_TNF) {
+		ssp->dr = (uint16_t)data;
+	} else {
+		printk("%s: write timout\n", DRVNAME);
+	}
+	//vdprintk("LEAVE: ssp_lh7x_write16(0x%04X)\n", (uint16_t)data);
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_read16
+*
+* Purpose:
+*	Read the LH7x SSP data register
+**********************************************************************/
+static unsigned int ssp_lh7x_read16(sspContext_t *sspContext)
+{
+	int i;
+	unsigned int data = -1;
+
+	//vdprintk("ENTER: ssp_lh7x_read16()\n");
+	for (i=sspContext->ts_txTimeout; ((i>0) && ((ssp->sr&SSP_SR_RNE) == 0)); i--) {
+		barrier();
+	}
+	if (ssp->sr & SSP_SR_RNE) {
+		if (sspContext->ssp_dev_sel == SSP_EEPROM) {
+			data = (unsigned int)ssp->dr;					/* EEPROM */
+			//printk("LEAVE: ssp_lh7x_read16(ee: 0x%04X)\n", data);
+		} else {
+			data = (((unsigned int)ssp->dr) >> 4) & 0x0FFF;	/* TOUCHSCREEN */
+			//printk("LEAVE: ssp_lh7x_read16(ts: 0x%04X)\n", data);
+		}
+	} else {
+		//printk("%s: read timout\n", DRVNAME);
+	}
+
+	return(data);
+}
+
+/**********************************************************************
+* Macro: ssp_lh7x_ts_pen_down
+**********************************************************************/
+static int ssp_lh7x_ts_pen_down(sspContext_t *sspContext)
+{
+	
+	//int pen_down = vic->IRQStatus & 0x01; //look for IRQ0
+	int pen_down = vic->RawIntr & 0x01; //look for IRQ0
+	dprintk("ssp_lh7x_ts_pen_down(%d)\n", pen_down);
+	return (pen_down);
+}
+
+/**********************************************************************
+* Macro: ssp_lh7x_ts_pen_down_irq_enable
+**********************************************************************/
+static int ssp_lh7x_ts_pen_down_irq_enable(sspContext_t *sspContext)
+{
+	int lastState = vic->IntEnable & 1;
+	dprintk("ssp_lh7x_ts_pen_down_irq_enable\n");
+	//vic->IntEnable = 1;
+	enable_irq(0);
+	sspContext->irq_state = 1;
+	return(lastState);
+}
+
+/**********************************************************************
+* Macro: ssp_lh7x_ts_pen_down_irq_disable
+**********************************************************************/
+static int ssp_lh7x_ts_pen_down_irq_disable(
+		sspContext_t *sspContext)
+{
+	int lastState = vic->IntEnable & 1;
+	dprintk("ssp_lh7x_ts_pen_down_irq_disable\n");
+	//vic->IntEnClear = 1;
+	disable_irq(0);
+	sspContext->irq_state = 0;
+	return(lastState);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_ts_pen_down_irq
+*
+* We only detect touch screen _touches_ (pen down) with this interrupt
+* handler, and even then we just schedule our task.
+*
+* Note: It has already been determined that this is our interrupt
+* before we ever get it here so checking is minimal to non-existant.
+**********************************************************************/
+static void ssp_lh7x_ts_pen_down_irq(int irq, sspContext_t *sspContext,
+		struct pt_regs * regs)
+{
+	/*
+	* Disable the touchscreen interrupts
+	* by disabling the touchscreen IRQ
+	* --- AND ---
+	* Enable regular polling of the touchscreen device
+	* (The touchscreen IRQ will be re-enabled and polling
+	* will be disabled when it is detected that the
+	* pen is no longer down.)
+	*/
+	/* Disable touch screen IRQ */
+	dprintk("ENTER: ssp_lh7x_ts_pen_down_irq()\n");
+	ssp_lh7x_ts_pen_down_irq_disable(sspContext);
+	dprintk("ENTER: wake_up()\n");
+	wake_up(sspContext->irq_wait_ptr);
+	vdprintk("LEAVE: ssp_lh7x_ts_pen_down_irq()\n");
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_irq_handler
+*
+* This interrupt handler only directs traffic for the interrupts
+* by forwarding on the call to the appropriate interrupt handler.
+**********************************************************************/
+static void ssp_lh7x_irq_handler(int irq, void *_sspContext,
+		struct pt_regs * regs)
+{
+	sspContext_t *sspContext = _sspContext;
+	if ((sspContext) && (sspContext->irq_wait_ptr)) {
+		//if (ssp_lh7x_ts_pen_down(sspContext)) {
+		if (1) {
+			ssp_lh7x_ts_pen_down_irq(irq, sspContext, regs);
+		}
+#if defined(VERBOSE) && defined(DEBUG)
+		else {
+			vdprintk("ssp_lh7x_irq_handler() --- Not our interrupt\n");
+		}
+#endif
+	}
+#if defined(VERBOSE) && defined(DEBUG)
+	else {
+		vdprintk("ssp_lh7x_irq_handler( NO ACTION )\n");
+	}
+#endif
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_lock
+* Function: ssp_lh7x_unlock
+*
+* Purpose:
+*	Lock/UnLock the SSP for a particular device (ts/ee)
+**********************************************************************/
+static int ssp_lh7x_lock(sspContext_t *sspContext, int device)
+{
+	int sts = -1;
+	int cr0;
+
+	spin_lock_irq(&sspContext->sspLock);
+	if (device == SSP_DEV_TOUCHSCREEN) {
+		/* Select the touchscreen */
+		sspContext->ssp_dev_sel = SSP_TOUCHSCREEN;
+		cr0 = ssp->cr0;
+		cr0 &= ~0x00F0;
+		/* National Microwire frame format --- SPI Polarity High */
+		/* Don't mess with data size or clock rate */
+		cr0 |= (SSP_CR0_FRF_NS | SSP_CR0_SPH);
+		ssp->cr0 = cr0;
+		vdprintk("ssp_lh7x_lock(SSP_DEV_TOUCHSCREEN)\n");
+		// sts = 0;
+	} else if (device == SSP_DEV_EEPROM) {
+		/* Select the eeprom */
+		sspContext->ssp_dev_sel = SSP_EEPROM;
+		cr0 = ssp->cr0;
+		cr0 &= ~0x00F0;
+		/* Motorola SPI frame --- w/SPH & w/SPO */
+		/* Don't mess with data size or clock rate */
+		cr0 |= (SSP_CR0_FRF_MOT | SSP_CR0_SPH | SSP_CR0_SPO);
+		ssp->cr0 = cr0;
+		vdprintk("ssp_lh7x_lock(SSP_DEV_EEPROM)\n");
+		// sts = 0;
+	}
+	//cpld->ssp_dev_sel = sspContext->ssp_dev_sel;
+
+	return(sts);
+}
+
+static int ssp_lh7x_unlock(sspContext_t *sspContext, int device)
+{
+	int sts = -1;
+// #define SSP_DEFAULT_DEVICE	SSP_TOUCHSCREEN
+#define SSP_DEFAULT_DEVICE	SSP_INVALID_DEVICE
+
+	spin_unlock_irq(&sspContext->sspLock);
+	if (device == SSP_DEV_TOUCHSCREEN) {
+		/* Select the default device */
+		sspContext->ssp_dev_sel = SSP_DEFAULT_DEVICE;
+		vdprintk("ssp_lh7x_unlock(SSP_DEV_TOUCHSCREEN)\n");
+		// sts = 0;
+	} else if (device == SSP_DEV_EEPROM) {
+		/* Select the default device */
+		sspContext->ssp_dev_sel = SSP_DEFAULT_DEVICE;
+		vdprintk("ssp_lh7x_unlock(SSP_DEV_EEPROM)\n");
+		// sts = 0;
+	}
+	//cpld->ssp_dev_sel = sspContext->ssp_dev_sel;
+
+	return(sts);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_disable
+*
+* Purpose:
+*	Disconnect I/O pins from the SSP module
+*	and disable the SSP peripheral and its clocks.
+**********************************************************************/
+static void ssp_lh7x_disable(void)
+{
+	int rcpcLockState;
+
+	vdprintk("ENTER: ssp_lh7x_disable()\n");
+
+	/* Switch all muxed I/O away from the SSP */
+	iocon->SSIMux &= ~(
+			SSIMUX_SSPIN |
+			SSIMUX_SSPOUT |
+			SSIMUX_SSPCLK |
+			SSIMUX_SSPENB |
+			SSIMUX_SSPFRM
+			);
+
+	/* Disable ssp clock */
+	rcpcLockState = rcpc_lh7x_lock(RCPC_UNLOCK);
+	rcpc->rcpc_sspClkControl |= RCPC_SCLKSEL_SSPCLK;
+	(void) rcpc_lh7x_lock(rcpcLockState);
+
+	/* Set control register to their reset defaults */
+	ssp->cr0 = 0;
+	ssp->cr1 = 0;
+
+	/* clear any receive overruns */
+	ssp->u.icr = SSP_IIR_RORIS;
+
+	//JMG /* disable the ssp DMA streams */
+	//JMG dmac->stream0.max = 0;
+	//JMG dmac->stream0.ctrl = 0;
+	//JMG dmac->stream1.max = 0;
+	//JMG dmac->stream1.ctrl = 0;
+	//JMG /* clear any previous SSP DMA completions */
+	//JMG dmac->clear = DMAC_EOT0 | DMAC_EOT1;
+
+	vdprintk("LEAVE: ssp_lh7x_disable()\n");
+
+	return;
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_enable
+*
+* Purpose:
+*	Disconnect I/O pins from the SSP module
+*	and disable the SSP peripheral and its clocks.
+**********************************************************************/
+static void ssp_lh7x_enable(void)
+{
+
+	vdprintk("ENTER: ssp_lh7x_enable()\n");
+
+	/* Enable the SSP */
+	ssp->cr1 |= SSP_CR1_SSE;		/* Synchronous serial port enable */
+
+	/* Switch all muxed I/O to the SSP */
+	/* Note that SSPENB is not required for spi */
+	iocon->SSIMux = (
+			SSIMUX_SSPIN |
+			SSIMUX_SSPOUT |
+			SSIMUX_SSPCLK |
+			//SSIMUX_SSPENB |
+			SSIMUX_SSPFRM
+			);
+		
+
+	vdprintk("LEAVE: ssp_lh7x_enable()\n");
+
+	return;
+}
+
+/**********************************************************************
+* Fill in our context structures
+**********************************************************************/
+
+static sspContext_t sspContext_l = {
+	ts_txTimeout: 10000,
+	ts_rxTimeout: 10000,
+	ee_txTimeout: 10000,
+	ee_rxTimeout: 10000,
+	haveIrq: 0,
+};
+
+/**********************************************************************
+* Function: ssp_request_pointer
+* Function: ssp_provide_pointer
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+void *ssp_request_pointer(int device, char *request)
+{
+	sspContext_t *sspContext = &sspContext_l;
+	void *vp = NULL;
+
+	dprintk("ENTER: ssp_request_pointer(\"%d\":\"%s\")\n", device, request);
+	if (device == SSP_DEV_TOUCHSCREEN) {
+		if        (strcmp(request, "write") == 0) {
+			vp = ssp_lh7x_write16;
+		} else if (strcmp(request, "read") == 0) {
+			vp = ssp_lh7x_read16;
+		} else if (strcmp(request, "enable_pen_down_irq") == 0) {
+			vp = ssp_lh7x_ts_pen_down_irq_enable;
+		} else if (strcmp(request, "disable_pen_down_irq") == 0) {
+			vp = ssp_lh7x_ts_pen_down_irq_disable;
+		} else if (strcmp(request, "is_pen_down") == 0) {
+			vp = ssp_lh7x_ts_pen_down;
+		} else if (strcmp(request, "lock") == 0) {
+			vp = ssp_lh7x_lock;
+		} else if (strcmp(request, "unlock") == 0) {
+			vp = ssp_lh7x_unlock;
+		} else if (strcmp(request, "sspContext") == 0) {
+			vp = sspContext;
+		} else if (strcmp(request, "flush_tx_fifo") == 0) {
+			vp = ssp_flush_tx_fifo;
+		} else if (strcmp(request, "flush_rx_fifo") == 0) {
+			vp = ssp_flush_rx_fifo;
+		} else if (strcmp(request, "ssp_busy_wait") == 0) {
+			vp = ssp_busy_wait;
+		} else if (strcmp(request, "chipselect_enable") == 0) {
+			vp = ssp_chipselect_enable;
+		} else if (strcmp(request, "chipselect_disable") == 0) {
+			vp = ssp_chipselect_disable;
+		} else if (strcmp(request, "chipselect_manual") == 0) {
+			vp = ssp_chipselect_manual;
+		}
+	} else if (device == SSP_DEV_EEPROM) {
+		if        (strcmp(request, "write") == 0) {
+			vp = ssp_lh7x_write16;
+		} else if (strcmp(request, "read") == 0) {
+			vp = ssp_lh7x_read16;
+		} else if (strcmp(request, "lock") == 0) {
+			vp = ssp_lh7x_lock;
+		} else if (strcmp(request, "unlock") == 0) {
+			vp = ssp_lh7x_unlock;
+		} else if (strcmp(request, "sspContext") == 0) {
+			vp = sspContext;
+		} else if (strcmp(request, "chipselect_enable") == 0) {
+			vp = ssp_chipselect_enable;
+		} else if (strcmp(request, "chipselect_disable") == 0) {
+			vp = ssp_chipselect_disable;
+		} else if (strcmp(request, "chipselect_manual") == 0) {
+			vp = ssp_chipselect_manual;
+		} else if (strcmp(request, "chipselect_automatic") == 0) {
+			vp = ssp_chipselect_automatic;
+		} else if (strcmp(request, "flush_tx_fifo") == 0) {
+			vp = ssp_flush_tx_fifo;
+		} else if (strcmp(request, "flush_rx_fifo") == 0) {
+			vp = ssp_flush_rx_fifo;
+		} else if (strcmp(request, "ssp_busy_wait") == 0) {
+			vp = ssp_busy_wait;
+		}
+	}
+	dprintk("LEAVE: ssp_request_pointer(0x%08X)\n", (unsigned int)vp);
+
+	return(vp);
+}
+
+void *ssp_provide_pointer(int device, char *request, void *vp)
+{
+	sspContext_t *sspContext = &sspContext_l;
+
+	dprintk("ENTER: ssp_provide_pointer(\"%d\":\"%s\":0x%08X)\n",
+			device, request, (unsigned int)vp);
+	if (device == SSP_DEV_TOUCHSCREEN) {
+		if (strcmp(request, "irq_wait_ptr") == 0) {
+			sspContext->irq_wait_ptr = vp;
+		} else {
+			vp = NULL;
+		}
+	} else if (device == SSP_DEV_EEPROM) {
+		vp = NULL;
+	} else {
+		vp = NULL;
+	}
+	dprintk("LEAVE: ssp_provide_pointer(0x%08X)\n", (unsigned int)vp);
+
+	return(vp);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_init
+*
+* Purpose:
+*	Register & Initialize the module
+**********************************************************************/
+static int __init ssp_lh7x_init(void)
+{
+	sspContext_t *sspContext = &sspContext_l;
+	int sts = 0;
+	int rcpcLockState;
+	int result;
+
+	vdprintk("ENTER: ssp_lh7x_init()\n");
+
+	vdprintk("ssp = 0x%08X\n", (unsigned int)ssp);
+
+	/* Determine the HCLK (bus clock) frequency in Hz */
+#ifdef OLDWAY
+	hclk_freq = ssp_lh7x_get_hclk_freq();
+#else
+	hclk_freq = hclkfreq_get();
+#endif
+
+	/*
+	* Disconnect I/O pins from the SSP module
+	* and disable the SSP peripheral and its clocks.
+	*/
+	ssp_lh7x_disable();
+
+	/* Initialize the RCPC SSP clock & prescaler */
+	rcpcLockState = rcpc_lh7x_lock(RCPC_UNLOCK);
+	rcpc->rcpc_sspClkPrescale = 0;					/* As fast as possible */
+	rcpc->rcpc_sspClkControl &= ~RCPC_SCLKSEL_SSPCLK;	/* Enable SSP clock */
+	(void) rcpc_lh7x_lock(rcpcLockState);
+
+	ssp->cpsr = SSP_CPSR_CPDVSR(SSP_PRESCALE_MIN);
+
+	/* Initialize CR0 */
+	ssp->cr0 = (
+		  SSP_CR0_DSS(16)		/* 16-bit data */
+		| SSP_CR0_FRF_NS		/* National Microwire frame format */
+		| SSP_CR0_SPH			/* SPI Polarity */
+		| SSP_CR0_SCR(1)		/* Serial clock rate (~922kbps) */
+		);
+
+	/* Initialize CR1 */
+	ssp->cr1 = (
+		  SSP_CR1_SSE				/* Synchronous serial port enable */
+		);
+
+	/* Set the SSP speed in bits per second */
+	/* Note this MUST be done after the SSP_CR0_FRF_xxx mode is set */
+	(void) ssp_lh7x_set_speed(LH7x_TS_BPS);
+
+	/* Select the touchscreen */
+	sspContext->ssp_dev_sel = SSP_TOUCHSCREEN;
+	//cpld->ssp_dev_sel = sspContext->ssp_dev_sel;
+
+	/* Flush the transmit FIFO */
+	ssp_flush_tx_fifo(sspContext);
+
+	/* Flush the receive FIFO */
+	ssp_flush_rx_fifo(sspContext);
+
+	/* clear any receive overruns */
+	ssp->u.icr = SSP_IIR_RORIS;
+
+	//printk("ssp->cr0 = 0x%04X\n", ssp->cr0);
+	//printk("ssp->cr1 = 0x%04X\n", ssp->cr1);
+	//printk("ssp->sr = 0x%04X\n", ssp->sr);
+	//printk("ssp->cpsr = 0x%04X\n", ssp->cpsr);
+	//printk("ssp->u.icr | u.iir = 0x%04X\n", ssp->u.icr);
+
+	ssp_chipselect_automatic();
+	/*
+	* Connect I/O pins from the SSP module
+	* and enable the SSP peripheral and its clocks.
+	*/
+	ssp_lh7x_enable();
+
+	/*
+	* Request IRQ2 and attach it to the touchscreen pen_down line and enable it
+	*/
+	sspContext->haveIrq = 0;
+	result = request_irq(0, ssp_lh7x_irq_handler,
+			SA_SAMPLE_RANDOM, DRVNAME, sspContext);
+	if (result < 0) {
+		printk("%s: cannot get requested IRQ(0)\n", DRVNAME);
+	} else {
+		sspContext->haveIrq = 1;
+		dprintk("%s: got requested IRQ(0)\n", DRVNAME);
+	}
+	ssp_lh7x_ts_pen_down_irq_enable(sspContext);
+
+	vdprintk("LEAVE: ssp_lh7x_init()\n");
+	return(sts);
+}
+
+/**********************************************************************
+* Function: ssp_lh7x_exit
+*
+* Purpose:
+*	Un-Register & Cleanup the module
+**********************************************************************/
+static void ssp_lh7x_exit(void)
+{
+	sspContext_t *sspContext = &sspContext_l;
+	int rcpcLockState;
+
+	vdprintk("ENTER: ssp_lh7x_exit()\n");
+
+	//printk("ssp->cr0 = 0x%04X\n", ssp->cr0);
+	//printk("ssp->cr1 = 0x%04X\n", ssp->cr1);
+	//printk("ssp->sr = 0x%04X\n", ssp->sr);
+	//printk("ssp->cpsr = 0x%04X\n", ssp->cpsr);
+	//printk("ssp->u.icr | u.iir = 0x%04X\n", ssp->u.icr);
+
+	/*
+	* Disable & Return IRQ 2
+	*/
+	lock_kernel();
+	ssp_lh7x_ts_pen_down_irq_disable(sspContext);
+	if (sspContext->haveIrq) {
+		free_irq(0, sspContext);
+		sspContext->haveIrq = 0;
+	}
+	unlock_kernel();
+
+	ssp->cr0 = 0;
+	ssp->cr1 = 0;
+	ssp->u.icr = SSP_IIR_RORIS;	/* clear any receive overruns */
+	ssp->cpsr = SSP_CPSR_CPDVSR(SSP_PRESCALE_MIN);
+
+	/* Turn off the  RCPC SSP clock */
+	rcpcLockState = rcpc_lh7x_lock(RCPC_UNLOCK);
+	rcpc->rcpc_sspClkControl |= RCPC_SCLKSEL_SSPCLK;	/* Disable SSP clock */
+	(void) rcpc_lh7x_lock(rcpcLockState);
+
+	vdprintk("LEAVE: ssp_lh7x_exit()\n");
+	return;
+}
+
+module_init(ssp_lh7x_init);
+module_exit(ssp_lh7x_exit);
+
+MODULE_AUTHOR("Jim Gleason / Lineo, Inc.");
+MODULE_DESCRIPTION("SSP Driver for Sharp LH7x EVB");
+MODULE_LICENSE("Copyright (c) 2002 Lineo, Inc.");
+
diff -urN linux-2.4.26/drivers/serial/amba_pl011.c linux-2.4.26-vrs1-lnode80/drivers/serial/amba_pl011.c
--- linux-2.4.26/drivers/serial/amba_pl011.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/serial/amba_pl011.c	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,854 @@
+/*
+ *  linux/drivers/char/serial_amba_pl011.c
+ *
+ *  Driver for AMBA PrimeCell PL011 serial ports
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ *  Based on drivers/char/serial_amba.c, which is:
+ *      Copyright 1999 ARM Limited
+ *      Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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/tty.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/serial_amba_pl011.h>
+
+#ifdef CONFIG_ARCH_LH79520
+#include <asm/arch/rcpc.h>
+#include <asm/arch/iocon.h>
+#include <asm/arch/gpio.h>
+#endif
+
+#define UART_NR		3
+
+#define SERIAL_AMBA_MAJOR	204
+#define SERIAL_AMBA_MINOR	16
+#define SERIAL_AMBA_NR		UART_NR
+
+#define CALLOUT_AMBA_NAME	"cuaam"
+#define CALLOUT_AMBA_MAJOR	205
+#define CALLOUT_AMBA_MINOR	16
+#define CALLOUT_AMBA_NR		UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *amba11_table[UART_NR];
+static struct termios *amba11_termios[UART_NR], *amba11_termios_locked[UART_NR];
+#ifdef SUPPORT_SYSRQ
+static struct console amba11_console;
+#endif
+static void amba11uart_tx_chars(struct uart_port *port);
+
+#define AMBA_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the AMBA UARTs
+ */
+#define UART_PUT_ICR(p, c)	writel((c), (p)->membase + AMBA_UARTICR)
+#define UART_GET_CHAR(p)	readb((p)->membase + AMBA_UARTDR)
+#define UART_PUT_CHAR(p, c)	writel((c), (p)->membase + AMBA_UARTDR)
+#define UART_GET_RSR(p)		readb((p)->membase + AMBA_UARTRSR)
+#define UART_GET_LCRH(p)	readb((p)->membase + AMBA_UARTLCR_H)
+#define UART_PUT_LCRH(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_H)
+
+#define UART_RX_DATA(s)		(((s) & AMBA_UARTFR_RXFE) == 0)
+#define UART_TX_READY(s)	(((s) & AMBA_UARTFR_TXFF) == 0)
+#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
+
+#define UART_GET_INT_STATUS(p)	readw((p)->membase + AMBA_UARTMIS)
+#define UART_GET_FR(p)		readw((p)->membase + AMBA_UARTFR)
+#define UART_GET_CR(p)		readl((p)->membase + AMBA_UARTCR)
+#define UART_PUT_CR(p,c)	writel((c), (p)->membase + AMBA_UARTCR)
+#define UART_GET_IMSC(p)	readl((p)->membase + AMBA_UARTIMSC)
+#define UART_PUT_IMSC(p,c)	writel((c), (p)->membase + AMBA_UARTIMSC)
+#define UART_GET_IBRD(p)	readl((p)->membase + AMBA_UARTIBRD)
+#define UART_PUT_IBRD(p,c)	writel((c), (p)->membase + AMBA_UARTIBRD)
+
+
+#define UART_DUMMY_RSR_RX	256
+#define UART_PORT_SIZE		64
+
+/*
+ * Our private driver data mappings.
+ */
+#define drv_old_status	driver_priv
+
+struct uart_amba11_port {
+	struct uart_port	port;
+	unsigned int		old_status;
+};
+
+static void amba11uart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	unsigned int mask;
+
+	mask = UART_GET_IMSC( port);
+	mask &= ~AMBA_UARTIMSC_TXIM;
+	UART_PUT_IMSC( port, mask);		/* disable Tx interrupts */
+}
+
+
+static void amba11uart_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	unsigned int mask;
+
+	mask = UART_GET_IMSC(port);
+	if( (mask & AMBA_UARTIMSC_TXIM) == 0) {	/* not already enabled	*/
+	    mask |= AMBA_UARTIMSC_TXIM;		/* enable Tx interrupts */
+	    UART_PUT_IMSC(port, mask);
+
+	    amba11uart_tx_chars(port);		/* start transmiting	*/
+	}
+
+}
+
+
+static void amba11uart_stop_rx(struct uart_port *port)
+{
+	unsigned int mask;
+
+	mask = UART_GET_IMSC(port);
+	mask &= ~(AMBA_UARTIMSC_RXIM | AMBA_UARTIMSC_RTIM);
+	UART_PUT_IMSC(port, mask);		/* disable Rx interrupts */
+}
+
+
+static void amba11uart_enable_ms(struct uart_port *port)
+{
+	unsigned int mask;
+
+	mask  = UART_GET_IMSC( port);
+	mask |= AMBA_UARTIMSC_Modem;
+	UART_PUT_IMSC(port, mask);		/* Disable modem interrupts */
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+amba11uart_rx_chars(struct uart_port *port, struct pt_regs *regs)
+#else
+amba11uart_rx_chars(struct uart_port *port)
+#endif
+{
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, rsr, max_count = 256;
+
+	status = UART_GET_FR(port);
+	while (UART_RX_DATA(status) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		ch = UART_GET_CHAR(port);
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
+		if (rsr & AMBA_UARTRSR_ANY) {
+			if (rsr & AMBA_UARTRSR_BE) {
+				rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
+				port->icount.brk++;
+				if (uart_handle_sysrq_char(port, ch, regs))
+					goto ignore_char;
+			} else if (rsr & AMBA_UARTRSR_PE)
+				port->icount.parity++;
+			else if (rsr & AMBA_UARTRSR_FE)
+				port->icount.frame++;
+			if (rsr & AMBA_UARTRSR_OE)
+				port->icount.overrun++;
+
+			rsr &= port->read_status_mask;
+
+			if (rsr & AMBA_UARTRSR_BE)
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			else if (rsr & AMBA_UARTRSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (rsr & AMBA_UARTRSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+		if ((rsr & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rsr & AMBA_UARTRSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+	ignore_char:
+		status = UART_GET_FR(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void amba11uart_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+	int status;
+
+	if (port->x_char) {
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		amba11uart_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+		status = UART_GET_FR(port);	
+	} while (UART_TX_READY(status));
+	//FJBwhile (--count > 0);
+	
+	if (uart_circ_chars_pending(xmit) <
+			WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		amba11uart_stop_tx(port, 0);
+}
+
+static void amba11uart_modem_status(struct uart_port *port)
+{
+	struct uart_amba11_port *uap = (struct uart_amba11_port *) port;
+	unsigned int status, delta;
+
+	UART_PUT_ICR(&uap->port, 0x3ff);
+
+	status = UART_GET_FR(&uap->port) & AMBA_UARTFR_MODEM_ANY;
+	//FJB - check CTS on modem port only (port 1)
+	if(port == (struct uart_port *)UART1_PHYS)
+	{
+	    if(GPIOG->dr & 0x01)
+	    {
+		//CTS is high meaning STOP SENDING
+		status |= AMBA_UARTFR_CTS;
+	    }
+	}
+
+	delta = status ^ uap->old_status;
+	uap->old_status = status;
+
+	if (!delta)
+		return;
+
+	if (delta & AMBA_UARTFR_DCD)
+		uart_handle_dcd_change(&uap->port, (status & AMBA_UARTFR_DCD) == 0);
+
+	if ((delta & AMBA_UARTFR_DSR) == 0)
+		uap->port.icount.dsr++;
+
+	if (delta & AMBA_UARTFR_CTS)
+		uart_handle_cts_change(&uap->port, (status & AMBA_UARTFR_CTS) == 0);
+
+	wake_up_interruptible(&uap->port.info->delta_msr_wait);
+}
+
+static void amba11uart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+
+	status = UART_GET_INT_STATUS(port);
+	do {
+		if (status & (AMBA_UART_IS_RT | AMBA_UART_IS_RX))
+
+#ifdef SUPPORT_SYSRQ
+			amba11uart_rx_chars(port, regs);
+#else
+			amba11uart_rx_chars(port);
+#endif
+
+		if (status & AMBA_UART_IS_TX)
+			amba11uart_tx_chars(port);
+
+
+		if (status & AMBA_UART_IS_MI)
+			amba11uart_modem_status(port);
+
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_GET_INT_STATUS(port);
+	} while (status & (AMBA_UART_IS_RT | AMBA_UART_IS_RX |
+			   AMBA_UART_IS_TX));
+}
+
+static unsigned int amba11uart_tx_empty(struct uart_port *port)
+{
+	return UART_GET_FR(port) & AMBA_UARTFR_BUSY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int amba11uart_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_FR(port);
+	if ((status & AMBA_UARTFR_DCD) == 0)
+		result |= TIOCM_CAR;
+	if ((status & AMBA_UARTFR_DSR) == 0)
+		result |= TIOCM_DSR;
+	if ((status & AMBA_UARTFR_CTS) == 0)
+		result |= TIOCM_CTS;
+
+	return result;
+}
+
+static void amba11uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	u_int cr;
+
+	cr = UART_GET_CR( port);
+	
+	if (mctrl & TIOCM_RTS)
+		cr &= ~AMBA_UARTCR_RTS;
+	else
+		cr |= AMBA_UARTCR_RTS;
+
+	if (mctrl & TIOCM_DTR)
+		cr &= ~AMBA_UARTCR_DTR;
+	else
+		cr |= AMBA_UARTCR_DTR;
+
+	UART_PUT_CR( port, cr);
+}
+
+
+static void amba11uart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned int lcr_h;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	lcr_h = UART_GET_LCRH(port);
+	if (break_state == -1)
+		lcr_h |= AMBA_UARTLCR_H_BRK;
+	else
+		lcr_h &= ~AMBA_UARTLCR_H_BRK;
+	UART_PUT_LCRH(port, lcr_h);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int amba11uart_startup(struct uart_port *port)
+{
+	int retval;
+	struct uart_amba11_port *uap = (struct uart_amba11_port *)port;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, amba11uart_int, 0, "amba", port);
+	if (retval)
+		return retval;
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;
+
+	/*
+	 * Finally, enable interrupts
+	 */
+#ifdef CONFIG_ARCH_LH79520
+	{
+	    /*
+	     * enable the clock to the serial ports
+	     */
+	    rcpcRegs_t  *rcpc  = (rcpcRegs_t *)IO_ADDRESS( RCPC_PHYS);
+	    ioconRegs_t *iocon = (ioconRegs_t *)IO_ADDRESS( IOCON_PHYS);
+
+	    rcpc->control       |= RCPC_CTRL_WRTLOCK_ENABLED;		/* unlock RCPC registers */
+	    barrier();
+
+	    rcpc->periphClkCtrl &= ~(RCPC_CLKCTRL_U0_DISABLE | RCPC_CLKCTRL_U1_DISABLE | RCPC_CLKCTRL_U2_DISABLE) ;
+	    rcpc->control       &= ~RCPC_CTRL_WRTLOCK_ENABLED;		/* lock RCPC registers   */
+
+	    /* set multiplexed pins for UART0 use */
+	    iocon->UARTMux |= (UARTMUX_UT0TXD | UARTMUX_UT0RXD);
+	}
+#endif /* CONFIG_ARCH_LH79520 */
+		
+	/* 
+	 * Use iobase to store a pointer to info. We need this to start a 
+	 * transmission as the tranmittr interrupt is only generated on
+	 * the transition to the idle state 
+	 */
+
+	UART_PUT_IMSC( port, (AMBA_UARTIMSC_RXIM | AMBA_UARTIMSC_RTIM) );
+	UART_PUT_CR( port, (AMBA_UARTCR_UARTEN | AMBA_UARTCR_RXE | AMBA_UARTCR_TXE));
+
+	return 0;
+}
+
+static void amba11uart_shutdown(struct uart_port *port)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_CR(port, 0);
+
+	/* disable break condition and fifos */
+	UART_PUT_LCRH(port, UART_GET_LCRH(port) &
+		~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
+}
+
+static void amba11uart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
+{
+	unsigned int lcr_h, old_cr;
+	unsigned long flags;
+	unsigned long old_imsc;
+
+#if DEBUG
+	printk("amba11uart_set_cflag(0x%x) called\n", cflag);
+#endif
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; break;
+	case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; break;
+	case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; break;
+	default:  lcr_h = AMBA_UARTLCR_H_WLEN_8; break; // CS8
+	}
+	if (cflag & CSTOPB)
+		lcr_h |= AMBA_UARTLCR_H_STP2;
+	if (cflag & PARENB) {
+		lcr_h |= AMBA_UARTLCR_H_PEN;
+		if (!(cflag & PARODD))
+			lcr_h |= AMBA_UARTLCR_H_EPS;
+	}
+	if (port->fifosize > 1)
+		lcr_h |= AMBA_UARTLCR_H_FEN;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	port->read_status_mask = AMBA_UARTRSR_OE;
+	if (iflag & INPCK)
+		port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= AMBA_UARTRSR_BE;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & IGNBRK) {
+		port->ignore_status_mask |= AMBA_UARTRSR_BE;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= AMBA_UARTRSR_OE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+
+	old_cr = UART_GET_CR( port);
+	old_imsc = UART_GET_IMSC( port) & ~AMBA_UARTIMSC_Modem;
+
+	if (UART_ENABLE_MS(port, cflag))
+	    	old_imsc |= AMBA_UARTIMSC_Modem;
+
+	/* Set baud rate */
+	UART_PUT_IBRD( port, quot);
+
+	/*
+	 * ----------v----------v----------v----------v-----
+	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	 * ----------^----------^----------^----------^-----
+	 */
+	UART_PUT_LCRH(port, lcr_h);
+	UART_PUT_IMSC( port, old_imsc);
+	UART_PUT_CR(port, old_cr);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *amba11uart_type(struct uart_port *port)
+{
+	return port->type == PORT_AMBA_PL011 ? "AMBA PrimeCell PL011" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void amba11uart_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int amba11uart_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_amba")
+			!= NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void amba11uart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_AMBA_PL011;
+		amba11uart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int amba11uart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA_PL011)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops amba11_pops = {
+	tx_empty:	amba11uart_tx_empty,
+	set_mctrl:	amba11uart_set_mctrl,
+	get_mctrl:	amba11uart_get_mctrl,
+	stop_tx:	amba11uart_stop_tx,
+	start_tx:	amba11uart_start_tx,
+	stop_rx:	amba11uart_stop_rx,
+	enable_ms:	amba11uart_enable_ms,
+	break_ctl:	amba11uart_break_ctl,
+	startup:	amba11uart_startup,
+	shutdown:	amba11uart_shutdown,
+	change_speed:	amba11uart_change_speed,
+	type:		amba11uart_type,
+	release_port:	amba11uart_release_port,
+	request_port:	amba11uart_request_port,
+	config_port:	amba11uart_config_port,
+	verify_port:	amba11uart_verify_port,
+};
+
+static struct uart_amba11_port amba11_ports[UART_NR] = {
+    {
+	.port = {
+		.membase=	(void *)IO_ADDRESS(UART0_PHYS), // VA
+		.mapbase=	UART0_PHYS,
+		.iotype=	SERIAL_IO_MEM,
+		.irq=		IRQ_UART0,
+		.uartclk=	14745600,
+		.fifosize=	16,
+		.ops=		&amba11_pops,
+		.flags=		ASYNC_BOOT_AUTOCONF,
+		.line=		0,
+	},
+    },
+    {
+	.port = {
+		.membase=	(void *)IO_ADDRESS(UART1_PHYS),
+		.mapbase=	UART1_PHYS,
+		.iotype=	SERIAL_IO_MEM,
+		.irq=		IRQ_UART1,
+		.uartclk=	14745600,
+		.fifosize=	16,
+		.ops=		&amba11_pops,
+		.flags=		ASYNC_BOOT_AUTOCONF,
+		.line=		1,
+	},
+    },
+    {
+	.port = {
+		.membase=	(void *)IO_ADDRESS(UART2_PHYS),
+		.mapbase=	UART2_PHYS,
+		.iotype=	SERIAL_IO_MEM,
+		.irq=		IRQ_UART2,
+		.uartclk=	14745600,
+		.fifosize=	16,
+		.ops=		&amba11_pops,
+		.flags=		ASYNC_BOOT_AUTOCONF,
+		.line=		2,
+	},
+    },
+};
+
+
+#ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE
+#ifdef used_and_not_const_char_pointer
+static int amba11uart_console_read(struct uart_port *port, char *s, u_int count)
+{
+	unsigned int status;
+	int c;
+#if DEBUG
+	printk("amba11uart_console_read() called\n");
+#endif
+
+	c = 0;
+	while (c < count) {
+		status = UART_GET_FR(port);
+		if (UART_RX_DATA(status)) {
+			*s++ = UART_GET_CHAR(port);
+			c++;
+		} else {
+			// nothing more to get, return
+			return c;
+		}
+	}
+	// return the count
+	return c;
+}
+#endif
+
+static void amba11uart_console_write(struct console *co, const char *s, u_int count)
+{
+	struct uart_port *port = &amba11_ports[co->index].port;
+	unsigned int status;
+	int i;
+
+	/*
+	 *	First save the CR then disable the interrupts
+	 */
+	unsigned int old_imsc;
+	old_imsc = UART_GET_IMSC( port);
+	UART_PUT_IMSC( port, 0);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_FR(port);
+		} while (!UART_TX_READY(status));
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_FR(port);
+			} while (!UART_TX_READY(status));
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the TCR
+	 */
+	do {
+		status = UART_GET_FR(port);
+	} while (status & AMBA_UARTFR_BUSY);
+	UART_PUT_IMSC( port, old_imsc);
+}
+
+static kdev_t amba11uart_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + co->index);
+}
+
+static int amba11uart_console_wait_key(struct console *co)
+{
+	struct uart_port *port = &amba11_ports[co->index].port;
+	unsigned int status;
+
+	do {
+		status = UART_GET_FR(port);
+	} while (!UART_RX_DATA(status));
+	return UART_GET_CHAR(port);
+}
+
+static void __init
+amba11uart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	if (UART_GET_CR(port) & AMBA_UARTCR_UARTEN) {
+		unsigned int lcr_h, quot;
+		lcr_h = UART_GET_LCRH(port);
+
+		*parity = 'n';
+		if (lcr_h & AMBA_UARTLCR_H_PEN) {
+			if (lcr_h & AMBA_UARTLCR_H_EPS)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((lcr_h & 0x60) == AMBA_UARTLCR_H_WLEN_7)
+			*bits = 7;
+		else
+			*bits = 8;
+
+		quot = UART_GET_IBRD(port);
+		*baud = port->uartclk / (16 * quot );
+	}
+}
+
+static int __init amba11uart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+	  co->index = 0;
+	port = &amba11_ports[co->index].port;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		amba11uart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console amba11_console = {
+	name:		"ttyAM",
+	write:		amba11uart_console_write,
+#ifdef used_and_not_const_char_pointer
+	read:		amba11uart_console_read,
+#endif
+	device:		amba11uart_console_device,
+	setup:		amba11uart_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init amba11uart_console_init(void)
+{
+	register_console(&amba11_console);
+}
+
+#define AMBA_CONSOLE	&amba11_console
+#else
+#define AMBA_CONSOLE	NULL
+#endif
+
+static struct uart_driver amba11_reg = {
+	owner:			THIS_MODULE,
+	normal_major:		SERIAL_AMBA_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	normal_name:		"ttyAM%d",
+	callout_name:		"cuaam%d",
+#else
+	normal_name:		"ttyAM",
+	callout_name:		"cuaam",
+#endif
+	normal_driver:		&normal,
+	callout_major:		CALLOUT_AMBA_MAJOR,
+	callout_driver:		&callout,
+	table:			amba11_table,
+	termios:		amba11_termios,
+	termios_locked:		amba11_termios_locked,
+	minor:			SERIAL_AMBA_MINOR,
+	nr:			UART_NR,
+	cons:			AMBA_CONSOLE,
+};
+
+static int __init amba11uart_init(void)
+{
+	int ret;
+
+	ret =  uart_register_driver(&amba11_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < UART_NR; i++)
+		  uart_add_one_port(&amba11_reg, &amba11_ports[i].port);
+	}
+	return ret;
+};
+
+static void __exit amba11uart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+	  uart_remove_one_port(&amba11_reg, &amba11_ports[i].port);
+
+	uart_unregister_driver(&amba11_reg);
+};
+
+module_init(amba11uart_init);
+module_exit(amba11uart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Lineo, Inc.");
+MODULE_DESCRIPTION("ARM AMBA PrimeCell PL011 serial port driver");
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.26/drivers/serial/Config.in linux-2.4.26-vrs1-lnode80/drivers/serial/Config.in
--- linux-2.4.26/drivers/serial/Config.in	2005-11-02 16:54:25.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/serial/Config.in	2005-11-02 17:37:31.000000000 -0400
@@ -20,6 +20,22 @@
      define_bool CONFIG_SERIAL_INTEGRATOR y
   fi
 
+  dep_tristate 'ARM PL011 PrimeCell serial port support' CONFIG_SERIAL_AMBA_PL011 $CONFIG_ARCH_LH79520
+
+  if [ "$CONFIG_SERIAL_AMBA" = "y" ]; then
+	  bool '  Support for console on AMBA serial port' CONFIG_SERIAL_AMBA_CONSOLE 
+  fi
+
+  if [ "$CONFIG_SERIAL_AMBA_PL011" = "y" ]; then
+	  bool '  Support for console on ARM PrimeCell PL011 serial port' CONFIG_SERIAL_AMBA_PL011_CONSOLE 
+  fi
+
+  dep_tristate 'Sharp LH7A400 serial port support' CONFIG_SERIAL_LH7A400 $CONFIG_ARCH_LH7A400
+
+  if [ "$CONFIG_SERIAL_LH7A400" = "y" ]; then
+	  bool '  Support for console on LH7A400 serial port' CONFIG_SERIAL_LH7A400_CONSOLE 
+  fi
+
   dep_tristate 'CLPS711X serial port support' CONFIG_SERIAL_CLPS711X $CONFIG_ARCH_CLPS711X
   dep_bool '  Support for console on CLPS711X serial port' CONFIG_SERIAL_CLPS711X_CONSOLE $CONFIG_SERIAL_CLPS711X
 
@@ -57,6 +73,8 @@
 dep_bool '  Support Bell Technologies HUB6 card' CONFIG_SERIAL_8250_HUB6 $CONFIG_SERIAL_8250_EXTENDED
 
 if [ "$CONFIG_SERIAL_AMBA" = "y" -o \
+     "$CONFIG_SERIAL_AMBA_PL011" = "y" -o \
+     "$CONFIG_SERIAL_LH7A400" = "y" -o \
      "$CONFIG_SERIAL_CLPS711X" = "y" -o \
      "$CONFIG_SERIAL_SA1100" = "y" -o \
      "$CONFIG_SERIAL_ANAKIN" = "y" -o \
@@ -67,6 +85,8 @@
    define_bool CONFIG_SERIAL_CORE y
 else
    if [ "$CONFIG_SERIAL_AMBA" = "m" -o \
+        "$CONFIG_SERIAL_AMBA_PL011" = "m" -o \
+        "$CONFIG_SERIAL_LH7A400" = "m" -o \
         "$CONFIG_SERIAL_CLPS711X" = "m" -o \
         "$CONFIG_SERIAL_SA1100" = "m" -o \
         "$CONFIG_SERIAL_ANAKIN" = "m" -o \
@@ -78,6 +98,8 @@
    fi
 fi
 if [ "$CONFIG_SERIAL_AMBA_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_AMBA_PL011_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_LH7A400_CONSOLE" = "y" -o \
      "$CONFIG_SERIAL_CLPS711X_CONSOLE" = "y" -o \
      "$CONFIG_SERIAL_SA1100_CONSOLE" = "y" -o \
      "$CONFIG_SERIAL_ANAKIN_CONSOLE" = "y" -o \
diff -urN linux-2.4.26/drivers/serial/core.c linux-2.4.26-vrs1-lnode80/drivers/serial/core.c
--- linux-2.4.26/drivers/serial/core.c	2005-11-02 16:54:25.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/serial/core.c	2005-11-02 17:37:32.000000000 -0400
@@ -1938,6 +1938,7 @@
 }
 
 extern void ambauart_console_init(void);
+extern void amba11uart_console_init(void);
 extern void anakin_console_init(void);
 extern void clps711xuart_console_init(void);
 extern void sa1100_rs_console_init(void);
@@ -1970,6 +1971,12 @@
 #ifdef CONFIG_SERIAL_UART00_CONSOLE
 	uart00_console_init();
 #endif
+#ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE
+	amba11uart_console_init();
+#endif
+#ifdef CONFIG_SERIAL_LH7A400_CONSOLE
+	lh7a400uart_console_init();
+#endif
 }
 #endif /* CONFIG_SERIAL_CORE_CONSOLE */
 
diff -urN linux-2.4.26/drivers/serial/Makefile linux-2.4.26-vrs1-lnode80/drivers/serial/Makefile
--- linux-2.4.26/drivers/serial/Makefile	2005-11-02 16:54:25.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/serial/Makefile	2005-11-02 17:37:31.000000000 -0400
@@ -27,6 +27,8 @@
 obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
 obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
 obj-$(CONFIG_SERIAL_AMBA) += amba.o
+obj-$(CONFIG_SERIAL_AMBA_PL011) += amba_pl011.o
+obj-$(CONFIG_SERIAL_LH7A400) += serial_lh7a400.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
 obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
 obj-$(CONFIG_SERIAL_UART00) += uart00.o
diff -urN linux-2.4.26/drivers/video/Config.in linux-2.4.26-vrs1-lnode80/drivers/video/Config.in
--- linux-2.4.26/drivers/video/Config.in	2005-11-02 16:54:25.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/video/Config.in	2005-11-02 17:37:32.000000000 -0400
@@ -40,6 +40,11 @@
      dep_bool '  CLPS711X LCD support' CONFIG_FB_CLPS711X $CONFIG_ARCH_CLPS711X
      dep_bool '  SA-1100 LCD support' CONFIG_FB_SA1100 $CONFIG_ARCH_SA1100
      dep_bool '  MX1ADS LCD support' CONFIG_FB_DBMX1 $CONFIG_ARCH_MX1ADS
+     if [ "$CONFIG_ARCH_LH79520" = "y" -o \
+          "$CONFIG_ARCH_LH7A400" = "y" ];then
+           bool '  ARM PL110 LCD support' CONFIG_FB_PL110
+     fi
+
      if [ "$CONFIG_FB_SA1100" = "y" -a "$CONFIG_SA1100_CERF" = "y" ]; then
         choice 'CerfBoard LCD Display Size' \
 		"3.8_Color		CONFIG_CERF_LCD_38_A \
@@ -50,6 +55,15 @@
      if [ "$CONFIG_FB_SA1100" = "y" -a "$CONFIG_SA1100_CERF_CPLD" = "y" ]; then
        bool 'Cerfboard Backlight (CerfPDA)' CONFIG_SA1100_CERF_LCD_BACKLIGHT
      fi
+     if [ "$CONFIG_FB_PL110" = "y" ]; then
+	 choice 'LCD Display panel' \
+	 	"Panasonic                        CONFIG_PL110_PAN78 \
+		 Sharp_LQ039Q2DS53-HR-TFT         CONFIG_PL110_LQ39  \
+		 Sharp_LM057QCTT03-QVGA-STN       CONFIG_PL110_LM57  \
+		 Sharp_LQ057Q3DC02-VGA/QVGA-TFT   CONFIG_PL110_LQ57  \
+		 Sharp_LQ121S1DG31-800x600-TFT    CONFIG_PL110_LQ121 \
+		 Sharp_LQ104V1DG11-640x480-TFT    CONFIG_PL110_LQ104" Sharp_LQ039Q2DS53-HR-TFT
+     fi
    fi
    dep_tristate '  CyberPro 2000/2010/5000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
    if [ "$CONFIG_APOLLO" = "y" ]; then
@@ -280,7 +294,8 @@
 	   "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
 	   "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
 	   "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y"  -o \
-	   "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_CLPS711X" = "y" ]; then
+	   "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_CLPS711X" = "y" -o \
+           "$CONFIG_FB_PL110" = "y" ]; then
 	 define_tristate CONFIG_FBCON_MFB y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
@@ -288,20 +303,22 @@
 	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
 	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
 	      "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
-	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_CLPS711X" = "m"  ]; then
+	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_CLPS711X" = "m" -o \
+              "$CONFIG_FB_PL110" = "m" ]; then
 	    define_tristate CONFIG_FBCON_MFB m
 	 fi
       fi
       if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
 	   "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
 	   "$CONFIG_FB_TX3912" = "y"  -o "$CONFIG_FB_CLPS711X" = "y" -o \
-           "$CONFIG_FB_DBMX1" = "y" ]; then
+           "$CONFIG_FB_DBMX1" = "y" -o "$CONFIG_FB_PL110" = "y"]; then
 	 define_tristate CONFIG_FBCON_CFB2 y
 	 define_tristate CONFIG_FBCON_CFB4 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
-	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_CLPS711X" = "m" ]; then
+	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_CLPS711X" = "m" -o \
+	      "$CONFIG_FB_PL110" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB2 m
 	    define_tristate CONFIG_FBCON_CFB4 m
 	 fi
@@ -329,6 +346,7 @@
 	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
 	   "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \
 	   "$CONFIG_FB_INTEL" = "y" -o \
+	   "$CONFIG_FB_PL110" = "y" -o \
            "$CONFIG_FB_DBMX1" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB8 y
       else
@@ -352,6 +370,7 @@
 	      "$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_INTEL" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
 	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \
+	      "$CONFIG_FB_PL110" = "m" -o \
 	      "$CONFIG_FB_STI" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
@@ -373,6 +392,7 @@
 	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
 	   "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" -o \
 	   "$CONFIG_FB_ANAKIN" = "y" -o \
+	   "$CONFIG_FB_PL110" = "y" -o \
            "$CONFIG_FB_DBMX1" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB16 y
       else
@@ -390,6 +410,7 @@
 	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_INTEL" = "m" -o \
+	      "$CONFIG_FB_PL110" = "m" -o \
 	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
 	      "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB16 m
diff -urN linux-2.4.26/drivers/video/fbcon.c linux-2.4.26-vrs1-lnode80/drivers/video/fbcon.c
--- linux-2.4.26/drivers/video/fbcon.c	2003-08-25 07:44:42.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/video/fbcon.c	2005-11-02 17:37:32.000000000 -0400
@@ -2401,9 +2401,9 @@
 			   p->type == FB_TYPE_INTERLEAVED_PLANES)) {
 
 	    /* monochrome */
-	    unsigned char inverse = p->inverse || p->visual == FB_VISUAL_MONO01
-		? 0x00 : 0xff;
-
+	    //FJBunsigned char inverse = p->inverse || p->visual == FB_VISUAL_MONO01
+	    //FJB	? 0x00 : 0xff;
+	    unsigned char inverse = 0; 
 	    int is_hga = !strncmp(p->fb_info->modename, "HGA", 3);
 	    /* can't use simply memcpy because need to apply inverse */
 	    for( y1 = 0; y1 < LOGO_H; y1++ ) {
diff -urN linux-2.4.26/drivers/video/fbmem.c linux-2.4.26-vrs1-lnode80/drivers/video/fbmem.c
--- linux-2.4.26/drivers/video/fbmem.c	2005-11-02 16:54:25.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/video/fbmem.c	2005-11-02 17:37:32.000000000 -0400
@@ -109,6 +109,7 @@
 extern int chips_init(void);
 extern int g364fb_init(void);
 extern int sa1100fb_init(void);
+extern int pl110fb_init(void);
 extern int fm2fb_init(void);
 extern int fm2fb_setup(char*);
 extern int q40fb_init(void);
@@ -305,6 +306,9 @@
 #ifdef CONFIG_FB_SA1100
 	{ "sa1100", sa1100fb_init, NULL },
 #endif
+#ifdef CONFIG_FB_PL110
+	{ "pl110", pl110fb_init, NULL },
+#endif
 #ifdef CONFIG_FB_SUN3
 	{ "sun3", sun3fb_init, sun3fb_setup },
 #endif
diff -urN linux-2.4.26/drivers/video/Makefile linux-2.4.26-vrs1-lnode80/drivers/video/Makefile
--- linux-2.4.26/drivers/video/Makefile	2005-11-02 16:54:25.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/video/Makefile	2005-11-02 17:37:32.000000000 -0400
@@ -4,6 +4,14 @@
 
 O_TARGET := video.o
 
+#
+# The following is VERY IMPORTANT for the pl110; newer gccs won't compile the driver
+# properly and it will hang at "Console: switching to colour frame buffer device ..."
+#
+ifeq ($(CONFIG_FB_PL110),y)
+EXTRA_CFLAGS =-O1
+endif
+
 mod-subdirs	:= matrox sti
 
 # All of the (potential) objects that export symbols.
@@ -15,7 +23,7 @@
 		  fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
 		  fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
 		  fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
-		  cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
+		  cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o pl110fb.o
 
 # Each configuration option enables a list of files.
 
@@ -137,6 +145,7 @@
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
 obj-$(CONFIG_FB_ANAKIN)           += anakinfb.o
+obj-$(CONFIG_FB_PL110)            += pl110fb.o
 
 # Generic Low Level Drivers
 
diff -urN linux-2.4.26/drivers/video/pl110fb.c linux-2.4.26-vrs1-lnode80/drivers/video/pl110fb.c
--- linux-2.4.26/drivers/video/pl110fb.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/video/pl110fb.c	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,1719 @@
+/*
+ * linux/drivers/video/pl110fb.c
+ *
+ * ARM PrimeCell PL110 LCD Controller Frame Buffer Driver
+ *
+ * Copyright (C) 2002 Lineo, Inc.
+ * Based on sa1100fb.c, which is Copyright (C) Eric A. Thomas
+ *
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/uaccess.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+
+#ifdef CONFIG_ARCH_LH79520
+#include <asm/arch/rcpc.h>
+#include <asm/arch/cpld.h>
+#include <asm/arch/iocon.h>
+#endif
+
+#ifdef CONFIG_ARCH_LH7A400
+#include <asm/arch/cpld.h>
+#include <asm/arch/gpio.h>
+#endif
+
+/*
+ * debugging?
+ */
+#define DEBUG 0
+/*
+ * Complain if VAR is out of range.
+ */
+#define DEBUG_VAR 1
+#define BACKLIGHT	_BIT(15)
+//#define GPOUT16  (*(volatile u16*)GPOUT16_BASE)
+
+//#define GPOUT16  (*(volatile u16*)GPOUT16_BASE)
+
+// global defined in marm-lh7x.c -- driver
+extern unsigned short marm_backlight;
+#define GPOUT16 marm_backlight
+
+#include "pl110fb.h"
+
+extern unsigned int hclkfreq_get( void);
+
+void (*pl110fb_blank_helper)(int blank);
+EXPORT_SYMBOL(pl110fb_blank_helper);
+
+
+//#define _444 1
+#define _555 1
+
+#if _444
+static struct pl110fb_rgb rgb_8 = {
+	red:	{ offset: 0,  length: 4, },
+	green:	{ offset: 0,  length: 4, },
+	blue:	{ offset: 0,  length: 4, },
+	transp:	{ offset: 0,  length: 0, },
+};
+#elif _555
+static struct pl110fb_rgb rgb_8 = {
+	red:	{ offset: 0,  length: 5, },
+	green:	{ offset: 0,  length: 5, },
+	blue:	{ offset: 0,  length: 5, },
+	transp:	{ offset: 0,  length: 0, },
+};
+#else
+#error define _444 or _555
+#endif
+
+
+#if 0	// 5-6-5
+static struct pl110fb_rgb def_rgb_16 = {
+	red:	{ offset: 11, length: 5, },
+	green:	{ offset: 5,  length: 6, },
+	blue:	{ offset: 0,  length: 5, },
+	transp:	{ offset: 0,  length: 0, },
+};
+#else // 5-5-5
+static struct pl110fb_rgb def_rgb_16 = {
+	red:	{ offset: 10, length: 5, },
+	green:	{ offset: 5,  length: 5, },
+	blue:	{ offset: 0,  length: 5, },
+	transp:	{ offset: 0,  length: 0, },
+};
+#endif
+
+
+#define VERTICAL_REFRESH	70	/* optimum refresh rate, in Hz. */
+
+
+#if defined(CONFIG_ARCH_LH79520) || defined(CONFIG_ARCH_LH7A400)
+static struct pl110fb_mach_info lh_info __initdata = {
+
+#if defined(CONFIG_PL110_LQ39)
+	bpp:            8,
+	xres:		640,		yres:		480,
+	hsync_len:	    13, /* hsw */	   	vsync_len:	    2,  /* vsw */
+	left_margin:	21, /* hbp */		upper_margin:	5,  /* vbp */
+	right_margin:	11, /* hfp */		lower_margin:	5,  /* vfp */
+
+	sync:		FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+
+	LCDtiming2:	0,
+
+	LCDtiming3:	0,
+
+	LCDcontrol:      LCD_CTRL_BW_COLOR | LCD_CTRL_WATERMARK ,
+
+	LCDICPcontrol:	0,		//LCDICP_CONTROL_CLSEN | LCDICP_CONTROL_SPSEN,
+
+	LCDICPsetup:	LCDICP_SETUP_VERT_NORMAL | LCDICP_SETUP_HORIZ_NORMAL,
+
+	LCDICPtiming1:	LCDICP_TIMING1_PSDEL(9) | LCDICP_TIMING1_REVDEL(3) | LCDICP_TIMING1_LPDEL(14),
+
+	LCDICPtiming2:	LCDICP_TIMING2_PSDEL2(209) | LCDICP_TIMING2_SPLVALUE(34),
+
+	/*
+	 * The Sharp LQ039Q2DS53 panel takes an RGB666 signal,
+	 * but we provide it with an RGB555 signal instead (def_rgb_16).
+	 */
+
+	/* bpp set based on DIP switches on LCD board */
+
+//	xres:		320,			yres:		240,
+//	hsync_len:	13, /* hsw */		vsync_len:	2,  /* vsw */
+//	left_margin:	21, /* hbp */		upper_margin:	5,  /* vbp */
+//	right_margin:	11, /* hfp */		lower_margin:	5,  /* vfp */
+
+//	sync:		FB_SYNC_VERT_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+//	LCDtiming2:	LCD_TIMING2_IPC,
+//
+//	LCDtiming3:	0,
+//
+//	LCDcontrol:     LCD_CTRL_TFT | LCD_CTRL_BW_COLOR | LCD_CTRL_WATERMARK,
+//
+//	LCDICPcontrol:	LCDICP_CONTROL_CLSEN | LCDICP_CONTROL_SPSEN,
+//
+//	LCDICPsetup:	LCDICP_SETUP_MODE_HRTFT | LCDICP_SETUP_VERT_NORMAL | LCDICP_SETUP_HORIZ_NORMAL,
+//
+//	LCDICPtiming1:	LCDICP_TIMING1_PSDEL(9) | LCDICP_TIMING1_REVDEL(3) | LCDICP_TIMING1_LPDEL(14),
+//
+//	LCDICPtiming2:	LCDICP_TIMING2_PSDEL2(209) | LCDICP_TIMING2_SPLVALUE(34),
+
+
+#elif defined(CONFIG_PL110_PAN78)
+	bpp:            8,
+	xres:		640,		yres:		480,
+	hsync_len:	13, /* hsw */		vsync_len:	2,  /* vsw */
+	left_margin:	21, /* hbp */		upper_margin:	5,  /* vbp */
+	right_margin:	11, /* hfp */		lower_margin:	5,  /* vfp */
+
+	sync:		FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+
+	LCDtiming2:	0,
+
+	LCDtiming3:	0,
+
+	LCDcontrol:     LCD_CTRL_BW_COLOR | LCD_CTRL_WATERMARK,
+
+	LCDICPcontrol:	0, 		//LCDICP_CONTROL_CLSEN | LCDICP_CONTROL_SPSEN,
+
+	LCDICPsetup:	LCDICP_SETUP_VERT_NORMAL | LCDICP_SETUP_HORIZ_NORMAL,
+
+	LCDICPtiming1:	LCDICP_TIMING1_PSDEL(9) | LCDICP_TIMING1_REVDEL(3) | LCDICP_TIMING1_LPDEL(14),
+
+	LCDICPtiming2:	LCDICP_TIMING2_PSDEL2(209) | LCDICP_TIMING2_SPLVALUE(34),
+
+#elif defined(CONFIG_PL110_LM57)
+	bpp:            8,
+	xres:		320,		yres:		240,
+#elif defined(CONFIG_PL110_LQ57)
+	bpp:            8,
+	xres:		240,		yres:		320,
+#elif defined(CONFIG_PL110_LQ121)
+	bpp:		4,
+	xres:		320,		yres:		240,
+#elif defined(CONFIG_PL110_LQ101)
+#else
+#error "You must have an LCD panel configured"
+#endif
+};
+#endif // CONFIG_ARCH_LH79520 || CONFIG_ARCH_LH7A400
+
+
+
+static struct pl110fb_mach_info * __init
+pl110fb_get_machine_info(struct pl110fb_info *fbi)
+{
+	struct pl110fb_mach_info *inf = NULL;
+
+#if defined(CONFIG_ARCH_LH79520)
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+	u8 dipSw = (u8)~(cpld->display_dip_sw & 0xff);
+
+	if( machine_is_lh79520evb()) {
+	    inf = &lh_info;
+
+	    /* set bpp based on LCD board dip switch 0 */
+	    inf->bpp = 8; //(dipSw & 1 ? 8 : 16);
+	}
+#endif
+#if defined(CONFIG_ARCH_LH7A400)
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+	u8 dipSw = (u8)~(cpld->u3.dispDipSw & 0xff);
+
+	if( machine_is_lh7a400evb()) {
+	    inf = &lh_info;
+
+	    /* set bpp based on LCD board dip switch 0 */
+	    inf->bpp = (dipSw & 1 ? 8 : 16);
+	}
+#endif
+	return inf;
+}
+
+
+static int pl110fb_activate_var(struct fb_var_screeninfo *var, struct pl110fb_info *);
+static void set_ctrlr_state(struct pl110fb_info *fbi, u_int state);
+
+
+static inline void
+pl110fb_schedule_task(struct pl110fb_info *fbi, u_int state)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/*
+	 * We need to handle two requests being made at the same time.
+	 * There are two important cases:
+	 *  1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE)
+	 *     We must perform the unblanking, which will do our REENABLE for us.
+	 *  2. When we are blanking, but immediately unblank before we have
+	 *     blanked.  We do the "REENABLE" thing here as well, just to be sure.
+	 */
+	if (fbi->task_state == C_ENABLE && state == C_REENABLE)
+		state = (u_int) -1;
+	if (fbi->task_state == C_DISABLE && state == C_ENABLE)
+		state = C_REENABLE;
+
+	if (state != (u_int)-1) {
+		fbi->task_state = state;
+		schedule_task(&fbi->task);
+	}
+	local_irq_restore(flags);
+}
+
+/*
+ * Get the VAR structure pointer for the specified console
+ */
+static inline struct fb_var_screeninfo *
+get_con_var(struct fb_info *info, int con)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	return (con == fbi->currcon || con == -1) ? &fbi->fb.var : &fb_display[con].var;
+}
+
+/*
+ * Get the DISPLAY structure pointer for the specified console
+ */
+static inline struct display *
+get_con_display(struct fb_info *info, int con)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	return (con < 0) ? fbi->fb.disp : &fb_display[con];
+}
+
+/*
+ * Get the CMAP pointer for the specified console
+ */
+static inline struct fb_cmap *
+get_con_cmap(struct fb_info *info, int con)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+
+	return (con == fbi->currcon || con == -1) ? &fbi->fb.cmap : &fb_display[con].cmap;
+}
+
+static inline u_int
+chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+	chan &= 0xffff;
+	chan >>= 16 - bf->length;
+	return chan << bf->offset;
+}
+
+
+static int
+pl110fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
+		       u_int trans, struct fb_info *info)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	u_int val, ret = 1;
+	lcdRegs_t    *LCD = (lcdRegs_t *)IO_ADDRESS(LCD_PHYS);
+
+	if (regno < fbi->palette_size) {
+
+#if _444 // 4:4:4 
+		val  = ((red   >> 4)  & 0x0F00) >> 7;	// bits 4:0
+		val |= ((green >> 8)  & 0x00F0) << 2;	// bits 9:5
+		val |= ((blue  >> 12) & 0x000F) << 11;	// bits 14:10
+#else // 5:5:5
+		val  = (red   & 0xF800) >> 11;		// bits 4:0
+		val |= (green & 0xF800) >>  6;		// bits 9:5
+		val |= (blue  & 0xF800) >>  1;		// bits 14:10
+		val |= 0x8000;						// always set intensity bit
+#endif
+
+		if( regno & 1)			/* setting higher number entry */
+		    LCD->palette[regno >> 1] = (LCD->palette[regno >> 1] & 0x0000ffff) | (val << 16);
+		else				/* setting lower number entry	*/
+		    LCD->palette[regno >> 1] = (LCD->palette[regno >> 1] & 0xffff0000) | val;
+
+		/* */
+//		DPRINTK( "reg=%x  r=%x  g=%x  b=%x  t=%x    addr=%x  val=%x  entry=%x\n",
+//			regno, red, green, blue, trans, &LCD->palette[regno >> 1], val,
+//			LCD->palette[regno >> 1]);
+		/* */
+
+		ret = 0;
+	}
+	return ret;
+}
+
+static int
+pl110fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		   u_int trans, struct fb_info *info)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	struct display *disp = get_con_display(info, fbi->currcon);
+	u_int val;
+	int ret = 1;
+
+	/*
+	 * If inverse mode was selected, invert all the colours
+	 * rather than the register number.  The register number
+	 * is what you poke into the framebuffer to produce the
+	 * colour you requested.
+	 */
+	if (disp->inverse) {
+		red   = 0xffff - red;
+		green = 0xffff - green;
+		blue  = 0xffff - blue;
+	}
+
+	/*
+	 * If greyscale is true, then we convert the RGB value
+	 * to greyscale no mater what visual we are using.
+	 */
+	if (fbi->fb.var.grayscale)
+		red = green = blue = (19595 * red + 38470 * green +
+					7471 * blue) >> 16;
+
+	switch (fbi->fb.disp->visual) {
+	case FB_VISUAL_TRUECOLOR:
+		/*
+		 * 12 or 16-bit True Colour.  We encode the RGB value
+		 * according to the RGB bitfield information.
+		 */
+		if (regno < 16) {
+			u16 *pal = fbi->fb.pseudo_palette;
+
+			val  = chan_to_field(red, &fbi->fb.var.red);
+			val |= chan_to_field(green, &fbi->fb.var.green);
+			val |= chan_to_field(blue, &fbi->fb.var.blue);
+
+			pal[regno] = val;
+			ret = 0;
+		}
+		break;
+
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		ret = pl110fb_setpalettereg(regno, red, green, blue, trans, info);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ *  pl110fb_display_dma_period()
+ *    Calculate the minimum period (in picoseconds) between two DMA
+ *    requests for the LCD controller.
+ */
+static unsigned int
+pl110fb_display_dma_period(struct fb_var_screeninfo *var)
+{
+	unsigned int mem_bits_per_pixel;
+
+	mem_bits_per_pixel = var->bits_per_pixel;
+	if (mem_bits_per_pixel == 12)
+		mem_bits_per_pixel = 16;
+
+	/*
+	 * Period = pixclock * bits_per_byte * bytes_per_transfer
+	 *		/ memory_bits_per_pixel;
+	 */
+	return var->pixclock * 8 * 16 / mem_bits_per_pixel;
+}
+
+/*
+ *  pl110fb_decode_var():
+ *    Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *    if it's too big, return -EINVAL.
+ *
+ *    Suggestion: Round up in the following order: bits_per_pixel, xres,
+ *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ *    bitfields, horizontal timing, vertical timing.
+ */
+static int
+pl110fb_validate_var(struct fb_var_screeninfo *var,
+		      struct pl110fb_info *fbi)
+{
+	int ret = -EINVAL;
+
+	if (var->xres < MIN_XRES)
+		var->xres = MIN_XRES;
+	if (var->yres < MIN_YRES)
+		var->yres = MIN_YRES;
+	if (var->xres > fbi->max_xres)
+		var->xres = fbi->max_xres;
+	if (var->yres > fbi->max_yres)
+		var->yres = fbi->max_yres;
+	var->xres_virtual =
+	    var->xres_virtual < var->xres ? var->xres : var->xres_virtual;
+	var->yres_virtual =
+	    var->yres_virtual < var->yres ? var->yres : var->yres_virtual;
+
+	DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+	case 4:		ret = 0; break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:		ret = 0; break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:	ret = 0; break;
+#endif
+	default:
+		break;
+	}
+
+#ifdef CONFIG_CPU_FREQ
+	printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n",
+		pl110fb_display_dma_period(var),
+		cpufreq_get(smp_processor_id()));
+#endif
+
+	return ret;
+}
+
+
+static void
+pl110fb_hw_set_var(struct fb_var_screeninfo *var, struct pl110fb_info *fbi)
+{
+	u_long palette_mem_size;
+
+	fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
+
+	palette_mem_size = fbi->palette_size * sizeof(u16);
+
+	DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
+
+	fb_set_cmap(&fbi->fb.cmap, 1, pl110fb_setcolreg, &fbi->fb);
+
+	pl110fb_activate_var(var, fbi);
+}
+
+/*
+ * pl110fb_set_var():
+ *	Set the user defined part of the display for the specified console
+ */
+static int
+pl110fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	struct fb_var_screeninfo *dvar = get_con_var(&fbi->fb, con);
+	struct display *display = get_con_display(&fbi->fb, con);
+	int err, chgvar = 0, rgbidx;
+
+	DPRINTK("called\n");
+
+	/*
+	 * Decode var contents into a par structure, adjusting any
+	 * out of range values.
+	 */
+	err = pl110fb_validate_var(var, fbi);
+	if (err) {
+	    DPRINTK( "pl110fb_validate_var returned err=%d\n", err);
+	    return err;
+	}
+
+	if (var->activate & FB_ACTIVATE_TEST)
+		return 0;
+
+	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
+		return -EINVAL;
+
+	if (dvar->xres != var->xres)
+		chgvar = 1;
+	if (dvar->yres != var->yres)
+		chgvar = 1;
+	if (dvar->xres_virtual != var->xres_virtual)
+		chgvar = 1;
+	if (dvar->yres_virtual != var->yres_virtual)
+		chgvar = 1;
+	if (dvar->bits_per_pixel != var->bits_per_pixel)
+		chgvar = 1;
+	if (con < 0)
+		chgvar = 0;
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+	case 4:
+		if (fbi->cmap_static)
+			display->visual	= FB_VISUAL_STATIC_PSEUDOCOLOR;
+		else
+			display->visual	= FB_VISUAL_PSEUDOCOLOR;
+		display->line_length	= var->xres / 2;
+		display->dispsw		= &fbcon_cfb4;
+		rgbidx			= RGB_8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		if (fbi->cmap_static)
+			display->visual	= FB_VISUAL_STATIC_PSEUDOCOLOR;
+		else
+			display->visual	= FB_VISUAL_PSEUDOCOLOR;
+		display->line_length	= var->xres;
+		display->dispsw		= &fbcon_cfb8;
+		rgbidx			= RGB_8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		display->visual		= FB_VISUAL_TRUECOLOR;
+		display->line_length	= var->xres * 2;
+		display->dispsw		= &fbcon_cfb16;
+		display->dispsw_data	= fbi->fb.pseudo_palette;
+		rgbidx			= RGB_16;
+		break;
+#endif
+	default:
+		rgbidx = 0;
+		display->dispsw = &fbcon_dummy;
+		break;
+	}
+
+	display->screen_base	= fbi->screen_cpu;
+	display->next_line	= display->line_length;
+	display->type		= fbi->fb.fix.type;
+	display->type_aux	= fbi->fb.fix.type_aux;
+	display->ypanstep	= fbi->fb.fix.ypanstep;
+	display->ywrapstep	= fbi->fb.fix.ywrapstep;
+	display->can_soft_blank	= 1;
+	display->inverse	= fbi->cmap_inverse;
+
+	*dvar			= *var;
+	dvar->activate		&= ~FB_ACTIVATE_ALL;
+
+	/*
+	 * Copy the RGB parameters for this display
+	 * from the machine specific parameters.
+	 */
+	dvar->red		= fbi->rgb[rgbidx]->red;
+	dvar->green		= fbi->rgb[rgbidx]->green;
+	dvar->blue		= fbi->rgb[rgbidx]->blue;
+	dvar->transp		= fbi->rgb[rgbidx]->transp;
+
+	DPRINTK("RGBT length = %d:%d:%d:%d\n",
+		dvar->red.length, dvar->green.length, dvar->blue.length,
+		dvar->transp.length);
+
+	DPRINTK("RGBT offset = %d:%d:%d:%d\n",
+		dvar->red.offset, dvar->green.offset, dvar->blue.offset,
+		dvar->transp.offset);
+
+	/*
+	 * Update the old var.  The fbcon drivers still use this.
+	 * Once they are using fbi->fb.var, this can be dropped.
+	 */
+	display->var = *dvar;
+
+	/*
+	 * If we are setting all the virtual consoles, also set the
+	 * defaults used to create new consoles.
+	 */
+	if (var->activate & FB_ACTIVATE_ALL)
+		fbi->fb.disp->var = *dvar;
+
+	/*
+	 * If the console has changed and the console has defined
+	 * a changevar function, call that function.
+	 */
+	if (chgvar && info && fbi->fb.changevar)
+		fbi->fb.changevar(con);
+
+	/* If the current console is selected, activate the new var. */
+	if (con != fbi->currcon)
+		return 0;
+
+	pl110fb_hw_set_var(dvar, fbi);
+
+	return 0;
+}
+
+static int
+__do_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+	      struct fb_info *info)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	struct fb_cmap *dcmap = get_con_cmap(info, con);
+	int err = 0;
+
+	if (con == -1)
+		con = fbi->currcon;
+
+	/* no colormap allocated? (we always have "this" colour map allocated) */
+	if (con >= 0)
+		err = fb_alloc_cmap(&fb_display[con].cmap, fbi->palette_size, 0);
+
+	if (!err && con == fbi->currcon)
+		err = fb_set_cmap(cmap, kspc, pl110fb_setcolreg, info);
+
+	if (!err)
+		fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
+
+	return err;
+}
+
+static int
+pl110fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+		  struct fb_info *info)
+{
+	struct display *disp = get_con_display(info, con);
+
+	if (disp->visual == FB_VISUAL_TRUECOLOR ||
+	    disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
+		return -EINVAL;
+
+	return __do_set_cmap(cmap, kspc, con, info);
+}
+
+static int
+pl110fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+	struct display *display = get_con_display(info, con);
+
+	*fix = info->fix;
+
+	fix->line_length = display->line_length;
+	fix->visual	 = display->visual;
+	return 0;
+}
+
+static int
+pl110fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+	*var = *get_con_var(info, con);
+	return 0;
+}
+
+static int
+pl110fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+{
+	struct fb_cmap *dcmap = get_con_cmap(info, con);
+	fb_copy_cmap(dcmap, cmap, kspc ? 0 : 2);
+	return 0;
+}
+
+static struct fb_ops pl110fb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	pl110fb_get_fix,
+	fb_get_var:	pl110fb_get_var,
+	fb_set_var:	pl110fb_set_var,
+	fb_get_cmap:	pl110fb_get_cmap,
+	fb_set_cmap:	pl110fb_set_cmap,
+};
+
+/*
+ *  pl110fb_switch():       
+ *	Change to the specified console.  Palette and video mode
+ *      are changed to the console's stored parameters.
+ *
+ *	Uh oh, this can be called from a tasklet (IRQ)
+ */
+static int
+pl110fb_switch(int con, struct fb_info *info)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	struct display *disp;
+	struct fb_cmap *cmap;
+
+	DPRINTK("con=%d info->modename=%s\n", con, fbi->fb.modename);
+
+	if (con == fbi->currcon)
+		return 0;
+
+	if (fbi->currcon >= 0) {
+		disp = fb_display + fbi->currcon;
+
+		/*
+		 * Save the old colormap and video mode.
+		 */
+		disp->var = fbi->fb.var;
+
+		if (disp->cmap.len)
+			fb_copy_cmap(&fbi->fb.cmap, &disp->cmap, 0);
+	}
+
+	fbi->currcon = con;
+	disp = fb_display + con;
+
+	/*
+	 * Make sure that our colourmap contains 256 entries.
+	 */
+	fb_alloc_cmap(&fbi->fb.cmap, 256, 0);
+
+	if (disp->cmap.len)
+		cmap = &disp->cmap;
+	else
+		cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
+
+	fb_copy_cmap(cmap, &fbi->fb.cmap, 0);
+
+	fbi->fb.var = disp->var;
+	fbi->fb.var.activate = FB_ACTIVATE_NOW;
+
+	pl110fb_set_var(&fbi->fb.var, con, info);
+	return 0;
+}
+
+/*
+ * Formal definition of the VESA spec:
+ *  On
+ *  	This refers to the state of the display when it is in full operation
+ *  Stand-By
+ *  	This defines an optional operating state of minimal power reduction with
+ *  	the shortest recovery time
+ *  Suspend
+ *  	This refers to a level of power management in which substantial power
+ *  	reduction is achieved by the display.  The display can have a longer 
+ *  	recovery time from this state than from the Stand-by state
+ *  Off
+ *  	This indicates that the display is consuming the lowest level of power
+ *  	and is non-operational. Recovery from this state may optionally require
+ *  	the user to manually power on the monitor
+ *
+ *  Now, the fbdev driver adds an additional state, (blank), where they
+ *  turn off the video (maybe by colormap tricks), but don't mess with the
+ *  video itself: think of it semantically between on and Stand-By.
+ *
+ *  So here's what we should do in our fbdev blank routine:
+ *
+ *  	VESA_NO_BLANKING (mode 0)	Video on,  front/back light on
+ *  	VESA_VSYNC_SUSPEND (mode 1)  	Video on,  front/back light off
+ *  	VESA_HSYNC_SUSPEND (mode 2)  	Video on,  front/back light off
+ *  	VESA_POWERDOWN (mode 3)		Video off, front/back light off
+ *
+ *  This will match the matrox implementation.
+ */
+/*
+ * pl110fb_blank():
+ *	Blank the display by setting all palette values to zero.  Note, the 
+ * 	12 and 16 bpp modes don't really use the palette, so this will not
+ *      blank the display in all modes.  
+ */
+static void
+pl110fb_blank(int blank, struct fb_info *info)
+{
+	struct pl110fb_info *fbi = (struct pl110fb_info *)info;
+	int i;
+
+	DPRINTK("pl110fb_blank: blank=%d info->modename=%s\n", blank,
+		fbi->fb.modename);
+
+	switch (blank) {
+	case VESA_POWERDOWN:
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+		if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR ||
+		    fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
+			for (i = 0; i < fbi->palette_size; i++)
+				pl110fb_setpalettereg(i, 0, 0, 0, 0, info);
+		pl110fb_schedule_task(fbi, C_DISABLE);
+		if (pl110fb_blank_helper)
+			pl110fb_blank_helper(blank);
+		break;
+
+	case VESA_NO_BLANKING:
+		if (pl110fb_blank_helper)
+			pl110fb_blank_helper(blank);
+		if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR ||
+		    fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
+			fb_set_cmap(&fbi->fb.cmap, 1, pl110fb_setcolreg, info);
+		pl110fb_schedule_task(fbi, C_ENABLE);
+	}
+}
+
+static int
+pl110fb_updatevar(int con, struct fb_info *info)
+{
+	DPRINTK("entered\n");
+	return 0;
+}
+
+/*
+ * Calculate the PCD value from the clock rate (in picoseconds).
+ * We take account of the PPCR clock setting.
+ */
+static inline int
+get_pcd(unsigned int pixclock)
+{
+	unsigned int pcd;
+
+	if (pixclock) {
+		pcd = hclkfreq_get() / 100000;
+		pcd *= pixclock;
+		pcd /= 10000000;
+		pcd += 1;	/* make up for integer math truncations */
+	} else {
+		/*
+		 * People seem to be missing this message.  Make it big.
+		 * Make it stand out.  Make sure people see it.
+		 */
+		printk(KERN_WARNING "******************************************************\n");
+		printk(KERN_WARNING "**            ZERO PIXEL CLOCK DETECTED             **\n");
+		printk(KERN_WARNING "** You are using a zero pixclock.  This means that  **\n");
+		printk(KERN_WARNING "** clock scaling will not be able to adjust your    **\n");
+		printk(KERN_WARNING "** your timing parameters appropriately, and the    **\n");
+		printk(KERN_WARNING "** bandwidth calculations will fail to work.  This  **\n");
+		printk(KERN_WARNING "** will shortly become an error condition, which    **\n");
+		printk(KERN_WARNING "** will prevent your LCD display working.  Please   **\n");
+		printk(KERN_WARNING "** send your patches in as soon as possible to shut **\n");
+		printk(KERN_WARNING "** this message up.                                 **\n");
+		printk(KERN_WARNING "******************************************************\n");
+		pcd = 0;
+	}
+
+	DPRINTK( "pcd=%d\n", pcd);
+
+	return pcd;
+}
+
+/*
+ * pl110fb_activate_var():
+ *	Configures LCD Controller based on entries in var parameter.  Settings are      
+ *	only written to the controller if changes were made.  
+ */
+static int
+pl110fb_activate_var(struct fb_var_screeninfo *var, struct pl110fb_info *fbi)
+{
+	struct pl110fb_lcd_reg new_regs;
+	u_int half_screen_size, yres, pcd = get_pcd( var->pixclock);
+	u_long flags;
+	lcdRegs_t    *LCD = (lcdRegs_t *)IO_ADDRESS(LCD_PHYS);
+	lcdicpRegs_t *LCDICP = (lcdicpRegs_t *)IO_ADDRESS(LCDICP_PHYS);
+
+	DPRINTK("Configuring pl110 LCD\n");
+	DPRINTK( "LCD=%p   LCDICP=%p\n", LCD, LCDICP);
+
+	DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n",
+		var->xres, var->hsync_len,
+		var->left_margin, var->right_margin);
+	DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n",
+		var->yres, var->vsync_len,
+		var->upper_margin, var->lower_margin);
+
+#if DEBUG_VAR
+	if (var->xres < 16        || var->xres > 1024)
+		printk(KERN_ERR "%s: invalid xres %d\n",
+			fbi->fb.fix.id, var->xres);
+	if (var->hsync_len < 1    || var->hsync_len > 64)
+		printk(KERN_ERR "%s: invalid hsync_len %d\n",
+			fbi->fb.fix.id, var->hsync_len);
+	if (var->left_margin < 1  || var->left_margin > 255)
+		printk(KERN_ERR "%s: invalid left_margin %d\n",
+			fbi->fb.fix.id, var->left_margin);
+	if (var->right_margin < 1 || var->right_margin > 255)
+		printk(KERN_ERR "%s: invalid right_margin %d\n",
+			fbi->fb.fix.id, var->right_margin);
+	if (var->yres < 1         || var->yres > 1024)
+		printk(KERN_ERR "%s: invalid yres %d\n",
+			fbi->fb.fix.id, var->yres);
+	if (var->vsync_len < 1    || var->vsync_len > 64)
+		printk(KERN_ERR "%s: invalid vsync_len %d\n",
+			fbi->fb.fix.id, var->vsync_len);
+	if (var->upper_margin < 0 || var->upper_margin > 255)
+		printk(KERN_ERR "%s: invalid upper_margin %d\n",
+			fbi->fb.fix.id, var->upper_margin);
+	if (var->lower_margin < 0 || var->lower_margin > 255)
+		printk(KERN_ERR "%s: invalid lower_margin %d\n",
+			fbi->fb.fix.id, var->lower_margin);
+#endif
+	if( var->bits_per_pixel == 8) {
+	    new_regs.LCDcontrol = LCD_CTRL_BPP8;
+	 } else if( var->bits_per_pixel == 16) {
+	    new_regs.LCDcontrol = LCD_CTRL_BPP16 | LCD_CTRL_BGR;
+	}
+
+	new_regs.LCDcontrol |= fbi->LCDcontrol | LCD_CTRL_ENABLE;
+	    
+	new_regs.LCDtiming0 =
+	    LCD_TIMING0_HFP(var->right_margin) +
+	    LCD_TIMING0_HBP(var->left_margin) +
+	    LCD_TIMING0_HSW(var->hsync_len) +
+	    LCD_TIMING0_PPL(var->xres);
+
+	/*
+	 * If we have a dual scan LCD, then we need to halve
+	 * the YRES parameter.
+	 */
+	yres = var->yres;
+	if( fbi->LCDcontrol & LCD_CTRL_DUAL)
+		yres /= 2;
+
+	new_regs.LCDtiming1 =
+		LCD_TIMING1_VBP(var->upper_margin) +
+		LCD_TIMING1_VFP(var->lower_margin) +
+		LCD_TIMING1_VSW(var->vsync_len) +
+		LCD_TIMING1_LPP(yres);
+
+	new_regs.LCDtiming2 = fbi->LCDtiming2 | 
+	    	LCD_TIMING2_CPL (480) | //(var->xres) |
+		LCD_TIMING2_PCD(pcd) |
+		(var->sync & FB_SYNC_HOR_HIGH_ACT  ? 0 : LCD_TIMING2_IHS) |
+		(var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : LCD_TIMING2_IVS);
+
+	new_regs.LCDtiming3    = fbi->LCDtiming3;
+	new_regs.LCDICPsetup   = fbi->LCDICPsetup | LCDICP_SETUP_PPL(var->xres);
+#if defined(CONFIG_ARCH_LH7A400)
+	new_regs.LCDICPsetup   |= LCDICP_SETUP_POWER;
+#endif
+
+	new_regs.LCDICPcontrol = fbi->LCDICPcontrol;
+	new_regs.LCDICPtiming1 = fbi->LCDICPtiming1;
+	new_regs.LCDICPtiming2 = fbi->LCDICPtiming2;
+
+	DPRINTK("new LCDtiming0    = 0x%08x\n", (u32)new_regs.LCDtiming0);
+	DPRINTK("new LCDtiming1    = 0x%08x\n", (u32)new_regs.LCDtiming1);
+	DPRINTK("new LCDtiming2    = 0x%08x\n", (u32)new_regs.LCDtiming2);
+	DPRINTK("new LCDtiming3    = 0x%08x\n", (u32)new_regs.LCDtiming3);
+	DPRINTK("new LCDcontrol    = 0x%08x\n", (u32)new_regs.LCDcontrol);
+	DPRINTK("new LCDICPsetup   = 0x%08x\n", (u32)new_regs.LCDICPsetup);
+	DPRINTK("new LCDICPcontrol = 0x%08x\n", (u32)new_regs.LCDICPcontrol);
+	DPRINTK("new LCDICPtiming1 = 0x%08x\n", (u32)new_regs.LCDICPtiming1);
+	DPRINTK("new LCDICPtiming2 = 0x%08x\n", (u32)new_regs.LCDICPtiming2);
+
+
+	/* Update shadow copy atomically */
+	local_irq_save(flags);
+	fbi->upbase = fbi->screen_dma;
+
+	fbi->reg_LCDtiming0    = new_regs.LCDtiming0;
+	fbi->reg_LCDtiming1    = new_regs.LCDtiming1;
+	fbi->reg_LCDtiming2    = new_regs.LCDtiming2;
+	fbi->reg_LCDtiming3    = new_regs.LCDtiming3;
+	fbi->reg_LCDcontrol    = new_regs.LCDcontrol;
+	fbi->reg_LCDICPsetup   = new_regs.LCDICPsetup;
+	fbi->reg_LCDICPcontrol = new_regs.LCDICPcontrol;
+	fbi->reg_LCDICPtiming1 = new_regs.LCDICPtiming1;
+	fbi->reg_LCDICPtiming2 = new_regs.LCDICPtiming2;
+	local_irq_restore(flags);
+
+	/*
+	 * Only update the registers if the controller is enabled
+	 * and something has changed.
+	 */
+	if ((LCD->timing0 != fbi->reg_LCDtiming0)       || (LCD->timing1 != fbi->reg_LCDtiming1) ||
+	    (LCD->timing2 != fbi->reg_LCDtiming2)       || (LCD->timing3 != fbi->reg_LCDtiming2) ||
+	    (LCD->control != fbi->reg_LCDcontrol)       || (LCDICP->setup != fbi->reg_LCDICPsetup) ||
+	    (LCDICP->timing1 != fbi->reg_LCDICPtiming1) || (LCDICP->timing2 != fbi->reg_LCDICPtiming2) ||
+	    (LCD->upbase != fbi->upbase)                || (LCD->lpbase != fbi->lpbase))
+		pl110fb_schedule_task(fbi, C_REENABLE);
+
+	return 0;
+}
+
+/*
+ * NOTE!  The following functions are purely helpers for set_ctrlr_state.
+ * Do not call them directly; set_ctrlr_state does the correct serialisation
+ * to ensure that things happen in the right way 100% of time time.
+ *	-- rmk
+ */
+
+static void
+pl110fb_backlight_on(struct pl110fb_info *fbi)
+{
+    DPRINTK("backlight on\n");
+
+#ifdef CONFIG_ARCH_LH79520
+    if( machine_is_lh79520evb()) {
+	//cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+	GPOUT16 |= BACKLIGHT;
+		
+	//cpld->lcd_pwr_cntl |= CPLD_BACKLIGHT_ON;
+    }
+#endif
+
+#ifdef CONFIG_ARCH_LH7A400
+    if( machine_is_lh7a400evb()) {
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+	cpld->lcd_pwr_cntl |= CPLD_BACKLIGHT_ON;
+    }
+#endif
+}
+
+static void
+pl110fb_backlight_off(struct pl110fb_info *fbi)
+{
+    DPRINTK("backlight off\n");
+
+#ifdef CONFIG_ARCH_LH79520
+    if( machine_is_lh79520evb()) {
+	//cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+	GPOUT16 &= ~BACKLIGHT;
+	//cpld->lcd_pwr_cntl &= ~CPLD_BACKLIGHT_ON;
+    }
+#endif
+#ifdef CONFIG_ARCH_LH7A400
+    if( machine_is_lh7a400evb()) {
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+	cpld->lcd_pwr_cntl &= ~CPLD_BACKLIGHT_ON;
+    }
+#endif
+}
+
+static void
+pl110fb_power_up_lcd(struct pl110fb_info *fbi)
+{
+	DPRINTK("LCD power on\n");
+
+#ifdef CONFIG_ARCH_LH79520
+	if( machine_is_lh79520evb()) {
+	    cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+	    cpld->lcd_pwr_cntl |= CPLD_LCDP_EN;
+	}
+#endif
+#ifdef CONFIG_ARCH_LH7A400
+	if( machine_is_lh7a400evb()) {
+	    cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+	    cpld->lcd_pwr_cntl |= CPLD_LCDP_EN;
+	}
+#endif
+}
+
+static void
+pl110fb_power_down_lcd(struct pl110fb_info *fbi)
+{
+	DPRINTK("LCD power off\n");
+#ifdef CONFIG_ARCH_LH79520
+	if( machine_is_lh79520evb()) {
+	    cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+	    cpld->lcd_pwr_cntl &= ~CPLD_LCDP_EN;
+	}
+#endif
+#ifdef CONFIG_ARCH_LH7A400
+	if( machine_is_lh7a400evb()) {
+	    cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+
+	    cpld->lcd_pwr_cntl &= ~CPLD_LCDP_EN;
+	}
+#endif
+}
+
+
+static void
+pl110fb_setup_hw(struct pl110fb_info *fbi)
+{
+#ifdef CONFIG_ARCH_LH79520
+    rcpcRegs_t  *rcpc  = (rcpcRegs_t *)IO_ADDRESS( RCPC_PHYS);
+    ioconRegs_t *iocon = (ioconRegs_t *)IO_ADDRESS( IOCON_PHYS);
+
+    rcpc->control       |= RCPC_CTRL_WRTLOCK_ENABLED;		/* unlock RCPC registers */
+    barrier();
+
+    /*
+     * use HCLK for the LCD clock.
+     */
+    rcpc->spareClkCtrl   &= ~RCPC_SPARE_CLKCTRL_LCDCLK_DISABLE; /* enable LCDCLK	*/
+    rcpc->spareClkSel    &= ~RCPC_SCLKSEL_LCDCLK;		/* LCDCLK from HCLK	*/
+    rcpc->spare0Prescale &= 0;
+    rcpc->AHBClkCtrl     &= ~RCPC_CLKCTRL_DMAC_DISABLE;		/* ensure DMA gets a clock */
+    rcpc->control        &= ~RCPC_CTRL_WRTLOCK_ENABLED;		/* lock RCPC registers	*/
+    
+    /* set the pin mux to enable all required LCD signals and disable the rest */
+
+    iocon->LCDMux = 
+		       LCDMUX_CLVDDEN		     
+//		     | LCDMUX_CLXCLK
+//        	     | LCDMUX_CLSPL		/* SPL */
+//		     | LCDMUX_CLS		/* CLS */
+		     | LCDMUX_PIOC2		/* don't need external LCD clock */
+		     | LCDMUX_CLCP		/* DCLK */
+		     | LCDMUX_CLLP		/* LP */
+		     | LCDMUX_CLD17
+		     | LCDMUX_CLD16		     
+		     | LCDMUX_CLD15
+		     | LCDMUX_CLD14
+		     | LCDMUX_CLD13
+		     | LCDMUX_CLD12
+		     | LCDMUX_CLFP
+		     | LCDMUX_CLD11
+		     | LCDMUX_CLD10
+		     | LCDMUX_CLD8	
+		     | LCDMUX_CLD9
+		     | LCDMUX_CLD2		/* red[1] */
+		     | LCDMUX_CLD3		/* red[2] */
+		     | LCDMUX_CLD4		/* red[3] */
+		     | LCDMUX_CLD5		/* red[4] */
+		     | LCDMUX_CLD7		/* green[0] */
+		     | LCDMUX_CLD6;		/* green[1] */
+
+//    iocon->LCDMux = LCDMUX_CLREV 
+//		     | LCDMUX_CLXCLK
+//		     | LCDMUX_CLD13		/* blue[0] */ 
+//		     | LCDMUX_CLD14		/* blue[1] */
+//		     | LCDMUX_CLD15		/* blue[2] */
+//		     | LCDMUX_CLD16		/* blue[3] */
+//		     | LCDMUX_CLD17		/* blue[4] */
+//		     | LCDMUX_CLSPL		/* SPL */
+//		     | LCDMUX_CLS		/* CLS */
+//		     | LCDMUX_PIOC2		/* don't need external LCD clock */
+//		     | LCDMUX_CLCP		/* DCLK */
+//		     | LCDMUX_CLP		/* LP */
+//		     | LCDMUX_CLSPS		/* SPS */
+//		     | LCDMUX_CLD2		/* red[1] */
+//		     | LCDMUX_CLD3		/* red[2] */
+//		     | LCDMUX_CLD4		/* red[3] */
+//		     | LCDMUX_CLD5		/* red[4] */
+//		     | LCDMUX_CPS		/* PS */
+//		     | LCDMUX_CLD7		/* green[0] */
+//		     | LCDMUX_CLD8		/* green[1] */
+//		     | LCDMUX_CLD9		/* green[2] */
+//		     | LCDMUX_CLD10		/* green[3] */
+//		     | LCDMUX_CLD11;		/* green[4] */
+
+    DPRINTK( "IOCON->LCDMux=%x\n", iocon->LCDMux);
+#endif
+#ifdef CONFIG_ARCH_LH7A400
+    gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS);
+
+    gpio->pinmux |= (GPIO_PINMUX_PEOCON | GPIO_PINMUX_PDOCON);	/* route LCD data bits	*/
+
+    DPRINTK( "gpio: pinmux=%x  pdddr=0x%x  peddr=0x%x\n",
+	    gpio->pinmux, gpio->pdddr, gpio->peddr);	// DDD
+#endif
+}
+
+static void
+pl110fb_enable_controller(struct pl110fb_info *fbi)
+{
+	lcdRegs_t *LCD = (lcdRegs_t *)IO_ADDRESS(LCD_PHYS);
+	lcdicpRegs_t *LCDICP = (lcdicpRegs_t *)IO_ADDRESS(LCDICP_PHYS);
+
+#if defined(CONFIG_ARCH_LH79520) || defined(CONFIG_ARCH_LH7A400)
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+#endif
+	DPRINTK("Enabling LCD controller\n");
+
+	LCDICP->control = fbi->reg_LCDICPcontrol;
+	LCDICP->setup   = fbi->reg_LCDICPsetup;
+	LCDICP->timing1 = fbi->reg_LCDICPtiming1;
+	LCDICP->timing2 = fbi->reg_LCDICPtiming2;
+	LCD->timing0    = fbi->reg_LCDtiming0;
+	LCD->timing1    = fbi->reg_LCDtiming1;
+	LCD->timing2    = fbi->reg_LCDtiming2;
+	LCD->timing3    = fbi->reg_LCDtiming3;
+	LCD->upbase     = fbi->upbase;
+#if defined(CONFIG_ARCH_LH7A400)
+	LCD->lpoverflow = fbi->upbase;
+#endif
+	LCD->intrEnable = 0;
+	LCD->control    = fbi->reg_LCDcontrol;
+
+	/* 
+	 * enable lcd output
+	 */
+#if defined(CONFIG_ARCH_LH79520) || defined(CONFIG_ARCH_LH7A400)
+	cpld->lcd_pwr_cntl |= CPLD_LCD_OE;
+#endif
+
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(20 * HZ / 1000);
+
+	LCD->control |= LCD_CTRL_PWR;
+
+
+#if defined(CONFIG_ARCH_LH7A400)
+	DPRINTK("real LCDoverflow   = %p\n",     (void *)LCD->lpoverflow);
+#endif
+	DPRINTK("real LCDupbase     = %p\n",     (void *)LCD->upbase);
+	DPRINTK("real LCDlpbase     = %p\n",     (void *)LCD->lpbase);
+	DPRINTK("real LCDtiming0    = 0x%08x\n", LCD->timing0);
+	DPRINTK("real LCDtiming1    = 0x%08x\n", LCD->timing1);
+	DPRINTK("real LCDtiming2    = 0x%08x\n", LCD->timing2);
+	DPRINTK("real LCDtiming3    = 0x%08x\n", LCD->timing3);
+	DPRINTK("real LCDcontrol    = 0x%08x\n", LCD->control);
+	DPRINTK("real LCDICPsetup   = 0x%08x\n", LCDICP->setup);
+	DPRINTK("real LCDICPcontrol = 0x%08x\n", LCDICP->control);
+	DPRINTK("real LCDICPtiming1 = 0x%08x\n", LCDICP->timing1);
+	DPRINTK("real LCDICPtiming2 = 0x%08x\n", LCDICP->timing2);
+}
+
+
+static void
+pl110fb_disable_controller(struct pl110fb_info *fbi)
+{
+	lcdRegs_t *LCD = (lcdRegs_t *)IO_ADDRESS(LCD_PHYS);
+	lcdicpRegs_t *LCDICP = (lcdicpRegs_t *)IO_ADDRESS(LCDICP_PHYS);
+
+#if defined(CONFIG_ARCH_LH79520) || defined(CONFIG_ARCH_LH7A400)
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+#endif
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	DPRINTK("Disabling LCD controller\n");
+
+	add_wait_queue(&fbi->ctrlr_wait, &wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+
+	LCD->intrEnable |= LCD_STATUS_VCOMP;	/* allow VCOMP interrupts */
+
+	/* turn off LCD power, wait a bit, then disable the controller */
+	LCD->control    &= ~LCD_CTRL_PWR;
+
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(20 * HZ / 1000);
+
+	LCD->control = 0;
+	LCDICP->control = 0;
+
+#if defined(CONFIG_ARCH_LH79520) || defined(CONFIG_ARCH_LH7A400)
+	cpld->lcd_pwr_cntl &= ~CPLD_LCD_OE;
+#endif
+
+	schedule_timeout(20 * HZ / 1000);
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&fbi->ctrlr_wait, &wait);
+}
+
+
+/*
+ *  pl110fb_handle_irq: Handle 'LCD DONE' interrupts.
+ */
+static void
+pl110fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct pl110fb_info *fbi = dev_id;
+	lcdRegs_t *LCD = (lcdRegs_t *)IO_ADDRESS(LCD_PHYS);
+
+	unsigned int intr = LCD->maskedIntrStatus;
+
+	DPRINTK("IRQ: status=0x%x\n", intr);
+
+	if( intr & LCD_STATUS_VCOMP) {		/* vertical compare interrupt	*/
+		LCD->intrEnable = 0;		/* only want one interrupt	*/
+		wake_up(&fbi->ctrlr_wait);
+	}
+
+	LCD->rawIntrStatus = 0;			/* clear interrupt		*/
+}
+
+/*
+ * This function must be called from task context only, since it will
+ * sleep when disabling the LCD controller, or if we get two contending
+ * processes trying to alter state.
+ */
+static void
+set_ctrlr_state(struct pl110fb_info *fbi, u_int state)
+{
+	u_int old_state;
+
+	down(&fbi->ctrlr_sem);
+
+	old_state = fbi->state;
+
+	switch (state) {
+	case C_DISABLE_CLKCHANGE:
+		/*
+		 * Disable controller for clock change.  If the
+		 * controller is already disabled, then do nothing.
+		 */
+		if (old_state != C_DISABLE && old_state != C_DISABLE_PM) {
+			fbi->state = state;
+			pl110fb_disable_controller(fbi);
+		}
+		break;
+
+	case C_DISABLE_PM:
+	case C_DISABLE:
+		/*
+		 * Disable controller
+		 */
+		if (old_state != C_DISABLE) {
+			fbi->state = state;
+
+			pl110fb_backlight_off(fbi);
+			if (old_state != C_DISABLE_CLKCHANGE)
+				pl110fb_disable_controller(fbi);
+			pl110fb_power_down_lcd(fbi);
+		}
+		break;
+
+	case C_ENABLE_CLKCHANGE:
+		/*
+		 * Enable the controller after clock change.  Only
+		 * do this if we were disabled for the clock change.
+		 */
+		if (old_state == C_DISABLE_CLKCHANGE) {
+			fbi->state = C_ENABLE;
+			pl110fb_enable_controller(fbi);
+		}
+		break;
+
+	case C_REENABLE:
+		/*
+		 * Re-enable the controller only if it was already
+		 * enabled.  This is so we reprogram the control
+		 * registers.
+		 */
+		if (old_state == C_ENABLE) {
+			pl110fb_disable_controller(fbi);
+			pl110fb_setup_hw(fbi);
+			pl110fb_enable_controller(fbi);
+		}
+		break;
+
+	case C_ENABLE_PM:
+		/*
+		 * Re-enable the controller after PM.  This is not
+		 * perfect - think about the case where we were doing
+		 * a clock change, and we suspended half-way through.
+		 */
+		if (old_state != C_DISABLE_PM)
+			break;
+		/* fall through */
+
+	case C_ENABLE:
+		/*
+		 * Power up the LCD screen, enable controller, and
+		 * turn on the backlight.
+		 */
+		if (old_state != C_ENABLE) {
+			fbi->state = C_ENABLE;
+			pl110fb_setup_hw(fbi);
+			pl110fb_power_up_lcd(fbi);
+			pl110fb_enable_controller(fbi);
+			pl110fb_backlight_on(fbi);
+		}
+		break;
+	}
+	up(&fbi->ctrlr_sem);
+}
+
+
+/*
+ * Our LCD controller task (which is called when we blank or unblank)
+ * via keventd.
+ */
+static void
+pl110fb_task(void *dummy)
+{
+	struct pl110fb_info *fbi = dummy;
+	u_int state = xchg(&fbi->task_state, -1);
+
+	set_ctrlr_state(fbi, state);
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Calculate the minimum DMA period over all displays that we own.
+ * This, together with the SDRAM bandwidth defines the slowest CPU
+ * frequency that can be selected.
+ */
+static unsigned int
+pl110fb_min_dma_period(struct pl110fb_info *fbi)
+{
+	unsigned int min_period = (unsigned int)-1;
+	int i;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		unsigned int period;
+
+		/*
+		 * Do we own this display?
+		 */
+		if (fb_display[i].fb_info != &fbi->fb)
+			continue;
+
+		/*
+		 * Ok, calculate its DMA period
+		 */
+		period = pl110fb_display_dma_period(get_con_var(&fbi->fb, i));
+		if (period < min_period)
+			min_period = period;
+	}
+
+	return min_period;
+}
+
+/*
+ * CPU clock speed change handler.  We need to adjust the LCD timing
+ * parameters when the CPU clock is adjusted by the power management
+ * subsystem.
+ */
+static int
+pl110fb_clkchg_notifier(struct notifier_block *nb, unsigned long val,
+			 void *data)
+{
+	struct pl110fb_info *fbi = TO_INF(nb, clockchg);
+	struct cpufreq_minmax *mm = data;
+	u_int pcd;
+
+	switch (val) {
+	case CPUFREQ_MINMAX:
+		printk(KERN_DEBUG "min dma period: %d ps, old clock %d kHz, "
+			"new clock %d kHz\n", pl110fb_min_dma_period(fbi),
+			mm->cur_freq, mm->new_freq);
+		/* todo: fill in min/max values */
+		break;
+
+	case CPUFREQ_PRECHANGE:
+		set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
+		break;
+
+	case CPUFREQ_POSTCHANGE:
+		pcd = get_pcd(fbi->fb.var.pixclock);
+		fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);	// DDD
+		set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
+		break;
+	}
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+/*
+ * Power management hook.  Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+static int
+pl110fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
+{
+	struct pl110fb_info *fbi = pm_dev->data;
+
+	DPRINTK("pm_callback: %d\n", req);
+
+	if (req == PM_SUSPEND || req == PM_RESUME) {
+		int state = (int)data;
+
+		if (state == 0) {
+			/* Enter D0. */
+			set_ctrlr_state(fbi, C_ENABLE_PM);
+		} else {
+			/* Enter D1-D3.  Disable the LCD controller.  */
+			set_ctrlr_state(fbi, C_DISABLE_PM);
+		}
+	}
+	DPRINTK("done\n");
+	return 0;
+}
+#endif
+
+/*
+ * pl110fb_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
+pl110fb_map_video_memory(struct pl110fb_info *fbi)
+{
+	/*
+	 * We reserve one page for the palette, plus the size
+	 * of the framebuffer.
+	 */
+	fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len);
+	fbi->map_cpu = consistent_alloc(GFP_KERNEL, fbi->map_size,
+					&fbi->map_dma);
+
+	if (fbi->map_cpu) {
+		fbi->screen_cpu = fbi->map_cpu;
+		fbi->screen_dma = fbi->map_dma;
+		fbi->fb.fix.smem_start = fbi->screen_dma;
+	}
+
+	DPRINTK( "fix.smem_len = %d  map_cpu = 0x%x    screen_cpu = 0x%x     screen_dma = 0x%x\n",
+		fbi->fb.fix.smem_len, fbi->map_cpu, fbi->screen_cpu, fbi->screen_dma);
+
+	return fbi->map_cpu ? 0 : -ENOMEM;
+}
+
+/* Fake monspecs to fill in fbinfo structure */
+static struct fb_monspecs monspecs __initdata = {
+	30000, 70000, 50, 65, 0	/* Generic */
+};
+
+
+static struct pl110fb_info * __init
+pl110fb_init_fbinfo(void)
+{
+	struct pl110fb_mach_info *inf;
+	struct pl110fb_info *fbi;
+	int pixelsPerSecond;
+
+	fbi = kmalloc(sizeof(struct pl110fb_info) + sizeof(struct display) +
+		      sizeof(u16) * 16, GFP_KERNEL);
+	if (!fbi)
+		return NULL;
+
+	memset(fbi, 0, sizeof(struct pl110fb_info) + sizeof(struct display));
+
+	fbi->currcon		= -1;
+
+	strcpy(fbi->fb.fix.id, PL110_NAME);
+
+	fbi->fb.fix.type	= FB_TYPE_PACKED_PIXELS;
+	fbi->fb.fix.type_aux	= 0;
+	fbi->fb.fix.xpanstep	= 0;
+	fbi->fb.fix.ypanstep	= 0;
+	fbi->fb.fix.ywrapstep	= 0;
+	fbi->fb.fix.accel	= FB_ACCEL_NONE;
+
+	fbi->fb.var.nonstd	= 0;
+	fbi->fb.var.activate	= FB_ACTIVATE_NOW;
+	fbi->fb.var.height	= -1;
+	fbi->fb.var.width	= -1;
+	fbi->fb.var.accel_flags	= 0;
+	fbi->fb.var.vmode	= FB_VMODE_NONINTERLACED;
+
+	strcpy(fbi->fb.modename, PL110_NAME);
+	strcpy(fbi->fb.fontname, "Acorn8x8");
+
+	fbi->fb.fbops		= &pl110fb_ops;
+	fbi->fb.changevar	= NULL;
+	fbi->fb.switch_con	= pl110fb_switch;
+	fbi->fb.updatevar	= pl110fb_updatevar;
+	fbi->fb.blank		= pl110fb_blank;
+	fbi->fb.flags		= FBINFO_FLAG_DEFAULT;
+	fbi->fb.node		= -1;
+	fbi->fb.monspecs	= monspecs;
+	fbi->fb.disp		= (struct display *)(fbi + 1);
+	fbi->fb.pseudo_palette	= (void *)(fbi->fb.disp + 1);
+
+	fbi->rgb[RGB_8]		= &rgb_8;
+	fbi->rgb[RGB_16]	= &def_rgb_16;
+
+	inf = pl110fb_get_machine_info(fbi);
+
+	/*
+	 * Calculate pixclock.  pixclock is the time in picoseconds spent
+	 * drawing a pixel.  The time (in seconds) to draw a pixel is
+	 * the inverse of how many pixels we draw in a second (pixelsPerSecond).
+	 *
+	 * pixelsPerSecond is xres*yres*refresh, plus all the overhead time
+	 * (horizontal and vertical front and back porches, plus horizontal
+	 * and vertical sync lengths).
+	 *
+	 * 
+	 */
+	pixelsPerSecond =
+	    (inf->xres + inf->hsync_len + inf->left_margin  + inf->right_margin) *
+	    (inf->yres + inf->vsync_len + inf->upper_margin + inf->lower_margin) *
+	    VERTICAL_REFRESH;
+
+	inf->pixclock = 1000000000 / (pixelsPerSecond / 1000);
+
+	DPRINTK( "pixelsPerSecond=%d    pixclock=%d\n", pixelsPerSecond,  inf->pixclock);
+
+
+	fbi->max_xres			= inf->xres;
+	fbi->fb.var.xres		= inf->xres;
+	fbi->fb.var.xres_virtual	= inf->xres;
+	fbi->max_yres			= inf->yres;
+	fbi->fb.var.yres		= inf->yres;
+	fbi->fb.var.yres_virtual	= inf->yres;
+	fbi->max_bpp			= inf->bpp;
+	fbi->fb.var.bits_per_pixel	= inf->bpp;
+	fbi->fb.var.pixclock		= inf->pixclock;
+	fbi->fb.var.hsync_len		= inf->hsync_len;
+	fbi->fb.var.left_margin		= inf->left_margin;
+	fbi->fb.var.right_margin	= inf->right_margin;
+	fbi->fb.var.vsync_len		= inf->vsync_len;
+	fbi->fb.var.upper_margin	= inf->upper_margin;
+	fbi->fb.var.lower_margin	= inf->lower_margin;
+	fbi->fb.var.sync		= inf->sync;
+	fbi->fb.var.grayscale		= inf->cmap_greyscale;
+	fbi->cmap_inverse		= inf->cmap_inverse;
+	fbi->cmap_static		= inf->cmap_static;
+	fbi->LCDtiming2			= inf->LCDtiming2;
+	fbi->LCDtiming3			= inf->LCDtiming3;
+	fbi->LCDcontrol			= inf->LCDcontrol;
+	fbi->LCDICPsetup		= inf->LCDICPsetup;
+	fbi->LCDICPcontrol		= inf->LCDICPcontrol;
+	fbi->LCDICPtiming1		= inf->LCDICPtiming1;
+	fbi->LCDICPtiming2		= inf->LCDICPtiming2;
+	fbi->state			= C_DISABLE;
+	fbi->task_state			= (u_char)-1;
+	fbi->fb.fix.smem_len		= fbi->max_xres * fbi->max_yres *
+					  fbi->max_bpp / 8;
+
+	init_waitqueue_head(&fbi->ctrlr_wait);
+	INIT_TQUEUE(&fbi->task, pl110fb_task, fbi);
+	init_MUTEX(&fbi->ctrlr_sem);
+
+	return fbi;
+}
+
+int __init
+pl110fb_init(void)
+{
+	struct pl110fb_info *fbi;
+	int ret;
+
+	DPRINTK( "\n\npl110fb_init\n");
+
+	DPRINTK( "cpu clock = %d     HCLK = %d\n", cpufreq_get(0), hclkfreq_get());
+
+	fbi = pl110fb_init_fbinfo();
+	ret = -ENOMEM;
+	if (!fbi)
+	    goto failed;
+
+	/* Initialize video memory */
+	ret = pl110fb_map_video_memory(fbi);
+	if (ret)
+	    goto failed;
+
+	ret = request_irq(IRQ_LCD, pl110fb_handle_irq, SA_INTERRUPT,
+			  fbi->fb.fix.id, fbi);
+	if (ret) {
+	    printk(KERN_ERR "pl110fb: request_irq failed: ret=%d\n", ret);
+	    goto failed;
+	}
+
+	pl110fb_set_var(&fbi->fb.var, -1, &fbi->fb);
+
+	ret = register_framebuffer(&fbi->fb);
+	if (ret < 0)
+		goto failed;
+
+#ifdef CONFIG_PM
+	/*
+	 * Note that the console registers this as well, but we want to
+	 * power down the display prior to sleeping.
+	 */
+	fbi->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, pl110fb_pm_callback);
+	if (fbi->pm)
+		fbi->pm->data = fbi;
+#endif
+#ifdef CONFIG_CPU_FREQ
+	fbi->clockchg.notifier_call = pl110fb_clkchg_notifier;
+	cpufreq_register_notifier(&fbi->clockchg);
+#endif
+
+	/*
+	 * Ok, now enable the LCD controller
+	 */
+	set_ctrlr_state(fbi, C_ENABLE);
+
+	/* This driver cannot be unloaded at the moment */
+	MOD_INC_USE_COUNT;
+
+	return 0;
+
+failed:
+	if (fbi)
+		kfree(fbi);
+	return ret;
+}
+
+int __init
+pl110fb_setup(char *options)
+{
+	return 0;
+}
+
+MODULE_DESCRIPTION("ARM PL110 framebuffer driver");
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.26/drivers/video/pl110fb.h linux-2.4.26-vrs1-lnode80/drivers/video/pl110fb.h
--- linux-2.4.26/drivers/video/pl110fb.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/drivers/video/pl110fb.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,350 @@
+/*
+ * linux/drivers/video/pl110fb.h
+ *    -- ARM PrimeCell PL110 LCD controller frame buffer device
+ *
+ * Copyright (C) 2002 Lineo, Inc.
+ *  
+ * Portions Copyright (C) 2001 Sharp Microelectronics of the Americas, Inc.
+ * 		       CAMAS, WA
+ *
+ * based in part on sa1100fb.h, which is Copyright (C) Eric A. Thomas
+ *
+ * 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.
+ */
+
+/*
+ * Color LCD Controller registers
+ */
+typedef struct {
+    volatile u32	timing0;		/* Horizontal axis panel control	*/
+    volatile u32	timing1;		/* Vertical axis panel control		*/
+    volatile u32	timing2;		/* clock and signal polarity control	*/
+    volatile u32	timing3;		/* line end control			*/
+    volatile dma_addr_t	upbase;			/* upper panel frame base address	*/
+    volatile dma_addr_t	lpbase;			/* lower panel frame base address	*/
+    volatile u32	intrEnable;		/* interrupt enable mask		*/
+    volatile u32	control;		/* LCD panel pixel parameters		*/
+    volatile u32	rawIntrStatus;		/* raw interrupt status			*/
+    volatile u32	maskedIntrStatus;	/* masked interrupt status		*/
+    volatile dma_addr_t	upcurr;			/* upper panel current address		*/
+    volatile dma_addr_t	lpcurr;			/* lower panel current address		*/
+    volatile dma_addr_t	lpoverflow;		/* SDRAM fb base			*/
+    volatile u32	reservedcc[115];	/* reserved				*/
+    volatile u32	palette[128];		/* 256 x 16-bit color palette		*/
+} lcdRegs_t;
+
+
+/*
+ * LCDTiming0 Register Bit Field constants
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than zero.
+ */ 
+#define LCD_TIMING0_HBP(n)	_SBF(24,((n)-1))		/* Horiz Back Porch */ 
+#define LCD_TIMING0_HFP(n)	_SBF(16,((n)-1))		/* Horiz Front Porch */ 
+#define LCD_TIMING0_HSW(n)	_SBF(8,((n)-1))			/* Horiz sync Pulse Width */ 
+#define LCD_TIMING0_PPL(n)	_SBF(2,((((n)/16)-1)&0x3F))	/* Pixels per line */ 
+
+/*
+ * LCDTiming1 Register Bit Field constants
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than zero.
+ */ 
+#define LCD_TIMING1_VBP(n)	_SBF(24,(n))		/* Vertical Back Porch */ 
+#define LCD_TIMING1_VFP(n)	_SBF(16,(n))		/* Vertical Front Porch */ 
+#define LCD_TIMING1_VSW(n)	_SBF(10,(n))		/* Vertical Synchronization Pulse */ 
+#define LCD_TIMING1_LPP(n)	_SBF(0,((n)-1))		/* Lines per Panel */ 
+
+/*
+ * LCDTiming2 Register Bit Field constants
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than two.
+ */ 
+#define LCD_TIMING2_BCD 	_BIT(26)		/* Bypass Pixel Clock Divider */
+#define LCD_TIMING2_CPL(n)	_SBF(16,((n)-1)&0x3FF)	/* Clocks Per Line */ 
+#define LCD_TIMING2_IOE		_BIT(14)		/* Invert Output Enable */ 
+#define LCD_TIMING2_IPC		_BIT(13)		/* Invert Panel Clock */ 
+#define LCD_TIMING2_IHS 	_BIT(12)		/* Invert Horizontal Synchronization */ 
+							/* set == HSYNC is active low	     */
+#define LCD_TIMING2_IVS		_BIT(11)		/* Invert Vertical Synchronization */ 
+							/* set == VSYNC is active low	     */
+#define LCD_TIMING2_ACB(n)	_SBF(6,((n)-1))		/* AC Bias Pin Frequency */ 
+#define LCD_TIMING2_CLKSEL	 _BIT(5)		/* Clock Selector */ 
+#define LCD_TIMING2_PCD(n)	_SBF(0,((n)-2))		/* Panel Clock Divisor */ 
+
+
+/*
+ * LCDTiming3 Register Bit Field constants
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than one.
+ */ 
+#define LCD_TIMING3_LEE		_BIT(16)		/* Line End Enable */ 
+#define LCD_TIMING3_LED(n)	_SBF(0,((n)-1))		/* Line End Signal Delay */ 
+
+
+/*
+ * intrEnable, rawIntrStatus, maskedIntrStatus bit field positions
+ */
+#define LCD_STATUS_MBERROR	_BIT(4)			/* Master Bus Error */ 
+#define LCD_STATUS_VCOMP 	_BIT(3)			/* Vertical Compare */ 
+#define LCD_STATUS_LNBU 	_BIT(2)			/* LCD Next addr. Base Update*/ 
+#define LCD_STATUS_FUF 		_BIT(1)			/* FIFO underflow */ 
+
+
+/*
+ * Control Register Bit Field constants
+ */ 
+#define LCD_CTRL_WATERMARK	_BIT(16)		/* LCD DMA FIFO Watermark Level */ 
+#define LCD_CTRL_LDMAFIFOTME	_BIT(15)		/* LCD DMA FIFO Test Mode Enable */ 
+
+#define LCD_CTRL_VCOMP(n)	_SBF(12,((n)&0x3))	/* Generate interrupt at:	*/
+#define LCD_CTRL_VCOMP_SVS	_SBF(12,0)		/*   start of vertical sync	*/
+#define LCD_CTRL_VCOMP_SBP	_SBF(12,1)		/*   start of back porch 	*/
+#define LCD_CTRL_VCOMP_SAV	_SBF(12,2)		/*   start of active video	*/
+#define LCD_CTRL_VCOMP_SFP	_SBF(12,3)		/*   start of front porch	*/
+
+#define LCD_CTRL_PWR		_BIT(11)		/* LCD Power Enable		*/ 
+#define LCD_CTRL_BEPO		_BIT(10)		/* Big Endian Pixel Order	*/ 
+#define LCD_CTRL_BEBO		_BIT(9)			/* Big Endian Byte Order	*/ 
+#define LCD_CTRL_BGR		_BIT(8)			/* Swap Red and Blue (RGB to BGR) */ 
+#define LCD_CTRL_DUAL		_BIT(7)			/* Dual Panel STN		*/ 
+#define LCD_CTRL_MON8		_BIT(6)			/* Monochrome LCD has 8-bit interface */ 
+#define LCD_CTRL_TFT 		_BIT(5)			/* TFT LCD			*/ 
+
+#define LCD_CTRL_BW_COLOR	_SBF(4,0)		/* STN LCD is Color		*/ 
+#define LCD_CTRL_BW_MONO	_SBF(4,1)		/* STN LCD is Monochrome	*/
+
+#define LCD_CTRL_BPP1		_SBF(1,0)		/* Bits per pixel		*/ 
+#define LCD_CTRL_BPP2		_SBF(1,1)
+#define LCD_CTRL_BPP4		_SBF(1,2)
+#define LCD_CTRL_BPP8		_SBF(1,3)
+#define LCD_CTRL_BPP16		_SBF(1,4)
+#define LCD_CTRL_BPP24		_SBF(1,5)
+
+#define LCD_CTRL_ENABLE		_BIT(0)			/* LCD Controller Enable	*/ 
+
+
+
+typedef struct {
+    volatile u32 setup;					/* Setup		*/ 
+    volatile u32 control;				/* Control		*/ 
+    volatile u32 timing1;				/* HR-TFT Timing 1	*/ 
+    volatile u32 timing2;				/* HR-TFT Timing 2	*/ 
+} lcdicpRegs_t;
+
+
+
+/*
+ * LCDICP Setup Register Bit Fields
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than zero.
+ */ 
+#define	LCDICP_SETUP_MODE_BYPASS	_SBF(0,0)
+#define	LCDICP_SETUP_MODE_HRTFT		_SBF(0,1)
+#define	LCDICP_SETUP_MODE_DMTN		_SBF(0,2)
+#define	LCDICP_SETUP_HORIZ_REVERSE	_SBF(2,0)
+#define	LCDICP_SETUP_HORIZ_NORMAL	_SBF(2,1)
+#define	LCDICP_SETUP_VERT_REVERSE	_SBF(3,0)
+#define	LCDICP_SETUP_VERT_NORMAL	_SBF(3,1)
+/* Calculates bit field value from actual pixels per line */ 
+#define LCDICP_SETUP_PPL(n)		_SBF(4,((n)-1))
+#define LCDICP_SETUP_POWER		_BIT(13)	/* lh7a400 only */
+
+
+/*
+ * LCDICP Control Register Bit Fields
+ */ 
+#define LCDICP_CONTROL_SPSEN		_BIT(0)
+#define LCDICP_CONTROL_CLSEN		_BIT(1)
+#define LCDICP_CONTROL_UBLEN		_BIT(2)
+#define LCDICP_CONTROL_DISP		_BIT(3)
+#define LCDICP_CONTROL_EN0		_BIT(4)
+#define LCDICP_CONTROL_EN1		_BIT(5)
+#define LCDICP_CONTROL_EN2		_BIT(6)
+#define LCDICP_CONTROL_EN3		_BIT(7)
+
+
+/*
+ * LCDICP Timing 1 Register Bit Fields
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than zero.
+ */ 
+#define LCDICP_TIMING1_LPDEL(n)		_SBF(0,((n)-1)&0xF)
+#define LCDICP_TIMING1_REVDEL(n)	_SBF(4,((n)-1)&0xF)
+#define LCDICP_TIMING1_PSDEL(n)		_SBF(8,((n)-1)&0xF)
+#define LCDICP_TIMING1_CLSDEL(n)	_SBF(8,((n)-1)&0xF)
+
+
+/*
+ * LCDICP Timing 2 Register Bit Fields
+ *
+ * NOTE: Ensure the argument to the following macros is greater
+ * than zero.
+ */ 
+#define LCDICP_TIMING2_PSDEL2(n)	_SBF(0,((n)-1)&0x1FF)
+#define LCDICP_TIMING2_CLSDEL2(n)	_SBF(0,((n)-1)&0x1FF)
+#define LCDICP_TIMING2_SPLVALUE(n)	_SBF(9,((n)-1)&0x7F)
+
+
+/*
+ * These are the bitfields for each
+ * display depth that we support.
+ */
+struct pl110fb_rgb {
+	struct fb_bitfield	red;
+	struct fb_bitfield	green;
+	struct fb_bitfield	blue;
+	struct fb_bitfield	transp;
+};
+
+/*
+ * This structure describes the machine which we are running on.
+ */
+struct pl110fb_mach_info {
+	u_long		pixclock;
+
+	u_short		xres;
+	u_short		yres;
+
+	u_char		bpp;
+	u_char		hsync_len;		/* horiz sync pulse width	*/
+	u_char		left_margin;		/* horiz back porch		*/
+	u_char		right_margin;		/* horiz front porch		*/
+
+	u_char		vsync_len;		/* vertical sync pulse width	*/
+	u_char		upper_margin;		/* vertical back porch		*/
+	u_char		lower_margin;		/* vertical front porch		*/
+	u_char		sync;
+
+	u_int		cmap_greyscale:1,
+			cmap_inverse:1,
+			cmap_static:1,
+			unused:29;
+
+	u_long		 LCDtiming2;
+	u_long		 LCDtiming3;
+	u_long		 LCDcontrol;
+	u_long		 LCDICPsetup;
+	u_long		 LCDICPcontrol;
+	u_long		 LCDICPtiming1;
+	u_long		 LCDICPtiming2;
+};
+
+
+/* Shadows for LCD/LCDICP controller registers */
+struct pl110fb_lcd_reg {
+	u_long		 LCDtiming0;
+	u_long		 LCDtiming1;
+	u_long		 LCDtiming2;
+	u_long		 LCDtiming3;
+	u_long		 LCDcontrol;
+	u_long		 LCDICPsetup;
+	u_long		 LCDICPcontrol;
+	u_long		 LCDICPtiming1;
+	u_long		 LCDICPtiming2;
+};
+
+#define RGB_8	(0)
+#define RGB_16	(1)
+#define NR_RGB	2
+
+struct pl110fb_info {
+	struct fb_info		fb;
+	signed int		currcon;
+
+	struct pl110fb_rgb	*rgb[NR_RGB];
+
+	u_int			max_bpp;
+	u_int			max_xres;
+	u_int			max_yres;
+
+	/*
+	 * These are the addresses we mapped
+	 * the framebuffer memory region to.
+	 */
+	dma_addr_t		map_dma;
+	u_char *		map_cpu;
+	u_int			map_size;
+
+	u_char *		screen_cpu;
+	dma_addr_t		screen_dma;
+	u_int			palette_size;
+
+	dma_addr_t		upbase;
+	dma_addr_t		lpbase;
+
+	u_long			LCDtiming2;
+	u_long			LCDtiming3;
+	u_long			LCDcontrol;
+	u_long			LCDICPsetup;
+	u_long			LCDICPcontrol;
+	u_long			LCDICPtiming1;
+	u_long			LCDICPtiming2;
+
+	u_int			cmap_inverse:1,
+				cmap_static:1,
+				unused:30;
+
+	u_long			reg_LCDtiming0;
+	u_long			reg_LCDtiming1;
+	u_long			reg_LCDtiming2;
+	u_long			reg_LCDtiming3;
+	u_long			reg_LCDcontrol;
+	u_long			reg_LCDICPsetup;
+	u_long			reg_LCDICPcontrol;
+	u_long			reg_LCDICPtiming1;
+	u_long			reg_LCDICPtiming2;
+
+	volatile u_char		state;
+	volatile u_char		task_state;
+	struct semaphore	ctrlr_sem;
+	wait_queue_head_t	ctrlr_wait;
+	struct tq_struct	task;
+
+#ifdef CONFIG_PM
+	struct pm_dev		*pm;
+#endif
+#ifdef CONFIG_CPU_FREQ
+	struct notifier_block	clockchg;
+#endif
+};
+
+#define __type_entry(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member)))
+
+#define TO_INF(ptr,member)	__type_entry(ptr,struct pl110fb_info,member)
+
+/*
+ * These are the actions for set_ctrlr_state
+ */
+#define C_DISABLE		(0)
+#define C_ENABLE		(1)
+#define C_DISABLE_CLKCHANGE	(2)
+#define C_ENABLE_CLKCHANGE	(3)
+#define C_REENABLE		(4)
+#define C_DISABLE_PM		(5)
+#define C_ENABLE_PM		(6)
+
+#define PL110_NAME	"PL110"
+
+/*
+ *  Debug macros 
+ */
+#if DEBUG
+#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+/*
+ * Minimum X and Y resolutions
+ */
+#define MIN_XRES	64
+#define MIN_YRES	64
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/ads_784x.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/ads_784x.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/ads_784x.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/ads_784x.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,25 @@
+/* vi: set sw=4 ts=4 ai: */
+
+/*
+*  linux/include/asm-arm/arch-lh79520/ads_784x.h
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  Provide ADS_784x (touchscreen) types & definitions for LH7x EVB boards
+*
+*/
+
+#ifndef _ADS_784X_h
+#define _ADS_784X_h
+
+#include <asm-arm/arch-lh79520/ssp_lh7x.h>
+
+/*********************************************************************
+* Global Function Declarations
+*********************************************************************/
+extern int ads_784x_register(sspContext_t *sspContext);
+extern int ads_784x_deregister(void);
+
+
+#endif /* _ADS_784X_h */
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/cpld.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/cpld.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/cpld.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/cpld.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,138 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/cpld.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LH79520_CPLD_H 
+#define  _LH79520_CPLD_H 
+
+typedef __attribute((packed))  struct {
+	volatile u16 keys_status;
+	volatile u16 reserved1;
+	volatile u16 l3_reg;
+	volatile u16 reserved2;
+	volatile u16 lcd_pwr_cntl;
+	volatile u16 reserved3;
+	volatile u16 l3_mode;
+	volatile u16 reserved4;
+	volatile u16 gpi;
+	volatile u16 reserved5;
+	volatile u16 gpo;
+	volatile u16 reserved6;
+	volatile u16 adc_dac_left;
+	volatile u16 adc_dac_right;
+	volatile u16 audio_control;
+	volatile u16 reserved7;
+	volatile u16 display_dip_sw;
+	volatile u16 reserved8;
+	volatile u16 seven_seg;
+	volatile u16 reserved9;
+	volatile u16 misc_stat;
+	volatile u16 reserved10;
+	volatile u16 gpio_data_dir;
+	volatile u16 reserved11;
+	volatile u16 ssp_dev_sel;
+	volatile u16 reserved12;
+	volatile u16 ser_port1_rts;
+	volatile u16 reserved13;
+	volatile u16 cf_reset;
+	volatile u16 reserved14;
+	volatile u16 cpu_dip_sw;
+	volatile u16 reserved15;
+	volatile u16 intr_mask;
+	volatile u16 reserved16;
+	volatile u16 reserved17;
+	volatile u16 reserved18;
+	volatile u16 reserved19;
+	volatile u16 reserved20;
+	volatile u16 reserved21;
+	volatile u16 reserved22;
+	volatile u16 nio_reg_clk;
+	volatile u16 reserved23;
+} cpldRegs_t;
+
+
+/* LCD power bits */
+#define CPLD_EN26V		_BIT(0)		/* turn on the 26V supply */
+#define CPLD_BACKLIGHT_ON	_BIT(1)		/* turn on the backlight */
+#define CPLD_DISP_EN		_BIT(2)		/* note DISP_EN is not wired on the Sharp EVB display board */
+#define CPLD_LCD_OE		_BIT(3)		/* enable the LCD drive signals */
+#define CPLD_LCD_PWR		_BIT(4)
+
+/* 
+ * enable the LCD 3.3V or 5V power supply; 
+ * does not effect HR-TFT power on the Sharp EVB display board.
+ */
+#define CPLD_LCDP_EN		_BIT(4)
+
+
+/* intr_mask bits */
+#define CPLD_TS_INTR_ENABLE	_BIT(7)		/* Enable touch screen IRQ */
+#define CPLD_CTS_INTR_ENABLE	_BIT(6)
+#define CPLD_RI_INTR_ENABLE	_BIT(5)
+
+/* misc_status bits */
+#define CPLD_MISCSTS_TS_IRQ	_BIT(4)		/* Touch Screen caused IRQ */
+#define CPLD_MISCSTS_TS_BUSY	_BIT(5)		/* Touch Screen busy */
+
+/* L3 mode bits */
+#if 0 // DDD
+#define CPLD_L3_MODE_HI		(cpld->l3_mode |= _BIT(0))
+#define CPLD_L3_MODE_LOW	(cpld->l3_mode |= ~(_BIT(0)))
+#else
+#define CPLD_L3_MODE_HI		cpld->l3_mode = _BIT(0) ; barrier()
+#define CPLD_L3_MODE_LOW	cpld->l3_mode = 0; barrier()
+#endif
+
+/* I2S audio control register bits */
+#define CPLD_DAC_USE_REQ1		_BIT(12)
+#define CPLD_ADC_DMA_ENABLE		_BIT(7)
+#define CPLD_DAC_DMA_ENABLE		_BIT(6)
+#define CPLD_ADC_DMA_AUTO		_BIT(5)
+#define CPLD_DAC_DMA_AUTO		_BIT(4)
+#define CPLD_ADC_IRQ_ENABLE		_BIT(3)
+#define CPLD_DAC_IRQ_ENABLE		_BIT(2)
+#define CPLD_ADC_IRQ_STATUS		_BIT(1)
+#define CPLD_DAC_IRQ_STATUS		_BIT(0)
+#define CPLD_AUDIO_DAC_INT_PENDING	_BIT(0)
+#define CPLD_AUDIO_ADC_INT_PENDING	_BIT(1)
+#define CPLD_AUDIO_DAC_INT_ENALBED	_BIT(2)
+#define CPLD_AUDIO_ADC_INT_ENABLED	_BIT(3)
+#define CPLD_AUDIO_DAC_INT_MASK \
+		(CPLD_AUDIO_DAC_INT_PENDING | CPLD_AUDIO_DAC_INT_ENALBED)
+#define CPLD_AUDIO_ADC_INT_MASK \
+		(CPLD_AUDIO_ADC_INT_PENDING | CPLD_AUDIO_ADC_INT_ENABLED)
+
+#define CPLD_ALL_ADC_BITS (CPLD_ADC_IRQ_STATUS | \
+		CPLD_ADC_IRQ_ENABLE | \
+		CPLD_ADC_DMA_AUTO | \
+		CPLD_ADC_DMA_ENABLE)
+
+#define CPLD_ALL_DAC_BITS (CPLD_DAC_IRQ_STATUS | \
+		CPLD_DAC_IRQ_ENABLE | \
+		CPLD_DAC_DMA_AUTO | \
+		CPLD_DAC_DMA_ENABLE | \
+		CPLD_DAC_USE_REQ1)
+
+#define CPLD_ALL_AUDIO_BITS (CPLD_ALL_DAC_BITS | CPLD_ALL_DAC_BITS)
+
+#define CPLD_FS_BIT_FIELD	8
+#define CPLD_FS_BITS		_SBF(CPLD_FS_BIT_FIELD, _BITMASK(4) );
+#define CPLD_FS_8000		0
+#define CPLD_FS_11025		1
+#define CPLD_FS_12000		2
+#define CPLD_FS_16000		3
+#define CPLD_FS_22050		4
+#define CPLD_FS_24000		5
+#define CPLD_FS_32000		6
+#define CPLD_FS_44100		7
+#define CPLD_FS_48000		8
+
+#endif // _LH79520_CPLD_H 
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/dma.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/dma.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/dma.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/dma.h	2005-11-02 17:42:49.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/dma.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <asm/hardware.h>
+#include <asm/arch/cpld.h>
+
+#define MAX_DMA_ADDRESS		0xfffc0000
+
+#define MAX_DMA_CHANNELS	0
+#define LH79520_DMA_CHANNELS	4
+
+/*
+ * All possible LH79520 devices a DMA channel can be attached to.
+ */
+/* FIXME */
+
+typedef enum {
+    DMA_SSP_Rx,
+    DMA_SSP_Tx,
+    DMA_Audio_Out,
+    DMA_Audio_In
+} dma_device_t;
+
+
+typedef void (*dma_callback_t)( void *buf_id, int size );
+
+
+/* LH79520 DMA API */
+extern int lh79520_request_dma( dmach_t *channel, const char *device_id,
+			       dma_device_t device );
+extern int lh79520_dma_set_callback( dmach_t channel, dma_callback_t cb );
+extern int lh79520_dma_set_spin( dmach_t channel, dma_addr_t addr, int size );
+extern int lh79520_dma_queue_buffer( dmach_t channel, void *buf_id,
+				    dma_addr_t data, int size );
+extern int lh79520_dma_get_current( dmach_t channel, void **buf_id, dma_addr_t *addr );
+extern int lh79520_dma_stop( dmach_t channel );
+extern int lh79520_dma_resume( dmach_t channel );
+extern int lh79520_dma_flush_all( dmach_t channel );
+extern void lh79520_free_dma( dmach_t channel );
+extern int lh79520_dma_sleep( dmach_t channel );
+extern int lh79520_dma_wakeup( dmach_t channel );
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/gpio.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/gpio.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/gpio.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/gpio.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,139 @@
+/*
+ * linux/include/asm-arm/arch-lh79520/gpio.h
+ *
+ * Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ * Original Author:   BarnettH
+ * Date:   May 17 2001 17:47:58
+ *
+ * Project: ARM IP headers
+ *
+ * Description:
+ *    This file contains the structure definitions and manifest
+ *    constants for ARM IP component:
+ *         General Purpose Input/Output PrimeCell PL060
+ *
+ *         Each GPIO Module has two GPIO (digital IO) ports which are
+ *         designated PORTA and PORTB.
+ *
+ *         Multiple instances of a GPIO module, and thus port pairs,
+ *         may be implemented in a single SOC.
+ *
+ *         Each port has eight bits, PORTx[7:0].
+ *
+ *         Each port has two 8-bit registers associated with it:
+ *             GPIOPxDR - Data register (dr)
+ *             GPIOPxDDR - Data Direction register (ddr)
+ *
+ *         The specific SOC will have its own unique name for the port.
+ *         Each port pair will have its own unique base address for the
+ *         port pair.
+ *
+ *         This include file is designed to permit the definition of 
+ *         pointers in the SOC map include file to distinct 8-bit ports
+ *         using the name designation is suitable for the SOC
+ *         implementation.
+ *
+ *         Example:
+ *         A map file that includes this file should specify a
+ *         base address for each GPIO module, e.g.:
+ *
+ *         #define GPIO0_BASE (0xFFFDF000)
+ *         #define GPIO1_BASE (0xFFFDE000)
+ *             *
+ *             *
+ *             *
+ *
+ *         The SOC map file will use these base addresses to define
+ *         pointers to GPIO port A, B, C, D, E, ... thusly:
+ *
+ *         #define GPIOPA ((volatile GPIOAREGS *)(GPIO0_BASE))
+ *         #define GPIOPB ((volatile GPIOBREGS *)(GPIO0_BASE))
+ *         #define GPIOPC ((volatile GPIOAREGS *)(GPIO1_BASE))
+ *         #define GPIOPD ((volatile GPIOBREGS *)(GPIO1_BASE))
+ *         #define GPIOPE ((volatile GPIOAREGS *)(GPIO2_BASE))
+ *             *
+ *             *
+ *             *
+ *
+ *         Example usage of these definitions in user code for Port C:
+ *
+ *             unsigned int data;
+ *
+ *             GPIOC->ddr = 0xF;    sets bits [7:4] as outputs
+ *                                  and bits [3:0] as inputs
+ *             GPIOC->dr  = 0xF0;   sets bits [7:4] to "1"
+ *
+ *             data = GPIOC->dr;    sets data to the value of
+ *                                  data register
+ *
+ *   Note: If it is desired to use the type qualifier "__packed"
+ *          to enable packing of structures, the manifest constant
+ *          "PACKED" must be defined as follows or as a
+ *          predefine at compilation (ARM-specific notation):
+ *
+ *    #define PACKED __packed
+ *
+ *    If a different compiler/preprocessor is used, the appropriate
+ *    notation must be substituted for "__packed".
+ *
+ *    Reference: ARM PrimeCell General Purpose Input/Output (PL060)
+ *               Technical Reference Manual, ARM DDI 0142B.
+ *
+ *    Revision History:
+ * 
+ *    Rev 1.1   May 17 2001 17:47:58   BarnettH
+ * Changed structure component types to reflect 32-bit access requirements.
+ * 
+ *    Rev 1.0   Mar 30 2001 16:03:30   BarnettH
+ * Initial revision.
+ * 
+ *    COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
+ *    CAMAS, WA
+ *********************************************************************/
+
+#ifndef ARM_GPIO_PL060_H
+#define ARM_GPIO_PL060_H
+
+/* GPIO Register Structures */ 
+//typedef __attribute((packed)) struct {
+typedef struct {
+    volatile unsigned int dr;
+    volatile unsigned int reserveda1;
+    volatile unsigned int ddr;
+    volatile unsigned int reserveda2;
+} gpioARegs_t;
+
+//typedef __attribute((packed)) struct {
+typedef struct {
+    volatile unsigned int reservedb1;
+    volatile unsigned int dr;
+    volatile unsigned int reservedb2;
+    volatile unsigned int ddr;
+} gpioBRegs_t;
+
+/*
+ * The names and usage of the bit fields in these registers is
+ * implementation specific, so few bit field constants are defined.
+ */ 
+
+#ifndef _BIT
+#define _BIT(n) (1 << (n))
+#endif
+
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+
+#define SSPFRM_GPIO_BIT _BIT(2)
+#define SSPEN_GPIO_BIT _BIT(0)
+
+#define GPIOPAREGS gpioARegs_t
+#define GPIOPBREGS gpioBRegs_t
+
+#endif /* ARM_GPIO_PL060_H */ 
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/hardware.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/hardware.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/hardware.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/hardware.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,341 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/hardware.h
+ *
+ *	Copyright (C) 2001 Sharp Microelectronics of the Americas, Inc.
+ *		CAMAS, WA
+ *  Portions Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ *	References:
+ *		(1) Sharp LH79520 Universal Microcontroller User's Guide,
+ *		Version 1.x, Sharp Microelectronics of the Americas, Inc.
+ *
+ */
+
+#ifndef _BIT
+#define _BIT(n)	(1 << (n))
+#endif
+
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+
+#ifndef _BITMASK
+#define _BITMASK(field_width) ( _BIT(field_width) - 1)
+#endif
+
+/* Hardware addresses of major areas.
+ *  *_START is the physical address
+ *  *_SIZE  is the size of the region
+ *  *_BASE  is the virtual address
+ */
+
+/*
+ * we can do an identity mapping (V=P) of all of I/O
+ * space, except for the VIC.
+ *
+ * One of the places you can find the VIC is at 0xffff0000,
+ * which is the same place the interrupt vectors want to live,
+ * so we'll leave a hole there, and use the VIC at it's other
+ * address: 0xfffff000.
+ */
+
+#define APB_START	0xfffc0000	/* Physical address of APB I/O space */
+#define APB_BASE	0xfffc0000	/* Virtual address of APB I/O space  */
+#define APB_SIZE	0x00026000	/* its size (up to 0xfffe6000)   */
+
+#define AHB_START	0xffff1000	/* Physical address of AHB I/O space */
+#define AHB_BASE	0xffff1000	/* Virtual address of AHB I/O space  */
+#define AHB_SIZE	0x00004000	/* its size (up to 0xffff5000)  */
+
+#define VIC_START	VIC_PHYS	/* Physical address of VIC	*/
+#define VIC_BASE	0xfffff000	/* Virtual address of VIC	*/
+#define VIC_SIZE	0x1000		/* its size			*/
+
+
+
+#define	FLASH_START	0x40000000	/* Flash on SMC bank 0		*/
+#define	FLASH_BASE	0xf4000000
+#define	FLASH_SIZE	(4 * 1024 * 1024)
+
+#define EXT_SRAM_START	0x44000000	/* External SRAM on SMC bank 1	*/
+#define EXT_SRAM_BASE	0xf4400000
+#define EXT_SRAM_SIZE	(2 * 1024 * 1024)
+
+
+// not used, but there is still code that breaks without it
+#define CPLD_START	0x48000000	/* CPLD on SMC bank 2		*/
+#define CPLD_BASE	0xf4800000
+#define CPLD_SIZE	4096
+
+#define CS8900_START	0x48000000	/* Ethernet on SMC bank 2	*/
+#define CS8900_BASE	0xf4800000
+#define CS8900_SIZE	4096
+
+#define GPOUT16_START	0x4c000000	/* latch on bank 3	*/
+#define GPOUT16_BASE	0xf4c00000
+#define GPOUT16_SIZE	4096
+
+
+#define IDE_START	0x50000000	/* CF/IDE on SMC bank 4		*/
+#define IDE_BASE	0xf5000000
+#define IDE_SIZE	4096
+
+#define IDE2_START	0x54000000	/* CF/IDE   on SMC bank 5	*/
+#define IDE2_BASE	0xf5400000
+#define IDE2_SIZE	4096
+
+#define UNUSED_START	0x58000000	/* unused   on SMC bank 6	*/
+#define RESERVED_START	0x5C000000	/* reserved on SMC bank 7	*/
+
+#define	INT_SRAM_START	0x60000000	/* on-chip SRAM			*/
+#define	INT_SRAM_BASE	0xf6000000
+#define	INT_SRAM_SIZE	(32 * 1024)
+
+
+#define IO_START	APB_START
+#define IO_BASE		APB_BASE
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(phys)	(phys) 
+
+#define PCIO_BASE	IO_BASE
+
+
+/**********************************************************************
+ * AHB BASES
+ *********************************************************************/
+#define AHB_PHYS		(0xFFFF0000)
+#define VIC_PHYS_MIRROR		(AHB_PHYS + 0x0000)
+#define SMC_REGS_PHYS		(AHB_PHYS + 0x1000)
+#define SDRAM_REGS_PHYS		(AHB_PHYS + 0x2000)
+#define LCD_PHYS		(AHB_PHYS + 0x4000)
+#define VIC_PHYS		(AHB_PHYS + 0xF000)
+
+/**********************************************************************
+ * APB PHYSS
+ *********************************************************************/
+#define APB_PHYS		(0xFFFC0000)
+#define UART0_PHYS		(APB_PHYS + 0x00000)
+#define UART1_PHYS		(APB_PHYS + 0x01000)
+#define UART2_PHYS		(APB_PHYS + 0x02000)
+#define PWM_PHYS		(APB_PHYS + 0x03000)
+#define TIMER0_PHYS		(APB_PHYS + 0x04000)
+#define TIMER1_PHYS		(APB_PHYS + 0x05000)
+#define SSP_PHYS		(APB_PHYS + 0x06000)
+#define GPIO3_PHYS		(APB_PHYS + 0x1C000)
+#define GPIO2_PHYS		(APB_PHYS + 0x1D000)
+#define GPIO1_PHYS		(APB_PHYS + 0x1E000)
+#define GPIO0_PHYS		(APB_PHYS + 0x1F000)
+#define RTC_PHYS		(APB_PHYS + 0x20000)
+#define DMAC_PHYS		(APB_PHYS + 0x21000)
+#define RCPC_PHYS		(APB_PHYS + 0x22000)
+#define WDTIMER_PHYS		(APB_PHYS + 0x23000)
+#define LCDICP_PHYS		(APB_PHYS + 0x24000)
+#define IOCON_PHYS		(APB_PHYS + 0x25000)
+
+/**********************************************************************
+ * REMAPping
+ *********************************************************************/
+#define SDRAM_MEM_PHYS		(0x20000000)
+#define SMC_MEM_PHYS		(0x40000000)
+#define INTERNAL_MEM_PHYS	(0x60000000)
+
+// DDD #if REMAP == 0 
+#define SMC_MIRROR_MEM_PHYS	(0x00000000)
+// DDD #elif REMAP == 1 
+// DDD #define SDRAM_MIRROR_MEM_PHYS		(0x00000000)
+// DDD #elif REMAP == 2 
+// DDD #define INTERNAL_MIRROR_MEM_PHYS	(0x00000000)
+// DDD #else
+// DDD #error REMAP must be defined as 0, 1, or 2
+// DDD #endif
+
+/**********************************************************************
+ * xSPR bits
+ *********************************************************************/
+#define CORE_IRQ	_BIT(7)
+#define CORE_FIQ	_BIT(6)
+
+/**********************************************************************
+ * SMC Memory Bank Address Space Bases
+ *********************************************************************/
+
+#define SMC_BANK0_PHYS		(SMC_MEM_PHYS + 0x00000000)
+#define SMC_BANK1_PHYS		(SMC_MEM_PHYS + 0x04000000)
+#define SMC_BANK2_PHYS		(SMC_MEM_PHYS + 0x08000000)
+#define SMC_BANK3_PHYS		(SMC_MEM_PHYS + 0x0C000000)
+#define SMC_BANK4_PHYS		(SMC_MEM_PHYS + 0x10000000)
+#define SMC_BANK5_PHYS		(SMC_MEM_PHYS + 0x14000000)
+#define SMC_BANK6_PHYS		(SMC_MEM_PHYS + 0x18000000)
+#define SMC_BANK7_PHYS		(SMC_MEM_PHYS + 0x1C000000)
+
+/**********************************************************************
+ * SDRAMC Memory Bank Address Space Bases
+ *********************************************************************/
+
+#define SDRAM_BANK0_PHYS	(SDRAM_MEM_PHYS + 0x00000000)
+#define SDRAM_BANK1_PHYS	(SDRAM_MEM_PHYS + 0x08000000)
+
+/**********************************************************************
+ * Vectored Interrupt Controller (VIC)
+ *********************************************************************/
+#define VICID_OFFSET		(0xFE0)
+// DDD #define VIC			((VICREGS *)(VIC_PHYS))
+// DDD #define VICID			((VICIDREGS *)(VIC_PHYS + VICID_OFFSET))
+#define VIC_INT_TYPE_IRQ	0
+#define VIC_INT_TYPE_FIQ	1
+
+/* VIC Interrupt Sources */ 
+#define	VIC_EXTINT0		0
+#define	VIC_EXTINT1		1
+#define	VIC_EXTINT2		2
+#define	VIC_EXTINT3		3
+#define	VIC_EXTINT4		4
+#define	VIC_EXTINT5		5
+#define	VIC_EXTINT6		6
+#define	VIC_EXTINT7		7
+#define	VIC_SPEXTINT0		8
+#define	VIC_SPEXTINT1		9
+#define	VIC_SPEXTINT2		10
+#define	VIC_SPEXTINT3		11
+#define	VIC_CLCDC		12
+#define	VIC_SSPTXINTR		13
+#define	VIC_SSPRXINTR		14
+#define	VIC_SSPRORINTR		15
+#define	VIC_SSPINTR		16
+#define	VIC_TIMER0		17
+#define	VIC_TIMER1		18
+#define	VIC_TIMER2		19
+#define	VIC_TIMER3		20
+#define	VIC_UART0_RX		21
+#define	VIC_UART0_TX		22
+#define	VIC_UART0		23
+#define	VIC_UART1		24
+#define	VIC_UART2		25
+#define	VIC_DMA0		26
+#define	VIC_DMA1		27
+#define	VIC_DMA2		28
+#define	VIC_DMA3		29
+#define	VIC_RTC			30
+#define	VIC_WDT			31
+
+/* VIC Vectors */ 
+#define VIC_VECT_0		0
+#define VIC_VECT_1		1
+#define VIC_VECT_2		2
+#define VIC_VECT_3		3
+#define VIC_VECT_4		4
+#define VIC_VECT_5		5
+#define VIC_VECT_6		6
+#define VIC_VECT_7		7
+#define VIC_VECT_8		8
+#define VIC_VECT_9		9
+#define VIC_VECT_10		10
+#define VIC_VECT_11		11
+#define VIC_VECT_12		12
+#define VIC_VECT_13		13
+#define VIC_VECT_14		14
+#define VIC_VECT_15		15
+#define VIC_VECT_MAX		VIC_VECT_15
+#define VIC_VECT_DEFAULT	~(0)
+
+
+#define	XTAL_IN			14745600	/* 14.7456 MHz crystal	*/
+#define PLL_CLOCK		(XTAL_IN * 21)	/* 309 MHz PLL clock	*/
+
+
+
+/**********************************************************************
+ * UART'S
+ *********************************************************************/
+#define UARTID_OFFSET	(0xFE0)
+// DDD #define UART0		((UARTREGS *)(UART0_PHYS))
+// DDD #define UART1		((UARTREGS *)(UART1_PHYS))
+// DDD #define UART2		((UARTREGS *)(UART2_PHYS))
+// DDD #define UART0ID		((UARTIDREGS *)(UART0_PHYS + UARTID_OFFSET))
+// DDD #define UART1ID		((UARTIDREGS *)(UART1_PHYS + UARTID_OFFSET))
+// DDD #define UART2ID		((UARTIDREGS *)(UART2_PHYS + UARTID_OFFSET))
+
+/**********************************************************************
+ * IRDA
+ *********************************************************************/
+// DDD #define IRDA0	((UARTREGS *)(UART0_PHYS))
+// DDD #define IRDA1	((UARTREGS *)(UART1_PHYS))
+// DDD #define IRDA2	((UARTREGS *)(UART2_PHYS))
+
+/**********************************************************************
+ * Pulse Width Modulator (PWM)
+ *********************************************************************/
+// DDD #define PWMX_OFFSET	(0x20)
+// DDD #define PWM		((PWMREGS *)(PWM_PHYS))
+// DDD #define PWM0		((PWMXREGS *)(PWM_PHYS))
+// DDD #define PWM1		((PWMXREGS *)(PWM_PHYS + PWMX_OFFSET))
+
+/**********************************************************************
+ * TIMER
+ *********************************************************************/
+// DDD #define TIMER2_OFFSET	(0x20)
+// DDD #define TIMER0		((TIMERREG *)(TIMER0_PHYS))
+// DDD #define TIMER1		((volatile TIMERREG *)(TIMER0_PHYS + TIMER2_OFFSET))
+// DDD #define TIMER2		((TIMERREG *)(TIMER1_PHYS))
+// DDD #define TIMER3		((TIMERREG *)(TIMER1_PHYS + TIMER2_OFFSET))
+
+/**********************************************************************
+ * Synchronous Serial Port (SSP)
+ *********************************************************************/
+// DDD #define SSP		((SSPREGS *)(SSP_PHYS))
+
+/**********************************************************************
+ * General Purpose Input/Output (GPIO)
+ *********************************************************************/
+#define GPIOA	((GPIOPAREGS *)(GPIO0_PHYS))
+#define GPIOB	((GPIOPBREGS *)(GPIO0_PHYS))
+#define GPIOC	((GPIOPAREGS *)(GPIO1_PHYS))
+#define GPIOD	((GPIOPBREGS *)(GPIO1_PHYS))
+#define GPIOE	((GPIOPAREGS *)(GPIO2_PHYS))
+#define GPIOF	((GPIOPBREGS *)(GPIO2_PHYS))
+#define GPIOG	((GPIOPAREGS *)(GPIO3_PHYS))
+#define GPIOH	((GPIOPBREGS *)(GPIO3_PHYS))
+
+/**********************************************************************
+ * Real Time Clock (RTC)
+ *********************************************************************/
+// DDD #define RTC	((RTCREGS *)(RTC_PHYS))
+
+/**********************************************************************
+ * DMA Controller (DMAC)
+ *********************************************************************/
+// DDD #define DMAC	((DMACREGS *)(DMAC_PHYS))
+
+/**********************************************************************
+ * Reset, Clock, and Power Controller (RCPC)
+ *********************************************************************/
+// DDD #define RCPC	((RCPCREGS *)(RCPC_PHYS))	
+
+/**********************************************************************
+ * Watchdog Timer (WDTIMER)
+ *********************************************************************/
+// DDD #define WDTIMER		((WDTIMERREGS *)(WDTIMER_PHYS))
+
+/**********************************************************************
+ * LCD Interface Control Processor (LCDICP)
+ *********************************************************************/
+// DDD #define LCDICP		((LCDICPREGS *)(LCDICP_PHYS))
+
+/**********************************************************************
+ * IOCON
+ *********************************************************************/
+// DDD #define IOCON	((IOCONREGS *)(IOCON_PHYS))
+
+/**********************************************************************
+ * GPOUT16 (MARMALADE)
+ *********************************************************************/
+#define	nLED		_BIT(8)
+#define	TS_DIN		_BIT(9)
+#define	nTS_CS		_BIT(10)
+#define	TS_DCLK		_BIT(11)
+#define	BACKLIGHT	_BIT(15)
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/ide.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/ide.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/ide.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/ide.h	2005-11-02 17:48:27.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * linux/include/asm-arm/arch-lh79520/ide.h
+ *
+ * Copyright 2002 Lineo, Inc.
+ *
+ * 17-Jan-2002: Initial clone of arch-anakin/ide.h
+ */
+ 
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg;
+	int i;
+	int regincr = 4;
+	
+	memset(hw, 0, sizeof(*hw));
+
+	reg = (ide_ioreg_t)data_port;
+
+	for( i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += regincr;
+	}
+	
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
+	
+	if (irq)
+		*irq = 0;
+}
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+    hw_regs_t hw;
+
+	/*
+	 * The IDE data ports are mapped in at IDE_BASE, and are aligined on 32 bit boundaries
+	 * The IDE control port (usually found at port 0x3f6 on a PC, e.g.) is 6 ints into IDE_BASE2.
+	 */
+    ide_init_hwif_ports( &hw, IDE_BASE, (char *)IDE2_BASE + 6*sizeof(int), NULL);
+    hw.irq = IRQ_CF;
+    ide_register_hw( &hw, NULL);
+}
+
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/iocon.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/iocon.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/iocon.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/iocon.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,210 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/iocon.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *	COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
+ *		CAMAS, WA
+ *
+ * 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
+ *
+ *	Description:
+ *      This file contains the structure definitions and manifest
+ *      constants for ARM IP component:
+ *      	I/O Configuration Block 
+ *
+ *	References:
+ *		(1) Sharp LH79520 Universal Microcontroller User's Guide,
+ *		Version 1.x, Sharp Microelectronics of the Americas, Inc.
+ *		(2) ARM Isis Technical Reference Manual, System on Chip Group,
+ *		ARM SC063-TRM-0001-B
+ *
+ *********************************************************************/
+
+#ifndef LH79520_IOCON_H
+#define LH79520_IOCON_H
+
+#if 0
+#ifndef _BIT
+#define _BIT(n)	(1 << (n))
+#endif
+
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+#endif // 0
+
+/*
+ * IO Configuration Block Structure
+ */ 
+typedef struct {
+	volatile unsigned int	MemMux;
+	volatile unsigned int	LCDMux;
+	volatile unsigned int	MiscMux;
+	volatile unsigned int	DMAMux;
+	volatile unsigned int	UARTMux;
+	volatile unsigned int	SSIMux;
+	volatile unsigned int	Scratchreg;
+} ioconRegs_t;
+
+/*
+ * Memory Multiplexing IOCON Register Bit Field constants
+ */ 
+#define MEMMUX_PIOE_NOMUX		_SBF(0,0)
+#define MEMMUX_MIDQM32			_SBF(0,1)
+#define MEMMUX_MIDQM30			_SBF(0,3)
+#define MEMMUX_PIOE4			_SBF(2,0)
+#define MEMMUX_MINWE			_SBF(2,1)
+#define MEMMUX_PIOE5			_SBF(3,0)
+#define MEMMUX_MISDNCS0			_SBF(3,1)
+#define MEMMUX_PIOE6			_SBF(4,0)
+#define MEMMUX_MISDNCS1			_SBF(4,1)
+#define MEMMUX_PIOE7			_SBF(5,0)
+#define MEMMUX_MICKE			_SBF(5,1)
+#define MEMMUX_PIOF0			_SBF(6,0)
+#define MEMMUX_MICLKIO			_SBF(6,1)
+#define MEMMUX_PIO_X			_SBF(7,0)
+#define MEMMUX_MIDATA_X			_SBF(7,1)
+#define MEMMUX_PIOH2			_SBF(8,0)
+#define MEMMUX_MICSN3			_SBF(8,1)
+#define MEMMUX_PIOH3			_SBF(9,0)
+#define MEMMUX_MICSN4			_SBF(9,1)
+#define MEMMUX_PIOH4			_SBF(10,0)
+#define MEMMUX_MICSN5			_SBF(10,1)
+#define MEMMUX_PIOH5			_SBF(11,0)
+#define MEMMUX_MICSN6			_SBF(11,1)
+#define MEMMUX_PIOH6			_SBF(12,0)
+#define MEMMUX_MIBLSN2			_SBF(12,1)
+#define MEMMUX_PIOH7			_SBF(13,0)
+#define MEMMUX_MIBLSN3			_SBF(13,1)
+
+/*
+ * LCD Multiplexing IOCON Register Bit Field constants
+ */ 
+#define LCDMUX_PIOB4			_SBF(0,0)
+#define LCDMUX_CLD12			_SBF(0,1)
+#define LCDMUX_CLREV			_SBF(0,2)
+#define LCDMUX_PIOB5            _SBF(2,0)
+#define LCDMUX_CLD13            _SBF(2,1)
+#define LCDMUX_PIOB6            _SBF(3,0)
+#define LCDMUX_CLD14            _SBF(3,1)
+#define LCDMUX_PIOB7            _SBF(4,0)
+#define LCDMUX_CLD15            _SBF(4,1)
+#define LCDMUX_CLDSPLEN			_SBF(4,2)
+#define LCDMUX_PIOC0			_SBF(6,0)
+#define LCDMUX_CLDEN			_SBF(6,1)
+#define LCDMUX_CLSPL            _SBF(6,2)
+#define LCDMUX_PIOC1			_SBF(8,0)
+#define LCDMUX_CLVDDEN			_SBF(8,1)
+#define LCDMUX_CLS  			_SBF(8,2)
+#define LCDMUX_PIOC2			_SBF(10,0)
+#define LCDMUX_CLXCLK			_SBF(10,1)
+#define LCDMUX_PIOC3			_SBF(11,0)
+#define LCDMUX_CLCP				_SBF(11,1)
+#define LCDMUX_PIOC4			_SBF(12,0)
+#define LCDMUX_CLD16			_SBF(12,1)
+#define LCDMUX_PIOC5			_SBF(13,0)
+#define LCDMUX_CLLP				_SBF(13,1)
+#define LCDMUX_CLP				_SBF(13,2)
+#define LCDMUX_PIOC6			_SBF(15,0)
+#define LCDMUX_CLD17			_SBF(15,1)
+#define LCDMUX_PIOC7			_SBF(16,0)
+#define LCDMUX_CLFP				_SBF(16,1)
+#define LCDMUX_CLSPS			_SBF(16,2)
+#define LCDMUX_PIOD0            _SBF(18,0)
+#define LCDMUX_CLD2             _SBF(18,1)
+#define LCDMUX_PIOD1            _SBF(19,0)
+#define LCDMUX_CLD3             _SBF(19,1)
+#define LCDMUX_PIOD2            _SBF(20,0)
+#define LCDMUX_CLD4             _SBF(20,1)
+#define LCDMUX_PIOD3            _SBF(21,0)
+#define LCDMUX_CLD5             _SBF(21,1)
+#define LCDMUX_PIOD4            _SBF(22,0)
+#define LCDMUX_CLD6             _SBF(22,1)
+#define LCDMUX_CPS              _SBF(22,2)
+#define LCDMUX_PIOD5            _SBF(24,0)
+#define LCDMUX_CLD7             _SBF(24,1)
+#define LCDMUX_PIOD6            _SBF(25,0)
+#define LCDMUX_CLD8             _SBF(25,1)
+#define LCDMUX_PIOD7            _SBF(26,0)
+#define LCDMUX_CLD9             _SBF(26,1)
+#define LCDMUX_RCEII6           _SBF(27,0)
+#define LCDMUX_CLD10            _SBF(27,1)
+#define LCDMUX_RCEII7           _SBF(28,0)
+#define LCDMUX_CLD11            _SBF(28,1)
+
+/*
+ * Miscellaneous Multiplexing IOCON Register Bit Field constants
+ */ 
+#define	MISCMUX_PWM1			_SBF(0,0)
+#define	MISCMUX_DCDEOT1			_SBF(0,1)
+#define	MISCMUX_PIOA5			_SBF(1,0)
+#define	MISCMUX_RCCLKOUT		_SBF(1,1)
+#define	MISCMUX_PIOA6			_SBF(2,0)
+#define	MISCMUX_RCEII0			_SBF(2,1)
+#define	MISCMUX_PIOA7			_SBF(3,0)
+#define	MISCMUX_RCEII1			_SBF(3,1)
+#define	MISCMUX_PIOB0			_SBF(4,0)
+#define	MISCMUX_RCEII2			_SBF(4,1)
+#define	MISCMUX_RCEII3			_SBF(5,0)
+#define	MISCMUX_PWM0SYNC		_SBF(5,1)
+#define	MISCMUX_RCEII4			_SBF(6,0)
+#define	MISCMUX_PWM0			_SBF(6,1)
+#define	MISCMUX_RCCTOUT			_SBF(7,0)
+#define	MISCMUX_DCDACK1			_SBF(7,1)
+#define	MISCMUX_DCDREQ1			_SBF(8,0)
+#define	MISCMUX_RCEII5			_SBF(8,1)
+#define	MISCMUX_PIOF1			_SBF(9,0)
+#define	MISCMUX_RCCLKEN			_SBF(9,1)
+#define	MISCMUX_RCCLKIN			_SBF(10,0)
+#define	MISCMUX_RCUTCLK			_SBF(10,1)
+
+/*
+ * DMA Multiplexing IOCON Register Bit Field constants
+ */ 
+#define	DMAMUX_PIOB1			_SBF(0,0)
+#define	DMAMUX_DCDEOT0			_SBF(0,1)
+#define	DMAMUX_PIOB2			_SBF(1,0)
+#define	DMAMUX_DCDACK0N			_SBF(1,1)
+#define	DMAMUX_PIOB3			_SBF(2,0)
+#define	DMAMUX_DCDREQ0			_SBF(2,1)
+
+/*
+ * UART Multiplexing IOCON Register Bit Field constants
+ */ 
+#define	UARTMUX_UT0IRRXA		_SBF(0,0)
+#define	UARTMUX_UT0RXD			_SBF(0,1)
+#define	UARTMUX_UT0IRTXA		_SBF(1,0)
+#define	UARTMUX_UT0TXD			_SBF(1,1)
+#define	UARTMUX_PIOA3			_SBF(2,0)
+#define	UARTMUX_UT1RXD			_SBF(2,1)
+#define	UARTMUX_PIOA4			_SBF(3,0)
+#define	UARTMUX_UT1TXD			_SBF(3,1)
+
+/*
+ * SSI Multiplexing IOCON Register Bit Field constants
+ */ 
+#define	SSIMUX_SSPIN			_SBF(0,0)
+#define	SSIMUX_UT2RXD			_SBF(0,1)
+#define	SSIMUX_SSPOUT			_SBF(1,0)
+#define	SSIMUX_UT2TXD			_SBF(1,1)
+#define	SSIMUX_PIOA0			_SBF(2,0)
+#define	SSIMUX_SSPENB			_SBF(2,1)
+#define	SSIMUX_PIOA1			_SBF(3,0)
+#define	SSIMUX_SSPCLK			_SBF(3,1)
+#define	SSIMUX_PIOA2			_SBF(4,0)
+#define	SSIMUX_SSPFRM			_SBF(4,1)
+
+#endif /* LH79520_IOCON_H */ 
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/io.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/io.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/io.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/io.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/io.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many 
+ * drivers out there that might just work if we fake them...
+ */
+// DDD #define __io(a)			(PCIO_BASE + (a))
+#define __io(a)				(a)
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+#define __arch_ioremap          __ioremap
+#define __arch_iounmap 		__iounmap
+
+/*
+ * Validate the pci memory address for ioremap.
+ */
+// DDD #define iomem_valid_addr(iomem,size)	(1)
+
+/*
+ * Convert PCI memory space to a CPU physical address
+ */
+// DDD #define iomem_to_phys(iomem)	(iomem)
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/irq.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/irq.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/irq.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/irq.h	2005-11-02 17:51:52.000000000 -0400
@@ -0,0 +1,250 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/irq.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/delay.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/rcpc.h>
+#include <asm/arch/iocon.h>
+#if 0
+#include <asm/arch/cpld.h>		// DDD only for testing the switches
+#endif
+
+
+#define NR_VEC	16			/* number of vectors */
+/*
+ * Vectored Interrupt Controller Module Register Structure
+ */ 
+typedef struct {
+	u32	IRQStatus;		/* masked IRQ status	*/
+	u32	FIQStatus;		/* masked FIQ status	*/
+	u32	RawIntr;		/* raw status		*/
+	u32	IntSelect;		/* select whether source generates IRQ or FIQ	*/
+	u32	IntEnable;		/* int enable mask				*/
+	u32	IntEnClear;		/* writes here clear bits in IntEnable		*/
+	u32	SoftInt;		/* gen soft interrupts				*/
+	u32	SoftIntClear;		/* writes here clear bits in SoftInt		*/
+	u32	Protection;		/* protection enable				*/
+	u32	reserved1[3];
+	u32	CurrentISR;		/* interrupt vector address of current interrupt */
+	u32	DefVectAddr;		/* default vector address			*/
+	u32	reserved2[50];
+	u32	VectAddr[NR_VEC];	/* interrupt vector address 0...NR_VEC		*/
+	u32	reserved3[48];
+	u32	VectCntl[NR_VEC];	/* vector control 0...NR_VEC			*/
+	u32	reserved4[48];
+	u32	ITCR;			/* test mode	*/
+	u32	ITIP1;			/* test mode	*/
+	u32	ITIP2;			/* test mode	*/
+	u32	ITOP1;			/* test mode	*/
+	u32	ITOP2;			/* test mode	*/
+	u32	reserved5[819];		/* empty	*/
+	u32	periphid[4];		/* Peripheral ID register bits			*/
+	u32	cellid[4];		/* PrimeCell  ID register bits			*/
+} vicRegs_t;
+
+
+/**********************************************************************
+ * Vectored Interrupt Controller Register Bit Fields
+ *********************************************************************/ 
+
+/**********************************************************************
+ * The bit fields of the following registers have implementation
+ * specific meaning, and must be defined at the implementation level.
+ *
+ * 		irqstatus	- VICIRQStatus
+ * 		fiqstatus	- VICFIQStatus
+ * 		rawintr		- VICRawIntr
+ * 		intselect	- VICIntSelect
+ * 		intenable	- VICIntEnable
+ * 		intenclear	- VICIntEnClear
+ * 		softint		- VICSoftInt
+ * 		softintclear- VICSoftIntClear
+ *
+ * The following definitions for these registers are generic,
+ * i.e., they are implementation independent. They can be used to
+ * create implementation specific macros.
+ *********************************************************************/ 
+
+/**********************************************************************
+ * VIC Interrupt Select Register Bit Fields
+ *********************************************************************/ 
+/* The following can be OR'd with the IntSelect Register to select
+ * an interrupt as FIQ. */ 
+#define VIC_INTSELECT_FIQ(n)	_BIT((n) & 0x1F)
+/* The following can be AND'd with the IntSelect Register to select
+ * an interrupt as IRQ. */ 
+#define VIC_INTSELECT_IRQ(n)	~(_BIT((n) & 0x1F))
+
+/**********************************************************************
+ * VIC Interrupt Enable, Interrupt Enable Clear Register Bit Fields
+ * VIC Soft Interrupt, Soft Interrupt Clear Register Bit Fields
+ *********************************************************************/ 
+#define VIC_INT_ENABLE(n)		_BIT((n) & 0x1F)
+#define VIC_INT_CLEAR(n)		_BIT((n) & 0x1F)
+
+/**********************************************************************
+ * VIC Protection Enable Register Bit Fields
+ *********************************************************************/ 
+#define VIC_PROTECTION		_BIT(0)
+
+/**********************************************************************
+ * VIC Vector Address Clear Register 
+ *********************************************************************/ 
+#define VIC_VECTORADDR_CLEAR	0
+
+/**********************************************************************
+ * VIC Vector Control Register Bit Fields
+ *********************************************************************/ 
+/* To revise a Vector Control Register, clear the register, then 
+ * use the SELECT macro to associate a line and enable the vector 
+ * with the same operation.
+ * The ENABLE macro is provided for completeness.
+ * Use this register to enable and disable the VECTOR feature;
+ * use the intenable register to enable the interrupt
+ * itself, and the intenclear register to clear the interrupt. */ 
+#define VIC_VECTCNTL_SELECT(n)	(_SBF(0,((n) & 0x1F)) | _BIT(5))
+#define VIC_VECTCNTL_ENABLE	_BIT(5)
+
+/**********************************************************************
+ * Vectored Interrupt Controller Test Registers
+ *********************************************************************/ 
+/**********************************************************************
+ * 	itcr	- Test Control
+ *********************************************************************/ 
+#define	VIC_ITCR_ITEN		_BIT(0)
+
+/**********************************************************************
+ *	itip1	- Test Input 1
+ *********************************************************************/ 
+#define	VIC_ITIP1_F		_BIT(6)
+#define	VIC_ITIP1_I		_BIT(7)
+
+/**********************************************************************
+ *	itop1	- Test Output 1
+ *********************************************************************/ 
+#define	VIC_ITOP1_F		_BIT(6)
+#define	VIC_ITOP1_I		_BIT(7)
+
+
+
+
+#define fixup_irq(i)	(i)
+
+#define TESTIRQ
+
+#ifdef TESTIRQ // DDD
+static unsigned int myReadCp15(void)
+{
+    unsigned int x;
+    asm ("mrc p15, 0, %0, c1, c0, 0;" : "=r"(x) : );
+    return x;
+}
+#endif
+
+
+
+static void lh79520_mask_irq( u32 irq)
+{
+    vicRegs_t *vic = (vicRegs_t *)VIC_BASE;
+    vic->IntEnClear = (1 << irq);
+}
+
+static void lh79520_unmask_irq( u32 irq)
+{
+    vicRegs_t *vic = (vicRegs_t *)VIC_BASE;
+
+#ifdef TESTIRQ
+    if (irq != 17)
+	udelay(1); // printk( "VIC unmask irq %d\n", irq);
+#endif // 0 DDD
+    vic->IntEnable = (1 << irq);
+}
+ 
+#undef TESTIRQ
+
+static __inline__ void irq_init_irq(void)
+{
+    int		irq, i;
+    vicRegs_t	*vic   = (vicRegs_t *)VIC_BASE;
+    rcpcRegs_t	*rcpc  = (rcpcRegs_t *)IO_ADDRESS( RCPC_PHYS);
+    ioconRegs_t *iocon = (ioconRegs_t *)IO_ADDRESS( IOCON_PHYS);
+
+    /* allow external interrupts to come in */
+    iocon->MiscMux =	MISCMUX_RCEII0 |
+			MISCMUX_RCEII1 |
+			MISCMUX_RCEII2;
+
+#ifdef TESTIRQ // DDD
+    printk( "irq_init_irq() cr1=%08X\n", myReadCp15());
+    printk( "vic=0x%08lX  rcpc=0x%08lX\n", (unsigned long) vic, (unsigned long) rcpc);
+    printk( "vic periph id[0-3] = 0x%X 0x%X 0x%X 0x%X\n", vic->periphid[0], vic->periphid[1], vic->periphid[2], vic->periphid[3]);
+#endif // 0 
+
+    vic->IntEnClear = 0xffffffff;			/* clear all interrupt enables	*/
+    vic->IntSelect  = 0;				/* everything generates IRQ	*/
+
+    // DDD don't want to do this !!  vic->Protection = 1;	/* allow only priviledged access */
+
+    /* disable vectored interrupts */
+    for( i = 0; i < NR_VEC; i++) {
+	vic->VectAddr[i] = 0;
+	vic->VectCntl[i] = 0;
+    }
+
+    for (irq = 0; irq < NR_IRQS; irq++) {
+	irq_desc[irq].valid     = 1;
+	irq_desc[irq].probe_ok  = 1;
+	irq_desc[irq].mask_ack	= lh79520_mask_irq;
+	irq_desc[irq].mask      = lh79520_mask_irq;
+	irq_desc[irq].unmask    = lh79520_unmask_irq;
+    }
+
+    /*
+     * External interrupts 0-2 and 6-7 are active LOW, and External
+     * interrupts 3-5 are active HIGH. <---= DDD wrong
+     */
+
+    rcpc->control   |=  RCPC_CTRL_WRTLOCK_ENABLED;		/* unlock RCPC registers */
+    barrier();
+
+    rcpc->intClear  = 0xff;					/* clear all external interrupts */
+    
+    rcpc->intConfig =   (
+			RCPC_INTCONFIG( RCPC_INT1, RCPC_INT_HLT) |	// irq 1 (ide) high level
+			RCPC_INTCONFIG( RCPC_INT2, RCPC_INT_LLT) |	// irq 2 (MARMALADE ETH) is low level
+			RCPC_INTCONFIG( RCPC_INT3, RCPC_INT_FET) |	// irq 3 (MARMALADE TS) active low
+    			RCPC_INTCONFIG( RCPC_INT4, RCPC_INT_HLT) |
+    			RCPC_INTCONFIG( RCPC_INT5, RCPC_INT_HLT) |
+    			RCPC_INTCONFIG( RCPC_INT6, RCPC_INT_LLT)
+			);
+
+    rcpc->control   &=  ~RCPC_CTRL_WRTLOCK_ENABLED;		/* lock RCPC registers   */
+    printk( "RCPC locked ->control=0x%08lX\n", (unsigned long) rcpc->control);
+    printk( "RCPC ->intConfig = 0x%08lX\n", (unsigned long) rcpc->intConfig);
+
+#if 0
+    {		// DDD test the switches
+	cpldRegs_t *cpld = (cpldRegs_t *)CPLD_BASE;
+	cpld->intr_mask = 0x1f;
+    }
+#endif
+
+    // DDD init_FIQ();
+}
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/irqs.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/irqs.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/irqs.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/irqs.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/irqs.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NR_IRQS			32
+
+
+#define	IRQ_ETHERNET	0
+#define	IRQ_CF		1
+#define	IRQ_CPLD	2
+#define	IRQ_PWM0SYNC	3
+#define	IRQ_PWM0	4
+#define	IRQ_DREQ1	5
+#define	IRQ_LCDVD10	6
+#define	IRQ_LCDVD11	7
+#define	IRQ_spare_i0	8	/* spare internal */
+#define	IRQ_spare_i1	9	/* spare internal */
+#define	IRQ_spare_i2	10	/* spare internal */
+#define	IRQ_SPEXTINT3	11
+#define	IRQ_LCD		12
+#define	IRQ_SSPTXINTR	13
+#define	IRQ_SSPRXINTR	14
+#define	IRQ_SSPRORINTR	15
+#define	IRQ_SSPINTR	16
+#define	IRQ_TIMER0	17
+#define	IRQ_TIMER1	18
+#define	IRQ_TIMER2	19
+#define	IRQ_TIMER3	20
+#define	IRQ_UART0_RX	21
+#define	IRQ_UART0_TX	22
+#define	IRQ_UART0	23
+#define	IRQ_UART1	24
+#define	IRQ_UART2	25
+#define	IRQ_DMA		26	/* all DMA channels */
+#define	IRQ_spare_i4	27	/* spare internal */
+#define	IRQ_spare_i5	28	/* spare internal */
+#define	IRQ_spare_i6	29	/* spare internal */
+#define	IRQ_RTC		30
+#define	IRQ_WDT		31
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/keyboard.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/keyboard.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/keyboard.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/keyboard.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,15 @@
+/*
+ *  linux/include/asm-arm/arch-anakin/keyboard.h
+ *
+ *  Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
+ *
+ * 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:
+ *   11-Apr-2001 TTC	Created
+ */
+#define kbd_init_hw()		do { } while (0)
+#define kbd_enable_irq()	do { } while (0)
+#define kbd_disable_irq()	do { } while (0)
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/lh7x-7seg.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/lh7x-7seg.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/lh7x-7seg.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/lh7x-7seg.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,71 @@
+/* vi: set sw=4 ts=4 ai: */
+
+#ifndef _LH79X_7SEG_H_
+#define _LH79X_7SEG_H_
+
+/**********************************************************************
+*  linux/drivers/misc/lh79x_7seg.c
+*
+*  Provide ADS_784x 7-Segment access for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License (GPL) version 2
+*  as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+/**********************************************************************
+* The sharp 7-segment display
+*
+*   _   ==   a
+*  | |  ==  f b
+*   -   ==   g
+*  | |  ==  e c
+*   -.  ==   d dot
+*
+* NOTE: The 7-segment display bars are bit-mapped.
+* NOTE: The 7-segment display bars are ACTIVE LOW.
+* 
+* NOTE: When read, the 7-segment display does not return valid data.  As a
+*       result, it is HIGHLY recommended daemons accessing the display
+*       use the provided routines which programatically track the current
+*       value of the display to simulate read functionality.  Otherwise,
+*       application access of the display will be tainted.
+*
+**********************************************************************/
+
+#define SSD_A	0x01
+#define SSD_B	0x02
+#define SSD_C	0x04
+#define SSD_D	0x08
+#define SSD_E	0x10
+#define SSD_F	0x20
+#define SSD_G	0x40
+#define SSD_DOT	0x80
+#define SSD_DP	SSD_DOT
+
+#ifdef KERNEL
+
+extern uint16_t lh79x_7seg_read_raw_display(void);
+extern u_char lh79x_7seg_read_raw_display_lsb(void);
+extern u_char lh79x_7seg_read_raw_display_msb(void);
+
+extern uint16_t lh79x_7seg_read_display(void);
+extern u_char lh79x_7seg_read_display_lsb(void);
+extern u_char lh79x_7seg_read_display_msb(void);
+
+extern void lh79x_7seg_write_raw_display(uint16_t raw_val);
+extern void lh79x_7seg_write_raw_display_lsb(u_char raw_lsb);
+extern void lh79x_7seg_write_raw_display_msb(u_char raw_msb);
+
+extern void lh79x_7seg_write_display(uint16_t val)
+extern void lh79x_7seg_write_display_lsb(u_char lsb)
+extern void lh79x_7seg_write_display_msb(u_char msb)
+extern void lh79x_7seg_write_display_str(u_char *str);
+
+#endif /* KERNEL */
+
+#endif /* _LH79X_7SEG_H_ */
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/memory.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/memory.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/memory.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/memory.h	2005-11-02 17:42:57.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/memory.h
+ *
+ * Copyright (C) 1999-2000 Nicolas Pitre <nico@cam.org>
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/config.h>
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+
+/*
+ * Physical DRAM offset is 0xc0000000 on the SA1100
+ */
+#define PHYS_OFFSET     (0x20000000UL)
+#define PHYS_OFFSET2     (0x28000000UL)         /* Phys addr of second bank of SDRAM */
+
+/*
+ * We take advantage of the fact that physical and virtual address can be the
+ * same.  The NUMA code is handling the large holes that might exist between
+ * all memory banks.
+ */
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *		address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *		to an address that the kernel can use.
+ *
+ * On the SA1100, bus addresses are equivalent to physical addresses.
+ */
+#define __virt_to_bus__is_a_macro
+#define __bus_to_virt__is_a_macro
+#define __virt_to_bus(x)	 __virt_to_phys(x)
+#define __bus_to_virt(x)	 __phys_to_virt(x)
+
+#ifdef CONFIG_DISCONTIGMEM
+/*
+ * Because of the wide memory address space between physical RAM banks on the 
+ * SA1100, it's much more convenient to use Linux's NUMA support to implement
+ * our memory map representation.  Assuming all memory nodes have equal access 
+ * characteristics, we then have generic discontiguous memory support.
+ *
+ * Of course, all this isn't mandatory for SA1100 implementations with only
+ * one used memory bank.  For those, simply undefine CONFIG_DISCONTIGMEM.
+ *
+ * The nodes are matched with the physical memory bank addresses which are 
+ * incidentally the same as virtual addresses.
+ * 
+ * 	node 0:  0xc0000000 - 0xc7ffffff
+ * 	node 1:  0xc8000000 - 0xcfffffff
+ * 	node 2:  0xd0000000 - 0xd7ffffff
+ * 	node 3:  0xd8000000 - 0xdfffffff
+ */
+
+#define NR_NODES	4
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> 27)
+
+/*
+ * Given a page frame number, convert it to a node id.
+ */
+#define PFN_TO_NID(pfn)		(((pfn) - PHYS_PFN_OFFSET) >> (27 - PAGE_SHIFT))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr)	NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
+
+/*
+ * Given a page frame number, find the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define PFN_TO_MAPBASE(pfn)	NODE_MEM_MAP(PFN_TO_NID(pfn))
+
+/*
+ * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
+ */
+#define LOCAL_MAP_NR(addr) \
+	(((unsigned long)(addr) & 0x07ffffff) >> PAGE_SHIFT)
+
+#else
+
+#define PFN_TO_NID(addr)	(0)
+
+#endif
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/param.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/param.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/param.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/param.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/param.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define HZ 100
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/rcpc.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/rcpc.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/rcpc.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/rcpc.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,222 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/rcpc.h
+ *
+ *  Copyright (C) 2001 Sharp Microelectronics of the Americas, Inc.
+ *		Camas, WA
+ *  Portions Copyright (C) 2002 Lineo, Inc.
+ *
+ * DDD
+ *
+ * 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.
+ *
+ */
+
+ 
+#ifndef RCPC_H
+#define RCPC_H
+
+/*
+ * RCPC: Reset, Clock, and Power Controller Register Structure
+ */ 
+typedef __attribute((packed)) struct {
+    u32	control;		/* control register */ 
+    u32	id;			/* identification */ 
+    u32	remap;			/* Remap Control */ 
+    u32	softReset;		/* Soft Reset */ 
+    u32	resetStatus;		/* Reset Status */ 
+    u32	resetStatusclr;		/* Reset Status Clear */ 
+    u32	HCLKPrescale;		/* HCLK Prescaler */ 
+    u32	CpuClkPrescale;		/* ARM Core Clk Prescaler */ 
+    u32	PCLKPrescale;		/* PCLK Prescaler */ 
+    u32	periphClkCtrl;		/* Peripheral Clock Ctrl */ 
+    u32	spareClkCtrl;		/* Spare Clock Ctrl */ 
+    u32	AHBClkCtrl;		/* AHB Clock Ctrl */ 
+    u32	periphClkSel;		/* Peripheral Clock Select*/
+    u32	spareClkSel;		/* Spare Clock Select */
+    u32	PWM0Prescale;		/* PWM 0 Prescaler*/
+    u32	PWM1Prescale;		/* PWM 1 Prescaler*/
+    u32	spare0Prescale;		/* Spare clock 0 Prescaler*/
+    u32	spare1Prescale;		/* Spare clock 1 Prescaler*/
+    u32	spare2Prescale;		/* Spare clock 2 Prescaler*/
+    u32	spare3Prescale;		/* Spare clock 3 Prescaler*/
+    u32	spare4Prescale;		/* Spare clock 4 Prescaler*/
+    u32	spare5Prescale;		/* Spare clock 5 Prescaler*/
+    u32	spare6Prescale;		/* Spare clock 6 Prescaler*/
+    u32	spare7Prescale;		/* Spare clock 7 Prescaler*/
+    u32	spare8Prescale;		/* Spare clock 8 Prescaler*/
+    u32	spare9Prescale;		/* Spare clock 9 Prescaler*/
+    u32	spare10Prescale;	/* Spare clck 10 Prescaler*/
+    u32	spare11Prescale;	/* Spare clck 11 Prescaler*/
+    u32	spare12Prescale;	/* Spare clck 12 Prescaler*/
+    u32	spare13Prescale;	/* Spare clck 13 Prescaler*/
+    u32	spare14Prescale;	/* Spare clck 14 Prescaler*/
+    u32	spare15Prescale;	/* Spare clck 15 Prescaler*/
+    u32	intConfig;		/* Ext. Interrupt Config */
+    u32	intClear;		/* Ext. Interrupt Clear  */
+    u32	coreClkConfig;		/* ARM Core Clock Config */
+} rcpcRegs_t;
+
+
+/*
+ * RCPC Bit Fields
+ */ 
+
+/*
+ * control Register Bit Fields
+ */ 
+#define RCPC_CTRL_EP			_BIT(0)	/* Enable PLL */ 
+#define RCPC_CTRL_EX			_BIT(1)	/* Enable Internal XTAL */ 
+
+#define RCPC_CTRL_PWRDWNSEL(n)		_SBF(2,(n)) /* Power Down Mode Sel*/ 
+/* Mode Arguments to RCPC_CTRL_PWRDWNSEL(n) */ 
+#define PWRDWNSEL_ACTIVE		0
+#define PWRDWNSEL_STANDBY		1
+#define PWRDWNSEL_SLEEP			2
+#define PWRDWNSEL_STOP1			3
+#define PWRDWNSEL_STOP2			4
+
+#define RCPC_CTRL_OUTSEL(n)		_SBF(5,(n))
+/* Arguments to RCPC_CTRL_OUTSEL(n) */ 
+#define OUTSEL_CLK_INTOSC		0
+#define OUTSEL_CLK_PLL			1
+#define OUTSEL_FCLK_CPU			2
+#define OUTSEL_HCLK			3
+
+#define RCPC_CTRL_CLKSEL_PLL		_SBF(7,0)
+#define RCPC_CTRL_CLKSEL_EXT		_SBF(7,1)
+
+#define RCPC_CTRL_WRTLOCK_LOCKED	_SBF(9,0)
+#define RCPC_CTRL_WRTLOCK_ENABLED	_SBF(9,1)
+
+/**********************************************************************
+ * identification - Identification Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_ID_DEFAULT			(0x5200)
+
+/**********************************************************************
+ * remap - Remap Control Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_REMAP_SMEM0		(0)
+#define RCPC_REMAP_SDMEM0		(1)
+#define RCPC_REMAP_IMEM0		(2)
+
+/**********************************************************************
+ * softreset - Soft Reset Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_SOFTRESET_ALL		(0xDEAD)
+#define RCPC_SOFTRESET_GBL		(0xDEAC)
+
+/**********************************************************************
+ * resetstatus, resetstatusclr - Reset Status Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_RESET_STATUS_EXT		_BIT(0)
+#define RCPC_RESET_STATUS_WDTO		_BIT(1)
+
+/**********************************************************************
+ * hclkPrescale - HCLK Prescaler Register Bit Fields
+ * cpuclkPrescale - ARM Core Clock Prescaler Register Bit Fields
+ * pclkPrescale - PCLK Prescaler Register Bit Fields
+ * pwm0Prescale - PWM0 Prescaler Register Bit Fields
+ * pwm1Prescale - PWM1 Prescaler Register Bit Fields
+ * sparePrescale - Spare Prescaler Register Bit Fields
+ * Note: not all constants are applicable to all registers.
+ * 	See Reference.
+ *********************************************************************/ 
+#define RCPC_PRESCALER_DIV1		_SBF(0,0)
+#define RCPC_PRESCALER_DIV2		_SBF(0,1)
+#define RCPC_PRESCALER_DIV4		_SBF(0,2)
+#define RCPC_PRESCALER_DIV6		_SBF(0,3)
+#define RCPC_PRESCALER_DIV8		_SBF(0,4)
+#define RCPC_PRESCALER_DIV16		_SBF(0,8)
+#define RCPC_PRESCALER_DIV30		_SBF(0,15)
+#define RCPC_PRESCALER_DIV32		_SBF(0,16)
+#define RCPC_PRESCALER_DIV64		_SBF(0,32)
+#define RCPC_PRESCALER_DIV128		_SBF(0,64)
+#define RCPC_PRESCALER_DIV256		_SBF(0,128)
+#define RCPC_PRESCALER_DIV65534		(0xFFFF)
+
+/**********************************************************************
+ * periphclkctrl - Peripheral Clock Control Register Bit Fields
+ * spareclkctrl - Spare Clock Control Register Bit Fields
+ * ahbclkctrl - AHB Clock Control Register Bit Fields
+ * Writing a "0" to a bit in these registers enables the
+ * 	corresponding clock
+ *********************************************************************/ 
+#define RCPC_CLKCTRL_U0_DISABLE		_BIT(0)
+#define RCPC_CLKCTRL_U1_DISABLE		_BIT(1)
+#define RCPC_CLKCTRL_U2_DISABLE		_BIT(2)
+#define RCPC_CLKCTRL_CT0_DISABLE	_BIT(3)
+#define RCPC_CLKCTRL_CT1_DISABLE	_BIT(4)
+#define RCPC_CLKCTRL_CT2_DISABLE	_BIT(5)
+#define RCPC_CLKCTRL_CT3_DISABLE	_BIT(6)
+#define RCPC_CLKCTRL_PWM0_DISABLE	_BIT(7)
+#define RCPC_CLKCTRL_PWM1_DISABLE	_BIT(8)
+#define RCPC_CLKCTRL_RTC_DISABLE	_BIT(9)
+#define RCPC_CLKCTRL_SPARE_DISABLE(f)	_BIT(f)
+
+#define RCPC_SPARE_CLKCTRL_SSPCLK_DISABLE	_BIT(1)
+#define RCPC_SPARE_CLKCTRL_LCDCLK_DISABLE	_BIT(0)
+
+#define RCPC_CLKCTRL_DMAC_DISABLE	_BIT(0)
+#define RCPC_CLKCTRL_HCLKSP0_DISABLE	_BIT(1)
+
+/**********************************************************************
+ * periphclksel - Peripheral Clock Select Register Bit Fields
+ * Writing a "0" to U0-U2 in this register enables the
+ * 	XTAL Oscillator as the clock source
+ * Writing a "0" to CT0-CT3 in this register enables the
+ * 	HCLK as the clock source
+ *********************************************************************/ 
+#define RCPC_PCLKSEL_U0_EXT		_BIT(0)	/* U0 Clock Source */ 
+#define RCPC_PCLKSEL_U1_EXT		_BIT(1)	/* U1 Clock Source */ 
+#define RCPC_PCLKSEL_U2_EXT		_BIT(2)	/* U2 Clock Source */ 
+#define RCPC_PCLKSEL_CT0_EXT		_BIT(3)	/* CT0 Clock Source */ 
+#define RCPC_PCLKSEL_CT1_EXT		_BIT(4)	/* CT1 Clock Source */ 
+#define RCPC_PCLKSEL_CT2_EXT		_BIT(5)	/* CT2 Clock Source */ 
+#define RCPC_PCLKSEL_CT3_EXT		_BIT(6)	/* CT3 Clock Source */ 
+#define RCPC_PCLKSEL_RTC_32		0	/* RTC Clock Source 32KHz */ 
+#define RCPC_PCLKSEL_RTC_EXT		_SBF(7,2) /* RTC Clock Source Ext */
+
+/**********************************************************************
+ * spareclksel - Peripheral Clock Select Register Bit Fields
+ * Writing a "0" to a bit in this register enables the
+ * 	HCLK as the clock source
+ *********************************************************************/ 
+#define RCPC_SCLKSEL_SP(n)		_SBF((n),1) /* SP2 - SP15 */ 
+#define RCPC_SCLKSEL_SSPCLK		_BIT(1)     /* SSP Clock External */ 
+#define RCPC_SCLKSEL_LCDCLK		_BIT(0)     /* LCD Clock External */ 
+
+/**********************************************************************
+ * intconfig - External Interrupt Configuration Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_INTCONFIG(f,v)		_SBF((f),(v))
+/* RCPC_INTCONFIG arguments for 'f' parameter */ 
+#define RCPC_INT0			0
+#define RCPC_INT1			2
+#define RCPC_INT2			4
+#define RCPC_INT3			6
+#define RCPC_INT4			8
+#define RCPC_INT5			10
+#define RCPC_INT6			12
+#define RCPC_INT7			14
+/* RCPC_INTCONFIG arguments for 'v' parameter */ 
+#define RCPC_INT_LLT			0	/* Low Level Trigger */ 
+#define RCPC_INT_HLT			1	/* High Level Trigger */ 
+#define RCPC_INT_FET			2	/* Falling Edge Trigger */ 
+#define RCPC_INT_RET			3	/* Rising Edge Trigger */ 
+
+/**********************************************************************
+ * intclear - External Interrupt Clear Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_INTCLEAR(n)		_BIT(n)	/* Clear Edge Interrupt 'n' */ 
+
+/**********************************************************************
+ * coreclkconfig - Core Clock Configuration Register Bit Fields
+ *********************************************************************/ 
+#define RCPC_CCC_STDASYNCH		0 /* Standard Mode, Asynch operation */
+#define RCPC_CCC_FASTBUS		1 /* Fast Bus Extension Mode */
+#define RCPC_CCC_STDSYNCH		2 /* Standard Mode, Synch operation */
+
+#endif // RCPC_H
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/serial.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/serial.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/serial.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/serial.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,34 @@
+/*
+ * linux/include/asm-arm/arch-lh79520/serial.h
+ *
+ * Copyright (c) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/*
+ * This assumes you have a 14.7456 MHz clock for your UART.
+ */
+#define BASE_BAUD	(14745600 / 16)
+
+/*
+ * Standard COM flags
+ */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define RS_TABLE_SIZE 2
+
+#define STD_SERIAL_PORT_DEFNS		\
+	/* MAGIC UART CLK   PORT       IRQ     FLAGS */			\
+	{ 0, BASE_BAUD, UART0_BASE, IRQ_UART0, STD_COM_FLAGS },  /* ttyAM0 */ \
+	{ 0, BASE_BAUD, UART1_BASE, IRQ_UART1, STD_COM_FLAGS },  /* ttyAM0 */ \
+	{ 0, BASE_BAUD, UART2_BASE, IRQ_UART2, STD_COM_FLAGS },  /* ttyAM1 */ \
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/smc_pl090.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/smc_pl090.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/smc_pl090.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/smc_pl090.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/smc_pl090.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ *
+ *      This file contains the structure definitions and manifest
+ *      constants for ARM IP component:
+ *      	Static Memory Controller PrimeCell PL090
+ *
+ *	References:
+ *		(1) ARM PrimeCell Static Memory Controller (PL090)
+ *		Technical Reference Manual, ARM DDI 0160C.
+ *		(2) ARM Isis Technical Reference Manual, System on Chip Group,
+ *		ARM SC063-TRM-0001-B
+ *
+ *	COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
+ *		CAMAS, WA
+ */
+
+#ifndef SMC_PL090_H
+#define SMC_PL090_H
+
+#ifndef _BIT
+#define _BIT(n)	(1 << (n))
+#endif
+
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+
+/*
+ * Static Memory Controller Module Register Structure
+ */ 
+typedef struct {
+	volatile unsigned int	bcr0;	 /* Configuration for bank 0 */ 
+	volatile unsigned int	bcr1;	 /* Configuration for bank 1 */ 
+	volatile unsigned int	bcr2;	 /* Configuration for bank 2 */ 
+	volatile unsigned int	bcr3;	 /* Configuration for bank 3 */ 
+	volatile unsigned int	bcr4;	 /* Configuration for bank 4 */ 
+	volatile unsigned int	bcr5;	 /* Configuration for bank 5 */ 
+	volatile unsigned int	bcr6;	 /* Configuration for bank 6 */ 
+	volatile unsigned int	bcr7;	 /* Configuration for bank 7 */ 
+} smcRegs_t;
+
+/*
+ * Static Memory Controller Bit Field constants
+ */ 
+#define IDCY(n)		_SBF(0,((n)&0x0F))	/* Idle Cycle Time */ 
+#define WST1(n)		_SBF(5,((n)&0x1F))	/* Wait State 1 */ 
+#define RBLE(n)		_SBF(10,((n)&0x01))	/* Read Byte Lane Enable */ 
+#define WST2(n)		_SBF(11,((n)&0x1F))	/* Wait State 2 */ 
+#define BUSERR		_BIT(24)			/* Bus Transfer Error Flag */ 
+#define WPERR		_BIT(25)			/* Write Protect Error Flag */ 
+#define WP			_BIT(26)			/* Write Protect */ 
+#define BM			_BIT(27)			/* Burst Mode */ 
+#define MW8			_SBF(28,0)			/* Memory width 8 bits */ 
+#define MW16		_SBF(28,1)			/* Memory width 16 bits */ 
+#define MW32		_SBF(28,2)			/* Memory width 32 bits */ 
+#define ATNONE		_SBF(30,0)			/* No Retry */ 
+#define ATEVERY		_SBF(30,2)			/* Retry after every access */
+#define ATAFTER4	_SBF(30,3)			/* Retry after 4 accesses */
+
+#endif /* SMC_PL090_H */ 
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/ssp_lh7x.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/ssp_lh7x.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/ssp_lh7x.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/ssp_lh7x.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,159 @@
+/* vi: set sw=4 ts=4 ai: */
+
+/**********************************************************************
+*  linux/include/asm-arm/arch-lh79520/ssp_lh7x.h
+*
+*  Provide SSP (Synchronous Serial Port) types & definitions
+*  for LH7x EVB boards
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License (GPL) version 2
+*  as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+#ifndef _SSP_LH7X_h
+#define _SSP_LH7X_h
+
+//#define SSP_BASE	SSP_PHYS
+
+/*********************************************************************
+* Synchronous Serial Port Registers
+*********************************************************************/ 
+#define SSPCR0		(SSP_BASE+0x00)	/* Control reg. 0 */
+#define SSPCR1		(SSP_BASE+0x04)	/* Control reg. 1 */
+#define SSPDR		(SSP_BASE+0x08)	/* Receive FIFO (Read)*/
+									/* Transmit FIFO data reg. (Write)*/
+#define SSPSR		(SSP_BASE+0x0C)	/* Status Reg. */
+#define SSPCPSR		(SSP_BASE+0x10)	/* Clock prescale reg. */
+#define SSPIIR		(SSP_BASE+0x14)	/* Interrupt identification reg. (Read) */
+#define SSPICR		SSPIIR			/* Interrupt clear reg. (Write) */
+/*
+* RESERVED:
+*	0x18 - 0x3C
+*	0x40 - 0x90		(For test purposes)
+*	0x94 - 0xFF
+*/
+
+/*********************************************************************
+* Synchronous Serial Port Register Structure
+*********************************************************************/ 
+typedef struct {
+	volatile unsigned int	cr0;
+	volatile unsigned int	cr1;
+	volatile unsigned int	dr;
+	volatile unsigned int	sr;
+	volatile unsigned int	cpsr;
+	union {
+		volatile unsigned int	iir;
+		volatile unsigned int	icr;
+	} u;
+	volatile unsigned int	reservedssp[58];
+} sspRegs_t;
+
+/*
+* To use the structure, declare the following in your source
+*	static sspRegs_t *ssp = (sspRegs_t *)SSP_BASE;
+*/
+
+/*********************************************************************
+* A couple of macros we use here...
+*********************************************************************/ 
+#ifndef _BIT
+#define _BIT(n) (1 << (n))
+#endif
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+#ifndef _BITMASK
+#define _BITMASK(field_width) ( _BIT(field_width) - 1)
+#endif
+
+/*********************************************************************
+* Synchronous Serial Port Bit Fields
+*********************************************************************/ 
+
+/*********************************************************************
+* Control 0 Register Bit Fields
+*********************************************************************/ 
+/* Valid range for argument to SSP_CR0_DSS(n) is [4-16] */ 
+#define	SSP_CR0_DSS(n)	_SBF(0,(n)-1)	/* Data Size Select */ 
+#define	SSP_CR0_FRF_MOT	_SBF(4,0)	/* Motorola SPI frame */ 
+#define	SSP_CR0_FRF_TI	_SBF(4,1)	/* TI synchronous serial frame */ 
+#define	SSP_CR0_FRF_NS	_SBF(4,2)	/* National Microwire frame */ 
+#define SSP_CR0_SPO		_BIT(6)		/* SPI Polarity */ 
+#define SSP_CR0_SPH		_BIT(7)		/* SPI Polarity */ 
+#define SSP_CR0_SCR(n)	_SBF(8,(n))	/* Serial Clock Rate */ 
+
+/*********************************************************************
+* Control 1 Register Bit Fields
+*********************************************************************/ 
+#define SSP_CR1_RIE		_BIT(0)		/* RX FIFO interrupt enable */ 
+#define SSP_CR1_TIE		_BIT(1)		/* TX FIFO interrupt enable */
+#define SSP_CR1_RORIE	_BIT(2)		/* RX FIFO overrun int. enable */ 
+#define SSP_CR1_LBM		_BIT(3)		/* Loop back mode */ 
+#define SSP_CR1_SSE		_BIT(4)		/* Synchronous serial port enable */ 
+
+/*********************************************************************
+* Status Register Bit Fields
+*********************************************************************/ 
+#define SSP_SR_TFE		_BIT(0)		/* TX FIFO Empty */ 
+#define SSP_SR_TNF		_BIT(1)		/* TX FIFO not full */
+#define SSP_SR_RNE		_BIT(2)		/* RX FIFO not empty */ 
+#define SSP_SR_RFF		_BIT(3)		/* RX FIFO full */ 
+#define SSP_SR_BSY		_BIT(4)		/* Busy flag */ 
+
+/*********************************************************************
+* Clock Prescale Divisor Register Bit Fields
+*********************************************************************/ 
+#define	SSP_CPSR_CPDVSR(n) _SBF(0,(n)&0xFE) /* Clock prescale divisor */
+
+/*********************************************************************
+* Interrupt Identification / Interrupt Clear Register Bit Fields
+* Note: ARM Reference conflicts on the definition of these bits
+* and the usage of the registers. Verify before using these
+* definitions.
+*********************************************************************/ 
+#define SSP_IIR_RIS		_BIT(0)		/* TX FIFO Empty */ 
+#define SSP_IIR_TIS		_BIT(1)		/* TX FIFO not full */
+#define SSP_IIR_RORIS	_BIT(2)		/* RX FIFO overrun int. status */ 
+
+/*********************************************************************
+* The TouchScreen communication BPS (bits per second)
+*********************************************************************/ 
+#define LH7x_TS_BPS 100000
+
+/*********************************************************************
+* Misc.
+*********************************************************************/ 
+#define SSP_MAX_TIMEOUT 0xffff
+#define RCPC_SSP_PRESCALE_MAX 256
+#define SSP_PRESCALE_MAX 254
+#define SSP_PRESCALE_MIN 2
+#define SSP_DIVIDER_MAX 256
+
+/* Define values to associate with the device we are conencted to */
+#define SSP_INVALID_DEVICE	0xFF
+#define SSP_EEPROM			0x00
+#define SSP_TOUCHSCREEN		0x01
+
+/*********************************************************************
+* Context Structure Definition
+*********************************************************************/ 
+typedef struct sspContext_t sspContext_t;
+struct sspContext_t {
+	wait_queue_head_t  *irq_wait_ptr;
+	int irq_state;
+	int ssp_dev_sel;		// cpld->ssp_dev_sel is not readable !!!
+	int ts_txTimeout;
+	int ts_rxTimeout;
+	int ee_txTimeout;
+	int ee_rxTimeout;
+	int haveIrq;
+	spinlock_t sspLock;
+};
+
+#endif /* _SSP_LH7X_h */
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/system.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/system.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/system.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/system.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/system.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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-Jan-2001 Duck	Created
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void
+arch_idle(void)
+{
+}
+
+static inline void
+arch_reset(char mode)
+{
+	cpu_reset(0);
+}
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/time.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/time.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/time.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/time.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/time.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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-Jan-2002 Duck	Created
+ */
+
+#ifndef __ASM_ARCH_TIME_H
+#define __ASM_ARCH_TIME_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/rcpc.h>
+
+/*
+ * Dual Timer Module Register Structure
+ * The LH79520 has two of these.
+ */ 
+typedef struct {
+	unsigned int	Timer1Load;
+	unsigned int	Timer1Value;
+	unsigned int	Timer1Control;
+	unsigned int	Timer1Clear;
+	unsigned int	Timer1Test;
+	unsigned int	reservedtmr1[3];
+	unsigned int	Timer2Load;
+	unsigned int	Timer2Value;
+	unsigned int	Timer2Control;
+	unsigned int	Timer2Clear;
+	unsigned int	Timer2Test;
+	unsigned int	reservedtmr2[3];
+} timerRegs_t;
+
+
+/*
+ * Timer Control Register Bit Field constants
+ * All other bits in the Timer Control Register must be written as
+ * zero
+ */ 
+#define TMRCTRL_ENABLE		_SBF(7,1)
+#define TMRCTRL_DISABLE		_SBF(7,0)
+#define TMRCTRL_MODE_PERIODIC	_SBF(6,1)
+#define TMRCTRL_MODE_FREERUN	_SBF(6,0)
+#define TMRCTRL_CASCADE_ENABLE	_SBF(4,1)
+#define TMRCTRL_CASCADE_DISABLE	_SBF(4,0)
+#define TMRCTRL_PRESCALE1	_SBF(2,0)
+#define TMRCTRL_PRESCALE16	_SBF(2,1)
+#define TMRCTRL_PRESCALE256	_SBF(2,2)
+
+/*
+ * what to load the timer with
+ * it's 14.745600 MHz * 21 (PLL multiplier) / 6 (PCLK prescalar) / 16 (TIMER_PRESCALE) / HZ
+ * this gives us timerLoad=32256  for Hz=100
+ */
+#define TIMER_PRESCALE		16
+
+static void
+timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	timerRegs_t	*mod1Timer = (timerRegs_t *)IO_ADDRESS( TIMER0_PHYS);
+
+	mod1Timer->Timer1Clear = 1;			/* clear interrupt */
+
+	do_timer(regs);
+}
+
+
+static inline void
+setup_timer(void)
+{
+	rcpcRegs_t	*rcpc = (rcpcRegs_t *)IO_ADDRESS( RCPC_PHYS);
+	timerRegs_t	*mod1Timer = (timerRegs_t *)IO_ADDRESS( TIMER0_PHYS),   /* first timer module */
+	    		*mod2Timer = (timerRegs_t *)IO_ADDRESS( TIMER1_PHYS);   /* second timer module */
+	u32		timerLoad;
+
+	timerLoad = hclkfreq_get() / TIMER_PRESCALE / HZ;
+	printk( "setup_timer(): timerLoad=%d\n", timerLoad);
+
+	/* stop all timers */
+	mod1Timer->Timer1Control = 0;
+	mod1Timer->Timer2Control = 0;
+	mod2Timer->Timer1Control = 0;
+	mod2Timer->Timer2Control = 0;
+
+	/* enable clock to first timer */
+	rcpc->control       |= RCPC_CTRL_WRTLOCK_ENABLED;		/* unlock RCPC registers */
+	barrier();
+
+	rcpc->periphClkCtrl &= ~RCPC_CLKCTRL_CT0_DISABLE;
+	rcpc->control       &= ~RCPC_CTRL_WRTLOCK_ENABLED;		/* lock RCPC registers   */
+	
+	/* setup the FRC in the first timer in the first module.  */
+	mod1Timer->Timer1Load    = timerLoad;
+
+	mod1Timer->Timer1Control = TMRCTRL_ENABLE |
+				   TMRCTRL_MODE_PERIODIC |
+				   TMRCTRL_PRESCALE16;
+
+
+
+	timer_irq.handler = timer_interrupt;
+	timer_irq.flags = SA_INTERRUPT;
+	setup_arm_irq( IRQ_TIMER0, &timer_irq);
+}
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/timex.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/timex.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/timex.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/timex.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/timex.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * On the LH79520, the DDD
+ */
+#define CLOCK_TICK_RATE		(PLL_CLOCK / 6 / 16)
+
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/uncompress.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/uncompress.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/uncompress.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/uncompress.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/uncompress.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define UART_DR	(*(volatile unsigned char *)0xfffc1000)
+#define UART_FR	(*(volatile unsigned short *)0xfffc1018)
+
+#define UARTFR_TXFE	0x80
+
+/*
+ * This does not append a newline
+ */
+static void
+puts( const char *s)
+{
+	while( *s) {
+		while( (UART_FR & UARTFR_TXFE) == 0)		/* wait for room in the tx FIFO */
+			;
+
+		UART_DR = *s;							/* ship a char */
+
+		if (*s == '\n') {						/* it's a new line */
+			while( (UART_FR & UARTFR_TXFE) == 0)	/* wait for room in the tx FIFO */
+				;
+
+			UART_DR = '\r';						/* ship a carriage return		*/
+		}
+		s++;
+	}
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff -urN linux-2.4.26/include/asm-arm/arch-lh79520/vmalloc.h linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/vmalloc.h
--- linux-2.4.26/include/asm-arm/arch-lh79520/vmalloc.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/arch-lh79520/vmalloc.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-lh79520/vmalloc.h
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.26/include/asm-arm/hardware/cradle.h linux-2.4.26-vrs1-lnode80/include/asm-arm/hardware/cradle.h
--- linux-2.4.26/include/asm-arm/hardware/cradle.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/hardware/cradle.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ * cradle.h
+ */
+#ifndef _INCLUDE_CRADLE_H_
+#define _INCLUDE_CRADLE_H_
+
+#define CRADLE_MAJOR  254
+
+#define CRADLE_GET_DOCKING_STATE_IOCTL 0
+
+#define	CRADLE_DOCKED_STATE	0
+#define CRADLE_UNDOCKED_STATE	1
+
+#endif
diff -urN linux-2.4.26/include/asm-arm/hardware/lcd_contrast.h linux-2.4.26-vrs1-lnode80/include/asm-arm/hardware/lcd_contrast.h
--- linux-2.4.26/include/asm-arm/hardware/lcd_contrast.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/hardware/lcd_contrast.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,30 @@
+/* 
+    lcd_contrast.h 
+
+
+These values are intended to be passed to the 
+pl110fb lcd driver. The driver was modified to control
+a Maxim contrast controller to make life easy. 
+
+*/
+
+
+#ifndef _LCD_CONTRAST_
+#define _LCD_CONTRAST_
+
+
+//ioctls
+#define LCD_CONTRAST_RESET 	0
+#define LCD_CONTRAST_INC   	1
+#define LCD_CONTRAST_DEC   	2
+
+#define LCD_CONTRAST_PRESET	3	
+// above takes parameters (0 - 63)
+// 0 - reset 
+// 31 - highest
+// 63 - lowest
+
+
+#endif //__LCD_CONTRAST__
+
+
diff -urN linux-2.4.26/include/asm-arm/hardware/serial_amba_pl011.h linux-2.4.26-vrs1-lnode80/include/asm-arm/hardware/serial_amba_pl011.h
--- linux-2.4.26/include/asm-arm/hardware/serial_amba_pl011.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/asm-arm/hardware/serial_amba_pl011.h	2005-11-02 17:37:32.000000000 -0400
@@ -0,0 +1,114 @@
+/*
+ *  linux/include/asm-arm/hardware/serial_amba_pl011.h
+ *
+ *  Internal header file for AMBA PrimeCell PL011 serial ports
+ *
+ *  Copyright (C) 2002 Lineo, Inc.
+ *
+ *  Based on serial_amba.h, which is:
+ *    Copyright (C) ARM Limited
+ *    Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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
+ */
+#ifndef ASM_ARM_HARDWARE_SERIAL_AMBA_PL011_H
+#define ASM_ARM_HARDWARE_SERIAL_AMBA_PL011_H
+
+/* -------------------------------------------------------------------------------
+ *  From AMBA UART (PL011) TRM
+ * -------------------------------------------------------------------------------
+ *  UART Register Offsets.
+ */
+#define AMBA_UARTDR                     0x00	 /*  Data read or written from the interface. */
+#define AMBA_UARTRSR                    0x04	 /*  Receive status register (Read). */
+#define AMBA_UARTECR                    0x04	 /*  Error clear register (Write). */
+
+
+#define AMBA_UARTFR                     0x18	 /*  Flag register (Read only). */
+#define AMBA_UARTILPR                   0x20	 /*  IrDA low power counter register. */
+#define AMBA_UARTIBRD                   0x24	 /*  Integer baud rate divisor. */
+#define AMBA_UARTFBRD                   0x28	 /*  Fractional baud rate divisor. */
+#define AMBA_UARTLCR_H                  0x2C	 /*  Line control register, high byte. */
+#define AMBA_UARTCR                     0x30	 /*  Control register. */
+#define AMBA_UARTIFLS                   0x34	 /*  Interrupt FIFO level select. */
+#define AMBA_UARTIMSC                   0x38	 /*  Interrupt Mask Set/Clear. */
+#define AMBA_UARTRIS                    0x3C	 /*  Raw Interrupt status register (Read). */
+#define AMBA_UARTMIS                    0x40	 /*  Masked Interrupt status register (Read). */
+#define AMBA_UARTICR                    0x44	 /*  Interrupt clear register (Write). */
+
+#define AMBA_UARTRSR_OE                 0x0800   /*  Overrun error */
+#define AMBA_UARTRSR_BE                 0x0400   /*  Break error   */
+#define AMBA_UARTRSR_PE                 0x0200   /*  Parity error  */
+#define AMBA_UARTRSR_FE                 0x0100   /*  framing error */
+
+#define AMBA_UARTFR_TXFF                0x20     /* Tx FIFO full   */
+#define AMBA_UARTFR_RXFE                0x10     /* Rx FIFO empty  */
+#define AMBA_UARTFR_BUSY                0x08     /* busy xmitting  */
+#define AMBA_UARTFR_DCD                 0x04
+#define AMBA_UARTFR_DSR                 0x02
+#define AMBA_UARTFR_CTS                 0x01
+#define AMBA_UARTFR_TMSK                (AMBA_UARTFR_TXFF + AMBA_UARTFR_BUSY)
+ 
+/* Interrupt Mask Set/Clear register bits */
+#define AMBA_UARTIMSC_RTIM              0x40	/* Rx timeout interrupt mask */
+#define AMBA_UARTIMSC_TXIM              0x20	/* Tx interrupt mask */
+#define AMBA_UARTIMSC_RXIM              0x10	/* Rx interrupt mask */
+#define AMBA_UARTIMSC_DSRMIM            0x08	/* DSR Modem Interrupt mask */
+#define AMBA_UARTIMSC_DCDMIM            0x04	/* DCD Modem Interrupt mask */
+#define AMBA_UARTIMSC_CTSMIM            0x02	/* CTS Modem Interrupt mask */
+#define AMBA_UARTIMSC_RIMIM             0x01	/* RI  Modem Interrupt mask */
+/* all modem mask bits */
+#define AMBA_UARTIMSC_Modem             (AMBA_UARTIMSC_DSRMIM |AMBA_UARTIMSC_DCDMIM | \
+	                                 AMBA_UARTIMSC_CTSMIM |AMBA_UARTIMSC_RIMIM)
+
+
+
+/* Control Register bits */
+
+#define AMBA_UARTCR_RTS                 0x800    /* nRTS */
+#define AMBA_UARTCR_DTR                 0x400    /* nDTR */
+#define AMBA_UARTCR_RXE                 0x200    /* Rx enable */
+#define AMBA_UARTCR_TXE                 0x100    /* Tx enable */
+#define AMBA_UARTCR_LBE                 0x080    /* Loopback enable */
+#define AMBA_UARTCR_SIRLP               0x004    /* IR SIR Low Power Mode */
+#define AMBA_UARTCR_SIREN               0x002    /* IR SIR enable */
+#define AMBA_UARTCR_UARTEN              0x001    /* UART enable */
+ 
+#define AMBA_UARTLCR_H_WLEN_8           0x60
+#define AMBA_UARTLCR_H_WLEN_7           0x40
+#define AMBA_UARTLCR_H_WLEN_6           0x20
+#define AMBA_UARTLCR_H_WLEN_5           0x00
+#define AMBA_UARTLCR_H_FEN              0x10
+#define AMBA_UARTLCR_H_STP2             0x08
+#define AMBA_UARTLCR_H_EPS              0x04
+#define AMBA_UARTLCR_H_PEN              0x02
+#define AMBA_UARTLCR_H_BRK              0x01
+
+/* Raw/Masked Interrupt Status Register bits*/
+#define AMBA_UART_IS_RT                 0x40
+#define AMBA_UART_IS_TX                 0x20
+#define AMBA_UART_IS_RX                 0x10
+#define AMBA_UART_IS_DSR                0x08
+#define AMBA_UART_IS_DCD                0x04
+#define AMBA_UART_IS_CTS                0x02
+#define AMBA_UART_IS_RI                 0x01
+#define AMBA_UART_IS_MI                 (AMBA_UART_IS_DSR | AMBA_UART_IS_DCD | \
+	                                 AMBA_UART_IS_CTS | AMBA_UART_IS_RI )
+
+#define AMBA_UARTRSR_ANY	(AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE)
+#define AMBA_UARTFR_MODEM_ANY	(AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS)
+
+#endif /*  ASM_ARM_HARDWARE_SERIAL_AMBA_PL011_H */
+
diff -urN linux-2.4.26/include/lh79520.h linux-2.4.26-vrs1-lnode80/include/lh79520.h
--- linux-2.4.26/include/lh79520.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/lh79520.h	2005-11-02 17:37:33.000000000 -0400
@@ -0,0 +1,340 @@
+/*
+ * lh79520.h: LH79520 specific defines
+ *
+ * Copyright (C) 2002 Lineo, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef BLOB_ARCH_LH79520_H
+#define BLOB_ARCH_LH79520_H
+
+#ifndef _BIT
+#define _BIT(n)	(1 << (n))
+#endif
+
+#ifndef _SBF
+#define _SBF(f,v) ((v) << (f))
+#endif
+
+/* the base address were BLOB is loaded by the first stage loader */
+// #define BLOB_ABS_BASE_ADDR	(0x60000000)	// for gdb bootstrap in SRAM
+#define BLOB_ABS_BASE_ADDR	(0x20200400)
+
+
+/* where do various parts live in RAM */
+#define BLOB_RAM_BASE		(0x20100000)
+#define KERNEL_RAM_BASE		(0x20008000)
+#define PARAM_RAM_BASE		(0x20110000)
+#define RAMDISK_RAM_BASE	(0x20400000)
+#define RAMDISK_VIRTUAL_BASE	(0xC0400000)	// kernel virtual address of where ramdisk will be
+
+
+/* and where do they live in flash */
+#define BLOB_FLASH_BASE		(0x00000000)
+#define BLOB_FLASH_LEN		(128 * 1024)				// 128 KB for blob
+
+#define PARAM_FLASH_BASE	(BLOB_FLASH_BASE + BLOB_FLASH_LEN)
+#define PARAM_FLASH_LEN		(64 * 1024)				//  64 KB for params
+
+#define KERNEL_FLASH_BASE	(PARAM_FLASH_BASE + PARAM_FLASH_LEN)
+#define KERNEL_FLASH_LEN	(1024 * 1024 - \
+				(BLOB_FLASH_LEN + PARAM_FLASH_LEN))	//  1 MB - (BLOB + PARAM) for kernel
+
+#define RAMDISK_FLASH_BASE	(KERNEL_FLASH_BASE + KERNEL_FLASH_LEN)
+#define RAMDISK_FLASH_LEN	(3 * 1024 * 1024)			//  3 MB for ramdisk
+
+#define PARAM_START		PARAM_FLASH_BASE
+#define PARAM_LEN		PARAM_FLASH_LEN
+
+/* the position of the kernel boot parameters */
+#define BOOT_PARAMS		(0x20000100)
+
+
+/* the size (in kbytes) to which the compressed ramdisk expands */
+#define RAMDISK_SIZE		(8 * 1024)
+
+
+/* Memory configuration */
+
+/**********************************************************************
+ * AHB BASES
+ *********************************************************************/
+#define AHB_PHYS		(0xFFFF0000)
+#define VIC_PHYS_MIRROR		(AHB_PHYS + 0x0000)
+#define SMC_REGS_BASE		(AHB_PHYS + 0x1000)
+#define SDRAM_REGS_BASE		(AHB_PHYS + 0x2000)
+#define LCD_BASE		(AHB_PHYS + 0x4000)
+#define VIC_PHYS		(AHB_PHYS + 0xF000)
+
+/**********************************************************************
+ * APB BASES
+ *********************************************************************/
+#define APB_PHYS		(0xFFFC0000)
+#define UART0_BASE		(APB_PHYS + 0x00000)
+#define UART1_BASE		(APB_PHYS + 0x01000)
+#define UART2_BASE		(APB_PHYS + 0x02000)
+#define PWM_BASE		(APB_PHYS + 0x03000)
+#define TIMER0_BASE		(APB_PHYS + 0x04000)
+#define TIMER1_BASE		(APB_PHYS + 0x05000)
+#define SSP_BASE		(APB_PHYS + 0x06000)
+#define GPIO3_BASE		(APB_PHYS + 0x1C000)
+#define GPIO2_BASE		(APB_PHYS + 0x1D000)
+#define GPIO1_BASE		(APB_PHYS + 0x1E000)
+#define GPIO0_BASE		(APB_PHYS + 0x1F000)
+#define RTC_BASE		(APB_PHYS + 0x20000)
+#define DMAC_BASE		(APB_PHYS + 0x21000)
+#define RCPC_BASE		(APB_PHYS + 0x22000)
+#define WDTIMER_BASE		(APB_PHYS + 0x23000)
+#define LCDICP_BASE		(APB_PHYS + 0x24000)
+#define IOCON_BASE		(APB_PHYS + 0x25000)
+
+#define SDRAM_MEM_BASE		0x20000000
+#define SMC_MEM_BASE		(0x40000000)
+#define INTERNAL_MEM_BASE	(0x60000000)
+
+
+/**********************************************************************
+ * SMC Memory Bank Address Space Bases
+ *********************************************************************/
+
+#define SMC_BANK0_BASE		(SMC_MEM_BASE + 0x00000000)
+#define SMC_BANK1_BASE		(SMC_MEM_BASE + 0x04000000)
+#define SMC_BANK2_BASE		(SMC_MEM_BASE + 0x08000000)
+#define SMC_BANK3_BASE		(SMC_MEM_BASE + 0x0C000000)
+#define SMC_BANK4_BASE		(SMC_MEM_BASE + 0x10000000)
+#define SMC_BANK5_BASE		(SMC_MEM_BASE + 0x14000000)
+#define SMC_BANK6_BASE		(SMC_MEM_BASE + 0x18000000)
+#define SMC_BANK7_BASE		(SMC_MEM_BASE + 0x1C000000)
+
+/* Flash ROM */
+#define FLASH_PHYS_BASE		0x00000000
+#define FLASH_PHYS_SIZE		0x00400000
+
+/**********************************************************************
+ * SDRAMC Memory Bank Address Space Bases
+ *********************************************************************/
+
+#define SDRAM_BANK0_BASE	(SDRAM_MEM_BASE + 0x00000000)
+#define SDRAM_BANK1_BASE	(SDRAM_MEM_BASE + 0x08000000)
+
+// WDT offsets
+#define WDT_WDCTLR_OFFSET			0x0
+
+// RCPC offsets for assembly files
+#define RCPC_CONTROL_OFFSET			0x00
+#define RCPC_REMAP_OFFSET			0x08
+#define RCPC_SOFTRESET_OFFSET			0x0C
+#define RCPC_RESETSTATUS_OFFSET			0x10
+#define RCPC_RESETSTATUS_CLEAR_OFFSET		0x14
+#define RCPC_HCLKCLK_PRESCALE_OFFSET		0x18
+#define RCPC_CPUCLK_PRESCALE_OFFSET		0x1C
+#define RCPC_PERIPHCLKCTRL_OFFSET		0x24
+#define RCPC_AHBCLKCTRL_OFFSET			0x2C
+#define RCPC_PERIPHCLKSELECT_OFFSET		0x30
+#define RCPC_CORECLKCONFIG_OFFSET		0x88
+
+#define RCPC_CPUCLK_PRESCALE_78			0x2
+#define RCPC_CPUCLK_PRESCALE_52			0x3
+#define RCPC_CPUCLK_PRESCALE_39			0x4
+#define RCPC_HCLK_PRESCALE_52			0x3
+#define RCPC_HCLK_PRESCALE_39			0x4
+#define RCPC_CPUCLK_PRESCALE_DEFAULT		RCPC_CPUCLK_PRESCALE_52
+#define RCPC_HCLK_PRESCALE_DEFAULT		RCPC_HCLK_PRESCALE_52
+//#define RCPC_CPUCLK_PRESCALE_DEFAULT		RCPC_CPUCLK_PRESCALE_78
+//#define RCPC_HCLK_PRESCALE_DEFAULT		RCPC_HCLK_PRESCALE_52
+
+/* IOCON offsets for assembly code */
+#define IOCON_MEMMUX_OFFSET			0x00
+//#define IOCON_MEMMUX_INIT			0x00003fff
+#define IOCON_MEMMUX_INIT			0x00000075
+#define IOCON_LCDMUX_OFFSET			0x04
+#define IOCON_LCDMUX_INIT			0x1f3db95d
+#define IOCON_MISCMUX_OFFSET		0x08
+#define IOCON_MISCMUX_INIT			0x0000005e
+#define IOCON_DMAMUX_OFFSET			0x0C
+#define IOCON_DMAMUX_INIT			0x00000000
+#define IOCON_UARTMUX_OFFSET		0x10
+#define IOCON_UARTMUX_INIT			0x0000000f
+#define IOCON_SSPMUX_OFFSET			0x14
+#define IOCON_SSPMUX_INIT			0x0000001c
+
+#if 0
+/* GPIO Configuration */
+#define GPIOB_DATA_OFFSET	0x000
+#define GPIOB_DATA_INIT		0x00000000
+#define GPIOB_DDR_OFFSET	0x008
+#define GPIOB_DDR_INIT		0x00000000
+#define GPIOF_DATA_OFFSET	0x000
+#define	GPIOF_DATA_INIT		0x000000DA
+#define GPIOF_DDR_OFFSET	0x008
+#define GPIOF_DDR_INIT		0x000000FA
+#define GPIOG_DATA_OFFSET	0x000
+#define	GPIOG_DATA_INIT		0x000000E0
+#define GPIOG_DDR_OFFSET	0x008
+#define GPIOG_DDR_INIT		0x000000E0
+#define GPIOH_DATA_OFFSET	0x004
+#define	GPIOH_DATA_INIT		0x00000043
+#define GPIOH_DDR_OFFSET	0x00C
+#define GPIOH_DDR_INIT		0x00000043
+#endif
+
+#define GPIOB_DATA_OFFSET	0x004
+#define GPIOB_DATA_INIT		0x00000000
+#define GPIOB_DDR_OFFSET	0x00c
+#define GPIOB_DDR_INIT		0x00000000
+#define GPIOF_DATA_OFFSET	0x004
+#define	GPIOF_DATA_INIT		0x00000008
+#define GPIOF_DDR_OFFSET	0x00C
+#define GPIOF_DDR_INIT		0x00000038
+#define GPIOG_DATA_OFFSET	0x000
+#define	GPIOG_DATA_INIT		0x000000E0
+#define GPIOG_DDR_OFFSET	0x008
+#define GPIOG_DDR_INIT		0x000000E0
+#define GPIOH_DATA_OFFSET	0x004
+#define	GPIOH_DATA_INIT		0x00000043
+#define GPIOH_DDR_OFFSET	0x00C
+#define GPIOH_DDR_INIT		0x00000043
+
+
+
+
+/* SDRAM controller offsets */
+#define SDRAM_CFG0_OFF		0
+#define	SDRAM_CFG1_OFF		4
+#define	SDRAM_REFTIMER_OFF	8
+
+#define SDRAM_INIT_NORMAL	0
+#define SDRAM_INIT_PALL		1
+#define SDRAM_INIT_MODE		2
+#define	SDRAM_INIT_NOP		3
+#define	SDRAM_BUSY		0x20		/* SDRAM Engine Status */ 
+
+
+/*
+ * Clock Indexes
+ * Caution: these indexes have to be coherent with the equivalent indexes
+ * included with associated 'C' modules
+ */
+
+#define RCPC_CLKIDX_DEFAULT	0
+#define RCPC_CLKIDX_39_39	1
+#define RCPC_CLKIDX_52_39	2
+#define RCPC_CLKIDX_52_52	3
+#define RCPC_CLKIDX_78_39	4
+#define RCPC_CLKIDX_78_52	5
+#define RCPC_CLKIDX_78_78	6
+#define RCPC_CLKIDX_10_10	7
+
+/*
+ * SDRAM Refresh timer values for various Clock Indexes
+ */
+#define REFTIMER_78		0x480
+#define REFTIMER_52		0x320
+#define REFTIMER_39		0x270
+#define REFTIMER_10		0x80
+
+
+/**********************************************************************
+ * Static Memory Controller (SMC)
+ *********************************************************************/
+#define SMC	((SMCREGS *)(SMC_REGS_BASE))
+
+/**********************************************************************
+ * SDRAM Controller (SDRAM)
+ *********************************************************************/
+#define SDRAM	((SDRAMREGS *)(SDRAM_REGS_BASE))
+
+/**********************************************************************
+ * Color LCD Controller (CLCDC)
+ *********************************************************************/
+#define CLCDC	((CLCDCREGS *)(LCD_BASE))
+
+/**********************************************************************
+ * UARTs 
+ *********************************************************************/
+#define UARTID_OFFSET	(0xFE0)
+#define UART0		((UART *)(UART0_BASE))
+#define UART1		((UART *)(UART1_BASE))
+#define UART2		((UART *)(UART2_BASE))
+#define UART0ID		((UARTID *)(UART0_BASE + UARTID_OFFSET))
+#define UART1ID		((UARTID *)(UART1_BASE + UARTID_OFFSET))
+#define UART2ID		((UARTID *)(UART2_BASE + UARTID_OFFSET))
+
+/* use this serial port */
+#define UART		((UARTREGS *)(UART0_BASE))
+#define LH_UART_NUM	0
+
+
+/**********************************************************************
+ * TIMER
+ *********************************************************************/
+#define TIMER2_OFFSET	(0x20)
+#define TIMER0		((TIMERREG *)(TIMER0_BASE))
+#define TIMER1		((volatile TIMERREG *)(TIMER0_BASE + TIMER2_OFFSET))
+#define TIMER2		((TIMERREG *)(TIMER1_BASE))
+#define TIMER3		((TIMERREG *)(TIMER1_BASE + TIMER2_OFFSET))
+
+/*
+ * base addresses of each dual timer module
+ */
+#define MOD1_TIMER	((TIMERREGS *) TIMER0_BASE)
+#define MOD2_TIMER	((TIMERREGS *) TIMER1_BASE)
+
+
+#define RCPC		((RCPCREGS *)(RCPC_BASE))	
+#define LCDICP		((LCDICPREGS *)(LCDICP_BASE))
+#define IOCON		((IOCONREGS *)(IOCON_BASE))
+#define CPLD_PHYS_BASE	SMC_BANK2_BASE
+#define CPLD 		((CPLDREGS *)(CPLD_PHYS_BASE))
+
+#define _7seg(val) \
+	{				\
+	    CPLDREGS *cpld = CPLD;	\
+	    cpld->seven_seg = (val);	\
+	}
+
+/*
+ * CPU board DIP switches
+ */
+#define DIPSW1	0x01
+#define DIPSW2	0x02
+#define DIPSW3	0x04
+#define DIPSW4	0x08
+#define DIPSW5	0x10
+#define DIPSW6	0x20
+#define DIPSW7	0x40
+#define DIPSW8	0x80
+
+/*
+ * CPU and BUS speeds, also tied to SDRAM speed
+ * NOTE: Don't change one without changing the others!!!!
+ */
+
+#if 0 // run the CPU at 52 MHz, and the bus at 52 MHz
+  #define CPU_CLK_PRESCALAR	RCPC_CPUCLK_PRESCALE_52
+  #define SDRAM_REFTIMER	REFTIMER_52
+  #define HCLK_PRESCALAR	RCPC_HCLK_PRESCALE_52
+  #define CORE_CLK_CONFIG	3			/* FastBus */
+#else // run the CPU at 78 MHz, and the Bus at 52 MHz
+  #define CPU_CLK_PRESCALAR	RCPC_CPUCLK_PRESCALE_78
+  #define SDRAM_REFTIMER	0x320 /*REFTIMER_78*/
+  #define HCLK_PRESCALAR	RCPC_HCLK_PRESCALE_52
+  #define CORE_CLK_CONFIG	0			/* std mode, async */
+#endif
+
+
+#endif // BLOB_ARCH_LH79520_H
diff -urN linux-2.4.26/include/linux/serial_core.h linux-2.4.26-vrs1-lnode80/include/linux/serial_core.h
--- linux-2.4.26/include/linux/serial_core.h	2005-11-02 16:54:26.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/linux/serial_core.h	2005-11-02 17:46:47.000000000 -0400
@@ -51,6 +51,8 @@
 #define PORT_SA1100	34
 #define PORT_UART00	35
 #define PORT_21285	37
+#define PORT_AMBA_PL011	38
+#define PORT_LH7A400	39
 
 /* Sparc type numbers.  */
 #define PORT_SUNZILOG	38
diff -urN linux-2.4.26/include/linux/verbosedebug.h linux-2.4.26-vrs1-lnode80/include/linux/verbosedebug.h
--- linux-2.4.26/include/linux/verbosedebug.h	1969-12-31 20:00:00.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/include/linux/verbosedebug.h	2005-11-02 17:37:33.000000000 -0400
@@ -0,0 +1,51 @@
+/* vi: set sw=4 ts=4 ai: */
+
+/**********************************************************************
+*  linux/include/linux/verbosedebug.h
+*
+*  Provide Verbose, Debug, and Verbose+Debug printk macros that can be
+*  enabled or disabled vi the definitions of DEBUG and VERBOSE.
+*
+*  vprintk	-- Verbose printk
+*  dprintk	-- Debug printk
+*  vdprintk	-- Verbose+Debug printk
+*
+*  Copyright (C) 2002  Lineo, Inc.
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License (GPL) version 2
+*  as published by the Free Software Foundation.
+*
+**********************************************************************/
+
+#ifndef _VerboseDebug_h
+#define _VerboseDebug_h
+
+#ifndef DRVNAME
+#	define DRVNAME ""
+#endif
+
+#ifdef VERBOSE
+#   ifdef DEBUG
+#       define vprintk(fmt,args...) {printk(DRVNAME ": " fmt, ## args);}
+#       define dprintk(fmt,args...) {printk(DRVNAME ": " fmt, ## args);}
+#       define vdprintk(fmt,args...) {printk(DRVNAME ": " fmt, ## args);}
+#   else
+#       define vprintk(fmt,args...) {printk(DRVNAME ": " fmt, ## args);}
+#       define dprintk(fmt,args...) {}
+#       define vdprintk(fmt,args...) {}
+#   endif
+#else
+#   ifdef DEBUG
+#       define vprintk(fmt,args...) {}
+#       define dprintk(fmt,args...) {printk(DRVNAME ": " fmt, ## args);}
+#       define vdprintk(fmt,args...) {}
+#   else
+#       define vprintk(fmt,args...) {}
+#       define dprintk(fmt,args...) {}
+#       define vdprintk(fmt,args...) {}
+#   endif
+#endif
+
+#endif /* _VerboseDebug_h */
+
diff -urN linux-2.4.26/Makefile linux-2.4.26-vrs1-lnode80/Makefile
--- linux-2.4.26/Makefile	2005-11-02 16:54:16.000000000 -0400
+++ linux-2.4.26-vrs1-lnode80/Makefile	2005-11-03 10:28:43.000000000 -0400
@@ -1,11 +1,11 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 26
-EXTRAVERSION =-vrs1
+EXTRAVERSION =-vrs1-lnode80
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
-ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+ARCH := arm
 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
 
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -19,7 +19,7 @@
 HOSTCC  	= gcc
 HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 
-CROSS_COMPILE 	=
+CROSS_COMPILE 	= arm-linux-
 
 #
 # Include the make variables (CC, etc...)